diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index dd09643788d62fb..82715bb74710504 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -1397,6 +1397,31 @@ def __del__(self): # empty __dict__. self.assertEqual(x, None) + def test_indirect_calls_with_gc_disabled(self): + junk = [] + i = 0 + detector = GC_Detector() + while not detector.gc_happened: + i += 1 + if i > 10000: + self.fail("gc didn't happen after 10000 iterations") + junk.append([]) # this will eventually trigger gc + + try: + gc.disable() + junk = [] + i = 0 + detector = GC_Detector() + while not detector.gc_happened: + i += 1 + if i > 10000: + break + junk.append([]) # this will eventually trigger gc + + self.assertEqual(i, 10001) + finally: + gc.enable() + class PythonFinalizationTests(unittest.TestCase): def test_ast_fini(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-03-11-22-24-59.gh-issue-116604.LCEzAT.rst b/Misc/NEWS.d/next/Core and Builtins/2024-03-11-22-24-59.gh-issue-116604.LCEzAT.rst new file mode 100644 index 000000000000000..516edfa9e6cedf7 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2024-03-11-22-24-59.gh-issue-116604.LCEzAT.rst @@ -0,0 +1,3 @@ +Respect the status of the garbage collector when indirect calls are made via +:c:func:`PyErr_CheckSignals` and the evaluation breaker. Patch by Pablo +Galindo diff --git a/Python/gc.c b/Python/gc.c index ea3b596d1713dfc..6b3316b642ea9e6 100644 --- a/Python/gc.c +++ b/Python/gc.c @@ -1805,6 +1805,10 @@ _PyObject_GC_Link(PyObject *op) void _Py_RunGC(PyThreadState *tstate) { + GCState *gcstate = get_gc_state(); + if (!gcstate->enabled) { + return; + } gc_collect_main(tstate, GENERATION_AUTO, _Py_GC_REASON_HEAP); }