]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140193: Forward port test_exec_set_nomemory_hang from 3.13 (GH-140187)
authoryihong <zouzou0208@gmail.com>
Tue, 11 Nov 2025 19:27:56 +0000 (03:27 +0800)
committerGitHub <noreply@github.com>
Tue, 11 Nov 2025 19:27:56 +0000 (11:27 -0800)
* chore: test_exec_set_nomemory_hang from 3.13

Signed-off-by: yihong0618 <zouzou0208@gmail.com>
* fix: apply comments

Signed-off-by: yihong0618 <zouzou0208@gmail.com>
* Update Lib/test/test_exceptions.py

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
* Update Lib/test/test_exceptions.py

Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
* fix: windows too long name 60 times is enough

Signed-off-by: yihong0618 <zouzou0208@gmail.com>
---------

Signed-off-by: yihong0618 <zouzou0208@gmail.com>
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Lib/test/test_exceptions.py

index 5262b58908a50985823c7d19f3e1ce8d9fd3cc6e..6f212d2f91efb1c3da87a14eb13342a6d5981da2 100644 (file)
@@ -1923,6 +1923,39 @@ class ExceptionTests(unittest.TestCase):
             exc2 = None
 
 
+    @cpython_only
+    # Python built with Py_TRACE_REFS fail with a fatal error in
+    # _PyRefchain_Trace() on memory allocation error.
+    @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
+    def test_exec_set_nomemory_hang(self):
+        import_module("_testcapi")
+        # gh-134163: A MemoryError inside code that was wrapped by a try/except
+        # block would lead to an infinite loop.
+
+        # The frame_lasti needs to be greater than 257 to prevent
+        # PyLong_FromLong() from returning cached integers, which
+        # don't require a memory allocation. Prepend some dummy code
+        # to artificially increase the instruction index.
+        warmup_code = "a = list(range(0, 1))\n" * 60
+        user_input = warmup_code + dedent("""
+            try:
+                import _testcapi
+                _testcapi.set_nomemory(0)
+                b = list(range(1000, 2000))
+            except Exception as e:
+                import traceback
+                traceback.print_exc()
+            """)
+        with SuppressCrashReport():
+            with script_helper.spawn_python('-c', user_input) as p:
+                p.wait()
+                output = p.stdout.read()
+
+        self.assertIn(p.returncode, (0, 1))
+        self.assertGreater(len(output), 0)  # At minimum, should not hang
+        self.assertIn(b"MemoryError", output)
+
+
 class NameErrorTests(unittest.TestCase):
     def test_name_error_has_name(self):
         try: