From ec167680ac643f5f48ed7d0bde06450e2bd11dd3 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Thu, 16 Oct 2025 10:06:02 +0800 Subject: [PATCH 1/5] chore: test_exec_set_nomemory_hang from 3.13 Signed-off-by: yihong0618 --- Lib/test/test_exceptions.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 323a8c401bde6c..761857bd222a3e 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1914,6 +1914,33 @@ def test_keyerror_context(self): 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: chore from branch 3.13 + warmup_code = "a = list(range(0, 1))\n" * 20 + 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: From 09a19c248fb106ff70ff1d18468d128c8aa2dbd6 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Thu, 16 Oct 2025 21:02:08 +0800 Subject: [PATCH 2/5] fix: apply comments Signed-off-by: yihong0618 --- Lib/test/test_exceptions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 761857bd222a3e..4fbf5e51f78df7 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1920,7 +1920,6 @@ def test_keyerror_context(self): @unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build') def test_exec_set_nomemory_hang(self): import_module("_testcapi") - # gh-134163: chore from branch 3.13 warmup_code = "a = list(range(0, 1))\n" * 20 user_input = warmup_code + dedent(""" try: From ed2793b1591b42e40973a508a83058359df088c5 Mon Sep 17 00:00:00 2001 From: yihong Date: Thu, 16 Oct 2025 21:08:47 +0800 Subject: [PATCH 3/5] Update Lib/test/test_exceptions.py Co-authored-by: Peter Bierma --- Lib/test/test_exceptions.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 4fbf5e51f78df7..dfdbe2745d0532 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1920,6 +1920,13 @@ def test_keyerror_context(self): @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" * 20 user_input = warmup_code + dedent(""" try: From 3f31156de3418251cff51167ef43f695823804bc Mon Sep 17 00:00:00 2001 From: yihong Date: Thu, 16 Oct 2025 21:10:52 +0800 Subject: [PATCH 4/5] Update Lib/test/test_exceptions.py Co-authored-by: Peter Bierma --- Lib/test/test_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index dfdbe2745d0532..1cc9c8a961e607 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1927,7 +1927,7 @@ def test_exec_set_nomemory_hang(self): # 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" * 20 + warmup_code = "a = list(range(0, 1))\n" * 2000 user_input = warmup_code + dedent(""" try: import _testcapi From cc4da89266f4162808a5baff2c83bbc399a1f1c7 Mon Sep 17 00:00:00 2001 From: yihong0618 Date: Fri, 17 Oct 2025 10:37:08 +0800 Subject: [PATCH 5/5] fix: windows too long name 60 times is enough Signed-off-by: yihong0618 --- Lib/test/test_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 1cc9c8a961e607..f3de27c289f211 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1927,7 +1927,7 @@ def test_exec_set_nomemory_hang(self): # 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" * 2000 + warmup_code = "a = list(range(0, 1))\n" * 60 user_input = warmup_code + dedent(""" try: import _testcapi