mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
gh-117953: Always Run Extension Init Func in Main Interpreter First (gh-118157)
This change makes sure all extension/builtin modules have their init function run first by the main interpreter before proceeding with import in the original interpreter (main or otherwise). This means when the import of a single-phase init module fails in an isolated subinterpreter, it won't tie any global state/callbacks to the subinterpreter.
This commit is contained in:
parent
1a23716d4b
commit
b2cd54a4fb
4 changed files with 217 additions and 70 deletions
|
@ -2454,10 +2454,6 @@ class SinglephaseInitTests(unittest.TestCase):
|
|||
# Start fresh.
|
||||
cls.clean_up()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
restore__testsinglephase()
|
||||
|
||||
def tearDown(self):
|
||||
# Clean up the module.
|
||||
self.clean_up()
|
||||
|
@ -3014,20 +3010,20 @@ class SinglephaseInitTests(unittest.TestCase):
|
|||
# * alive in 0 interpreters
|
||||
# * module def in _PyRuntime.imports.extensions
|
||||
# * mod init func ran for the first time (since reset)
|
||||
# * m_copy is NULL (claered when the interpreter was destroyed)
|
||||
# * m_copy is still set (owned by main interpreter)
|
||||
# * module's global state was initialized, not reset
|
||||
|
||||
# Use a subinterpreter that sticks around.
|
||||
loaded_interp1 = self.import_in_subinterp(interpid1)
|
||||
self.check_common(loaded_interp1)
|
||||
self.check_semi_fresh(loaded_interp1, loaded_main, base)
|
||||
self.check_copied(loaded_interp1, base)
|
||||
|
||||
# At this point:
|
||||
# * alive in 1 interpreter (interp1)
|
||||
# * module def still in _PyRuntime.imports.extensions
|
||||
# * mod init func ran for the second time (since reset)
|
||||
# * m_copy was copied from interp1 (was NULL)
|
||||
# * module's global state was updated, not reset
|
||||
# * mod init func did not run again
|
||||
# * m_copy was not changed
|
||||
# * module's global state was not touched
|
||||
|
||||
# Use a subinterpreter while the previous one is still alive.
|
||||
loaded_interp2 = self.import_in_subinterp(interpid2)
|
||||
|
@ -3038,8 +3034,8 @@ class SinglephaseInitTests(unittest.TestCase):
|
|||
# * alive in 2 interpreters (interp1, interp2)
|
||||
# * module def still in _PyRuntime.imports.extensions
|
||||
# * mod init func did not run again
|
||||
# * m_copy was copied from interp2 (was from interp1)
|
||||
# * module's global state was updated, not reset
|
||||
# * m_copy was not changed
|
||||
# * module's global state was not touched
|
||||
|
||||
@requires_subinterpreters
|
||||
def test_basic_multiple_interpreters_reset_each(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue