https://github.com/python/cpython/commit/6bd96894269be4754a811fb8ea1e3b627a676562 commit: 6bd96894269be4754a811fb8ea1e3b627a676562 branch: main author: Tian Gao <gaogaotiant...@hotmail.com> committer: gaogaotiantian <gaogaotiant...@hotmail.com> date: 2025-04-02T19:50:01-04:00 summary:
gh-60115: Support frozen modules for linecache.getline() (#131638) files: A Misc/NEWS.d/next/Library/2025-03-23-18-39-07.gh-issue-60115.AWdcmq.rst M Doc/library/linecache.rst M Doc/whatsnew/3.14.rst M Lib/linecache.py M Lib/test/test_linecache.py diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index 88c6079a05b7fa..e766a9280946d3 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -30,6 +30,10 @@ The :mod:`linecache` module defines the following functions: .. index:: triple: module; search; path + If *filename* indicates a frozen module (starting with ``'<frozen '``), the function + will attepmt to get the real file name from ``module_globals['__file__']`` if + *module_globals* is not ``None``. + If a file named *filename* is not found, the function first checks for a :pep:`302` ``__loader__`` in *module_globals*. If there is such a loader and it defines a ``get_source`` method, @@ -38,6 +42,10 @@ The :mod:`linecache` module defines the following functions: Finally, if *filename* is a relative filename, it is looked up relative to the entries in the module search path, ``sys.path``. + .. versionchanged:: 3.14 + + Support *filename* of frozen modules. + .. function:: clearcache() diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index 5c0f2829809e3e..108768de086bb2 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -706,6 +706,13 @@ json (Contributed by Trey Hunner in :gh:`122873`.) +linecache +--------- + +* :func:`linecache.getline` can retrieve source code for frozen modules. + (Contributed by Tian Gao in :gh:`131638`.) + + mimetypes --------- diff --git a/Lib/linecache.py b/Lib/linecache.py index dc02de19eb62cb..87d7d6fda657e4 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -63,6 +63,16 @@ def _getlines_from_code(code): return [] +def _source_unavailable(filename): + """Return True if the source code is unavailable for such file name.""" + return ( + not filename + or (filename.startswith('<') + and filename.endswith('>') + and not filename.startswith('<frozen ')) + ) + + def checkcache(filename=None): """Discard cache entries that are out of date. (This is not checked upon each call!)""" @@ -118,10 +128,17 @@ def updatecache(filename, module_globals=None): if filename in cache: if len(cache[filename]) != 1: cache.pop(filename, None) - if not filename or (filename.startswith('<') and filename.endswith('>')): + if _source_unavailable(filename): return [] - fullname = filename + if filename.startswith('<frozen ') and module_globals is not None: + # This is a frozen module, so we need to use the filename + # from the module globals. + fullname = module_globals.get('__file__') + if fullname is None: + return [] + else: + fullname = filename try: stat = os.stat(fullname) except OSError: diff --git a/Lib/test/test_linecache.py b/Lib/test/test_linecache.py index e23e1cc942856b..e4aa41ebb43762 100644 --- a/Lib/test/test_linecache.py +++ b/Lib/test/test_linecache.py @@ -281,6 +281,19 @@ def test_loader(self): self.assertEqual(linecache.getlines(filename, module_globals), ['source for x.y.z\n']) + def test_frozen(self): + filename = '<frozen fakemodule>' + module_globals = {'__file__': FILENAME} + empty = linecache.getlines(filename) + self.assertEqual(empty, []) + lines = linecache.getlines(filename, module_globals) + self.assertGreater(len(lines), 0) + lines_cached = linecache.getlines(filename) + self.assertEqual(lines, lines_cached) + linecache.clearcache() + empty = linecache.getlines(filename) + self.assertEqual(empty, []) + def test_invalid_names(self): for name, desc in [ ('\x00', 'NUL bytes filename'), diff --git a/Misc/NEWS.d/next/Library/2025-03-23-18-39-07.gh-issue-60115.AWdcmq.rst b/Misc/NEWS.d/next/Library/2025-03-23-18-39-07.gh-issue-60115.AWdcmq.rst new file mode 100644 index 00000000000000..6287e996ae1b01 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-03-23-18-39-07.gh-issue-60115.AWdcmq.rst @@ -0,0 +1 @@ +Support frozen modules for :func:`linecache.getline`. _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com