From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 2 Aug 2023 21:23:15 +0000 (-0700) Subject: [3.12] gh-107471: Fix Refleaks in test_import (gh-107569) (#107571) X-Git-Tag: v3.12.0rc1~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=12d1c494ae236e1a1ce8ae8084f8f9a6b6eb8295;p=thirdparty%2FPython%2Fcpython.git [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 017f047183fa33743f7e36c5c360f5c670032be3) Co-authored-by: Eric Snow --- diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index cc6e8d4e640c..06adf01f18c0 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -131,6 +131,7 @@ if _testsinglephase is not None: def restore__testsinglephase(*, _orig=_testsinglephase): # We started with the module imported and want to restore # it to its nominal state. + sys.modules.pop('_testsinglephase', None) _orig._clear_globals() _testinternalcapi.clear_extension('_testsinglephase', _orig.__file__) import _testsinglephase @@ -2110,7 +2111,7 @@ class SinglephaseInitTests(unittest.TestCase): _interpreters.run_string(interpid, textwrap.dedent(f''' name = {self.NAME!r} if name in sys.modules: - sys.modules[name]._clear_globals() + sys.modules.pop(name)._clear_globals() _testinternalcapi.clear_extension(name, {self.FILE!r}) ''')) _interpreters.destroy(interpid) diff --git a/Python/import.c b/Python/import.c index f8f01f1bcd8c..3f3f2a2b6813 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1080,6 +1080,7 @@ _extensions_cache_delete(PyObject *filename, PyObject *name) However, this decref would be problematic if the module def were dynamically allocated, it were the last ref, and this function were called with an interpreter other than the def's owner. */ + assert(_Py_IsImmortal(entry->value)); entry->value = NULL; finally: