Skip to content

Commit e1ebf51

Browse files
miss-islingtonZackerySpytz
authored andcommitted
bpo-24596: Decref module in PyRun_SimpleFileExFlags() on SystemExit (GH-7918) (GH-8069)
PyErr_Print() will not return when the exception is a SystemExit, so decref the __main__ module object in that case. (cherry picked from commit d8cba5d) Co-authored-by: Zackery Spytz <[email protected]>
1 parent f55a818 commit e1ebf51

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

Lib/test/test_gc.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import unittest
22
from test.support import (verbose, refcount_test, run_unittest,
33
strip_python_stderr, cpython_only, start_threads,
4-
temp_dir, requires_type_collecting)
4+
temp_dir, requires_type_collecting, TESTFN, unlink)
55
from test.support.script_helper import assert_python_ok, make_script
66

77
import sys
@@ -713,6 +713,21 @@ def __del__(self):
713713
rc, out, err = assert_python_ok('-c', code)
714714
self.assertEqual(out.strip(), b'__del__ called')
715715

716+
@requires_type_collecting
717+
def test_global_del_SystemExit(self):
718+
code = """if 1:
719+
class ClassWithDel:
720+
def __del__(self):
721+
print('__del__ called')
722+
a = ClassWithDel()
723+
a.link = a
724+
raise SystemExit(0)"""
725+
self.addCleanup(unlink, TESTFN)
726+
with open(TESTFN, 'w') as script:
727+
script.write(code)
728+
rc, out, err = assert_python_ok(TESTFN)
729+
self.assertEqual(out.strip(), b'__del__ called')
730+
716731
def test_get_stats(self):
717732
stats = gc.get_stats()
718733
self.assertEqual(len(stats), 3)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Decref the module object in :c:func:`PyRun_SimpleFileExFlags` before calling
2+
:c:func:`PyErr_Print()`. Patch by Zackery Spytz.

Python/pythonrun.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
421421
}
422422
flush_io();
423423
if (v == NULL) {
424+
Py_CLEAR(m);
424425
PyErr_Print();
425426
goto done;
426427
}
@@ -429,7 +430,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
429430
done:
430431
if (set_file_name && PyDict_DelItemString(d, "__file__"))
431432
PyErr_Clear();
432-
Py_DECREF(m);
433+
Py_XDECREF(m);
433434
return ret;
434435
}
435436

0 commit comments

Comments
 (0)