Skip to content

Commit da72a0b

Browse files
committed
fix: add news and tests
Signed-off-by: yihong0618 <[email protected]>
1 parent 7cdfb7c commit da72a0b

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

Lib/test/test_exceptions.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,32 @@ def testMemoryErrorBigSource(self, size):
342342
with self.assertRaisesRegex(OverflowError, "Parser column offset overflow"):
343343
compile(src, '<fragment>', 'exec')
344344

345+
@cpython_only
346+
# Python built with Py_TRACE_REFS fail with a fatal error in
347+
# _PyRefchain_Trace() on memory allocation error.
348+
@unittest.skipIf(support.Py_TRACE_REFS, 'cannot test Py_TRACE_REFS build')
349+
def test_atexit_with_low_memory(self):
350+
# gh-140080: Test that setting low memory after registering an atexit
351+
# callback doesn't cause an infinite loop during finalization.
352+
user_input = dedent("""
353+
import atexit
354+
import _testcapi
355+
356+
def callback():
357+
pass
358+
359+
atexit.register(callback)
360+
# Simulate low memory condition
361+
_testcapi.set_nomemory(0)
362+
""")
363+
with SuppressCrashReport():
364+
with script_helper.spawn_python('-c', user_input) as p:
365+
p.wait()
366+
output = p.stdout.read()
367+
368+
# The key point is that the process should exit (not hang)
369+
self.assertIn(p.returncode, (0, 1))
370+
345371
@cpython_only
346372
def testSettingException(self):
347373
# test that setting an exception at the C level works even if the
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix: ``atexit_callfuncs`` need to atexit_cleanup the state when copy is NULL
2+
to avoid the low memory error then recursive error.

Modules/atexitmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ atexit_callfuncs(struct atexit_state *state)
112112
{
113113
PyErr_FormatUnraisable("Exception ignored while "
114114
"copying atexit callbacks");
115-
// gh-140080: need to cleanup
115+
// gh-140080: need to cleanup to prevent recursive when low memory
116116
atexit_cleanup(state);
117117
return;
118118
}

0 commit comments

Comments
 (0)