From a9ecfcef9c9af6faf2f7853aaccaf6482a624c96 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 27 May 2024 11:33:56 -0600 Subject: [PATCH 1/5] Clear m_index when clearing a singlephase extension. --- Python/import.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Python/import.c b/Python/import.c index 4f3325aa67bd0a..a546cf9a0cbaee 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2192,6 +2192,7 @@ clear_singlephase_extension(PyInterpreterState *interp, return -1; } } + def->m_base.m_index = 0; /* Clear the cached module def. */ _extensions_cache_delete(path, name); From b01ac6e0f584f3049ac18cf24d3ac560ecac9f59 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 27 May 2024 11:35:31 -0600 Subject: [PATCH 2/5] Add a note about the check-state-first modules. --- Modules/_testsinglephase.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/_testsinglephase.c b/Modules/_testsinglephase.c index bcdb5ba31842fd..066e0dbfb63fbf 100644 --- a/Modules/_testsinglephase.c +++ b/Modules/_testsinglephase.c @@ -682,6 +682,9 @@ PyInit__testsinglephase_with_state(void) /* the _testsinglephase_*_check_cache_first modules */ /****************************************************/ +/* Each of these modules should only be freshly loaded. That means + clearing the caches and each module def's m_base after each load. */ + static struct PyModuleDef _testsinglephase_check_cache_first = { PyModuleDef_HEAD_INIT, .m_name = "_testsinglephase_check_cache_first", From 6054a7d8ec0de89c1ea65e34c98c099502e38673 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 27 May 2024 11:38:02 -0600 Subject: [PATCH 3/5] Clear the check-state-first modules after loading them. --- Lib/test/test_import/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 11eaae5e47e97a..b09065f812c0e4 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -2887,12 +2887,15 @@ def test_with_reinit_reloaded(self): self.assertIs(reloaded.snapshot.cached, reloaded.module) + @unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi") def test_check_state_first(self): for variant in ['', '_with_reinit', '_with_state']: name = f'{self.NAME}{variant}_check_cache_first' with self.subTest(name): mod = self._load_dynamic(name, self.ORIGIN) self.assertEqual(mod.__name__, name) + sys.modules.pop(name, None) + _testinternalcapi.clear_extension(name, self.ORIGIN) # Currently, for every single-phrase init module loaded # in multiple interpreters, those interpreters share a From 7a23841d787c07a84b5537095768ae1eb4e85fa6 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 27 May 2024 12:57:31 -0600 Subject: [PATCH 4/5] Fix _modules_by_index_check(). --- Python/import.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/import.c b/Python/import.c index a546cf9a0cbaee..7af969d13c39dc 100644 --- a/Python/import.c +++ b/Python/import.c @@ -494,7 +494,7 @@ _modules_by_index_check(PyInterpreterState *interp, Py_ssize_t index) if (MODULES_BY_INDEX(interp) == NULL) { return "Interpreters module-list not accessible."; } - if (index > PyList_GET_SIZE(MODULES_BY_INDEX(interp))) { + if (index >= PyList_GET_SIZE(MODULES_BY_INDEX(interp))) { return "Module index out of bounds."; } return NULL; From 3699d15b75b5c0d33b121dd5111cd3f2ba6d80f9 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 27 May 2024 12:58:02 -0600 Subject: [PATCH 5/5] Move a line up. --- Python/import.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Python/import.c b/Python/import.c index 7af969d13c39dc..6fe6df4db4f55e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2183,7 +2183,7 @@ clear_singlephase_extension(PyInterpreterState *interp, /* Clear data set when the module was initially loaded. */ def->m_base.m_init = NULL; Py_CLEAR(def->m_base.m_copy); - // We leave m_index alone since there's no reason to reset it. + def->m_base.m_index = 0; /* Clear the PyState_*Module() cache entry. */ Py_ssize_t index = _get_cached_module_index(cached); @@ -2192,7 +2192,6 @@ clear_singlephase_extension(PyInterpreterState *interp, return -1; } } - def->m_base.m_index = 0; /* Clear the cached module def. */ _extensions_cache_delete(path, name);