Skip to content

Commit a86a7b8

Browse files
gh-93696: Locate frozen module source with __file__ (GH-93697)
Co-authored-by: Kumar Aditya <[email protected]> (cherry picked from commit d91de28) Co-authored-by: James Gerity <[email protected]>
1 parent 9387b7c commit a86a7b8

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

Lib/pdb.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,12 @@ def do_list(self, arg):
12481248
if last is None:
12491249
last = first + 10
12501250
filename = self.curframe.f_code.co_filename
1251+
# gh-93696: stdlib frozen modules provide a useful __file__
1252+
# this workaround can be removed with the closure of gh-89815
1253+
if filename.startswith("<frozen"):
1254+
tmp = self.curframe.f_globals.get("__file__")
1255+
if isinstance(tmp, str):
1256+
filename = tmp
12511257
breaklist = self.get_file_breaks(filename)
12521258
try:
12531259
lines = linecache.getlines(filename, self.curframe.f_globals)

Lib/test/test_pdb.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,52 @@ def test_issue42383(self):
19151915
self.assertEqual(stdout.split('\n')[6].rstrip('\r'), expected)
19161916

19171917

1918+
def test_gh_93696_frozen_list(self):
1919+
frozen_src = """
1920+
def func():
1921+
x = "Sentinel string for gh-93696"
1922+
print(x)
1923+
"""
1924+
host_program = """
1925+
import os
1926+
import sys
1927+
1928+
def _create_fake_frozen_module():
1929+
with open('gh93696.py') as f:
1930+
src = f.read()
1931+
1932+
# this function has a co_filename as if it were in a frozen module
1933+
dummy_mod = compile(src, "<frozen gh93696>", "exec")
1934+
func_code = dummy_mod.co_consts[0]
1935+
1936+
mod = type(sys)("gh93696")
1937+
mod.func = type(lambda: None)(func_code, mod.__dict__)
1938+
mod.__file__ = 'gh93696.py'
1939+
1940+
return mod
1941+
1942+
mod = _create_fake_frozen_module()
1943+
mod.func()
1944+
"""
1945+
commands = """
1946+
break 20
1947+
continue
1948+
step
1949+
list
1950+
quit
1951+
"""
1952+
with open('gh93696.py', 'w') as f:
1953+
f.write(textwrap.dedent(frozen_src))
1954+
1955+
with open('gh93696_host.py', 'w') as f:
1956+
f.write(textwrap.dedent(host_program))
1957+
1958+
self.addCleanup(os_helper.unlink, 'gh93696.py')
1959+
self.addCleanup(os_helper.unlink, 'gh93696_host.py')
1960+
stdout, stderr = self._run_pdb(["gh93696_host.py"], commands)
1961+
# verify that pdb found the source of the "frozen" function
1962+
self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found")
1963+
19181964
class ChecklineTests(unittest.TestCase):
19191965
def setUp(self):
19201966
linecache.clearcache() # Pdb.checkline() uses linecache.getline()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow :mod:`pdb` to locate source for frozen modules in the standard library.

0 commit comments

Comments
 (0)