Skip to content

Commit 12d1c49

Browse files
[3.12] gh-107471: Fix Refleaks in test_import (gh-107569) (#107571)
gh-107471: Fix Refleaks in test_import (gh-107569) gh-107184 introduced a refleak in test_import.SubinterpImportTests (specifically test_singlephase_check_with_setting_and_override and test_single_init_extension_compat). We fix it here by making sure _testsinglephase is removed from sys.modules whenever we clear the runtime's internal state for the module. The underlying problem is strictly contained in the internal function _PyImport_ClearExtension() (AKA _testinternalcapi.clear_extension()), which is only used in tests. (This also fixes an intermittent segfault introduced in the same place, in test_disallowed_reimport.) (cherry picked from commit 017f047) Co-authored-by: Eric Snow <[email protected]>
1 parent f7e16d7 commit 12d1c49

File tree

2 files changed

+3
-1
lines changed

2 files changed

+3
-1
lines changed

Lib/test/test_import/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ def _ready_to_import(name=None, source=""):
131131
def restore__testsinglephase(*, _orig=_testsinglephase):
132132
# We started with the module imported and want to restore
133133
# it to its nominal state.
134+
sys.modules.pop('_testsinglephase', None)
134135
_orig._clear_globals()
135136
_testinternalcapi.clear_extension('_testsinglephase', _orig.__file__)
136137
import _testsinglephase
@@ -2110,7 +2111,7 @@ def clean_up():
21102111
_interpreters.run_string(interpid, textwrap.dedent(f'''
21112112
name = {self.NAME!r}
21122113
if name in sys.modules:
2113-
sys.modules[name]._clear_globals()
2114+
sys.modules.pop(name)._clear_globals()
21142115
_testinternalcapi.clear_extension(name, {self.FILE!r})
21152116
'''))
21162117
_interpreters.destroy(interpid)

Python/import.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,7 @@ _extensions_cache_delete(PyObject *filename, PyObject *name)
10801080
However, this decref would be problematic if the module def were
10811081
dynamically allocated, it were the last ref, and this function
10821082
were called with an interpreter other than the def's owner. */
1083+
assert(_Py_IsImmortal(entry->value));
10831084
entry->value = NULL;
10841085

10851086
finally:

0 commit comments

Comments
 (0)