@@ -1407,14 +1407,82 @@ def test_pdb_issue_gh_91742():
1407
1407
(Pdb) continue
1408
1408
Author: 'pi' Version: '3.14'
1409
1409
"""
1410
+
1411
+ def test_pdb_issue_gh_94215 ():
1412
+ """See GH-94215
1413
+
1414
+ Check that frame_setlineno() does not leak references.
1415
+
1416
+ >>> def test_function():
1417
+ ... def func():
1418
+ ... def inner(v): pass
1419
+ ... inner(
1420
+ ... 42
1421
+ ... )
1422
+ ...
1423
+ ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace()
1424
+ ... func()
1425
+
1426
+ >>> reset_Breakpoint()
1427
+ >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE
1428
+ ... 'step',
1429
+ ... 'next',
1430
+ ... 'next',
1431
+ ... 'jump 3',
1432
+ ... 'next',
1433
+ ... 'next',
1434
+ ... 'jump 3',
1435
+ ... 'next',
1436
+ ... 'next',
1437
+ ... 'jump 3',
1438
+ ... 'continue'
1439
+ ... ]):
1440
+ ... test_function()
1441
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(9)test_function()
1442
+ -> func()
1443
+ (Pdb) step
1444
+ --Call--
1445
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(2)func()
1446
+ -> def func():
1447
+ (Pdb) next
1448
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
1449
+ -> def inner(v): pass
1450
+ (Pdb) next
1451
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(4)func()
1452
+ -> inner(
1453
+ (Pdb) jump 3
1454
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
1455
+ -> def inner(v): pass
1456
+ (Pdb) next
1457
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(4)func()
1458
+ -> inner(
1459
+ (Pdb) next
1460
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(5)func()
1461
+ -> 42
1462
+ (Pdb) jump 3
1463
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
1464
+ -> def inner(v): pass
1465
+ (Pdb) next
1466
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(4)func()
1467
+ -> inner(
1468
+ (Pdb) next
1469
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(5)func()
1470
+ -> 42
1471
+ (Pdb) jump 3
1472
+ > <doctest test.test_pdb.test_pdb_issue_gh_94215[0]>(3)func()
1473
+ -> def inner(v): pass
1474
+ (Pdb) continue
1475
+ """
1476
+
1477
+
1410
1478
@support .requires_subprocess ()
1411
1479
class PdbTestCase (unittest .TestCase ):
1412
1480
def tearDown (self ):
1413
1481
os_helper .unlink (os_helper .TESTFN )
1414
1482
1415
1483
@unittest .skipIf (sys .flags .safe_path ,
1416
1484
'PYTHONSAFEPATH changes default sys.path' )
1417
- def _run_pdb (self , pdb_args , commands ):
1485
+ def _run_pdb (self , pdb_args , commands , expected_returncode = 0 ):
1418
1486
self .addCleanup (os_helper .rmtree , '__pycache__' )
1419
1487
cmd = [sys .executable , '-m' , 'pdb' ] + pdb_args
1420
1488
with subprocess .Popen (
@@ -1427,15 +1495,20 @@ def _run_pdb(self, pdb_args, commands):
1427
1495
stdout , stderr = proc .communicate (str .encode (commands ))
1428
1496
stdout = stdout and bytes .decode (stdout )
1429
1497
stderr = stderr and bytes .decode (stderr )
1498
+ self .assertEqual (
1499
+ proc .returncode ,
1500
+ expected_returncode ,
1501
+ f"Unexpected return code\n stdout: { stdout } \n stderr: { stderr } "
1502
+ )
1430
1503
return stdout , stderr
1431
1504
1432
- def run_pdb_script (self , script , commands ):
1505
+ def run_pdb_script (self , script , commands , expected_returncode = 0 ):
1433
1506
"""Run 'script' lines with pdb and the pdb 'commands'."""
1434
1507
filename = 'main.py'
1435
1508
with open (filename , 'w' ) as f :
1436
1509
f .write (textwrap .dedent (script ))
1437
1510
self .addCleanup (os_helper .unlink , filename )
1438
- return self ._run_pdb ([filename ], commands )
1511
+ return self ._run_pdb ([filename ], commands , expected_returncode )
1439
1512
1440
1513
def run_pdb_module (self , script , commands ):
1441
1514
"""Runs the script code as part of a module"""
@@ -1641,7 +1714,9 @@ def test_issue16180(self):
1641
1714
script = "def f: pass\n "
1642
1715
commands = ''
1643
1716
expected = "SyntaxError:"
1644
- stdout , stderr = self .run_pdb_script (script , commands )
1717
+ stdout , stderr = self .run_pdb_script (
1718
+ script , commands , expected_returncode = 1
1719
+ )
1645
1720
self .assertIn (expected , stdout ,
1646
1721
'\n \n Expected:\n {}\n Got:\n {}\n '
1647
1722
'Fail to handle a syntax error in the debuggee.'
@@ -1804,7 +1879,9 @@ def test_module_without_a_main(self):
1804
1879
with open (init_file , 'w' ):
1805
1880
pass
1806
1881
self .addCleanup (os_helper .rmtree , module_name )
1807
- stdout , stderr = self ._run_pdb (['-m' , module_name ], "" )
1882
+ stdout , stderr = self ._run_pdb (
1883
+ ['-m' , module_name ], "" , expected_returncode = 1
1884
+ )
1808
1885
self .assertIn ("ImportError: No module named t_main.__main__" ,
1809
1886
stdout .splitlines ())
1810
1887
@@ -1817,7 +1894,9 @@ def test_package_without_a_main(self):
1817
1894
with open (modpath + '/__init__.py' , 'w' ):
1818
1895
pass
1819
1896
self .addCleanup (os_helper .rmtree , pkg_name )
1820
- stdout , stderr = self ._run_pdb (['-m' , modpath .replace ('/' , '.' )], "" )
1897
+ stdout , stderr = self ._run_pdb (
1898
+ ['-m' , modpath .replace ('/' , '.' )], "" , expected_returncode = 1
1899
+ )
1821
1900
self .assertIn (
1822
1901
"'t_pkg.t_main' is a package and cannot be directly executed" ,
1823
1902
stdout )
@@ -2006,6 +2085,25 @@ def test_issue42383(self):
2006
2085
expected = '(Pdb) The correct file was executed'
2007
2086
self .assertEqual (stdout .split ('\n ' )[6 ].rstrip ('\r ' ), expected )
2008
2087
2088
+ @unittest .skip ("test crashes, see gh-94215" )
2089
+ def test_gh_94215_crash (self ):
2090
+ script = """\
2091
+ def func():
2092
+ def inner(v): pass
2093
+ inner(
2094
+ 42
2095
+ )
2096
+ func()
2097
+ """
2098
+ commands = textwrap .dedent ("""
2099
+ break func
2100
+ continue
2101
+ next
2102
+ next
2103
+ jump 2
2104
+ """ )
2105
+ stdout , stderr = self .run_pdb_script (script , commands )
2106
+ self .assertFalse (stderr )
2009
2107
2010
2108
class ChecklineTests (unittest .TestCase ):
2011
2109
def setUp (self ):
0 commit comments