https://github.com/python/cpython/commit/6bd96894269be4754a811fb8ea1e3b627a676562
commit: 6bd96894269be4754a811fb8ea1e3b627a676562
branch: main
author: Tian Gao <[email protected]>
committer: gaogaotiantian <[email protected]>
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 -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]