Skip to content

Commit d91de28

Browse files
gh-93696: Locate frozen module source with __file__ (#93697)
Co-authored-by: Kumar Aditya <[email protected]>
1 parent dd13b23 commit d91de28

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
@@ -1332,6 +1332,12 @@ def do_list(self, arg):
13321332
if last is None:
13331333
last = first + 10
13341334
filename = self.curframe.f_code.co_filename
1335+
# gh-93696: stdlib frozen modules provide a useful __file__
1336+
# this workaround can be removed with the closure of gh-89815
1337+
if filename.startswith("<frozen"):
1338+
tmp = self.curframe.f_globals.get("__file__")
1339+
if isinstance(tmp, str):
1340+
filename = tmp
13351341
breaklist = self.get_file_breaks(filename)
13361342
try:
13371343
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
@@ -2104,6 +2104,52 @@ def inner(v): pass
21042104
stdout, stderr = self.run_pdb_script(script, commands)
21052105
self.assertFalse(stderr)
21062106

2107+
def test_gh_93696_frozen_list(self):
2108+
frozen_src = """
2109+
def func():
2110+
x = "Sentinel string for gh-93696"
2111+
print(x)
2112+
"""
2113+
host_program = """
2114+
import os
2115+
import sys
2116+
2117+
def _create_fake_frozen_module():
2118+
with open('gh93696.py') as f:
2119+
src = f.read()
2120+
2121+
# this function has a co_filename as if it were in a frozen module
2122+
dummy_mod = compile(src, "<frozen gh93696>", "exec")
2123+
func_code = dummy_mod.co_consts[0]
2124+
2125+
mod = type(sys)("gh93696")
2126+
mod.func = type(lambda: None)(func_code, mod.__dict__)
2127+
mod.__file__ = 'gh93696.py'
2128+
2129+
return mod
2130+
2131+
mod = _create_fake_frozen_module()
2132+
mod.func()
2133+
"""
2134+
commands = """
2135+
break 20
2136+
continue
2137+
step
2138+
list
2139+
quit
2140+
"""
2141+
with open('gh93696.py', 'w') as f:
2142+
f.write(textwrap.dedent(frozen_src))
2143+
2144+
with open('gh93696_host.py', 'w') as f:
2145+
f.write(textwrap.dedent(host_program))
2146+
2147+
self.addCleanup(os_helper.unlink, 'gh93696.py')
2148+
self.addCleanup(os_helper.unlink, 'gh93696_host.py')
2149+
stdout, stderr = self._run_pdb(["gh93696_host.py"], commands)
2150+
# verify that pdb found the source of the "frozen" function
2151+
self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found")
2152+
21072153
class ChecklineTests(unittest.TestCase):
21082154
def setUp(self):
21092155
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)