@@ -1843,6 +1843,38 @@ def test_memory_error_in_subinterp(self):
18431843 rc , _ , err = script_helper .assert_python_ok ("-c" , code )
18441844 self .assertIn (b'MemoryError' , err )
18451845
1846+ @cpython_only
1847+ # Python built with Py_TRACE_REFS fail with a fatal error in
1848+ # _PyRefchain_Trace() on memory allocation error.
1849+ @unittest .skipIf (support .Py_TRACE_REFS , 'cannot test Py_TRACE_REFS build' )
1850+ def test_exec_set_nomemory_hang (self ):
1851+ import_module ("_testcapi" )
1852+ # gh-134163: A MemoryError inside code that was wrapped by a try/except
1853+ # block would lead to an infinite loop.
1854+
1855+ # The frame_lasti needs to be greater than 257 to prevent
1856+ # PyLong_FromLong() from returning cached integers, which
1857+ # don't require a memory allocation. Prepend some dummy code
1858+ # to artificially increase the instruction index.
1859+ warmup_code = "a = list(range(0, 1))\n " * 20
1860+ user_input = warmup_code + dedent ("""
1861+ try:
1862+ import _testcapi
1863+ _testcapi.set_nomemory(0)
1864+ b = list(range(1000, 2000))
1865+ except Exception as e:
1866+ import traceback
1867+ traceback.print_exc()
1868+ """ )
1869+ with SuppressCrashReport ():
1870+ with script_helper .spawn_python ('-c' , user_input ) as p :
1871+ p .wait ()
1872+ output = p .stdout .read ()
1873+
1874+ self .assertIn (p .returncode , (0 , 1 ))
1875+ self .assertGreater (len (output ), 0 ) # At minimum, should not hang
1876+ self .assertIn (b"MemoryError" , output )
1877+
18461878
18471879class NameErrorTests (unittest .TestCase ):
18481880 def test_name_error_has_name (self ):
0 commit comments