Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add another test case.
  • Loading branch information
ericsnowcurrently committed Feb 17, 2023
commit c993f970782a823519e74e554087eba1f720ab4f
79 changes: 79 additions & 0 deletions Lib/test/test_imp.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ def test_singlephase_multiple_interpreters(self):
# This single-phase module has global state, which is shared
# by all interpreters.
import _testsinglephase
name = _testsinglephase.__name__
filename = _testsinglephase.__file__

# Start and end clean.
_forget_extension(_testsinglephase)
Expand All @@ -334,6 +336,15 @@ def test_singlephase_multiple_interpreters(self):
self.addCleanup(_interpreters.destroy, interp1)
interp2 = _interpreters.create(isolated=False)
self.addCleanup(_interpreters.destroy, interp2)
for interpid in [interp1, interp2]:
_interpreters.run_string(interpid, 'import _testinternalcapi, sys')

def clear_subinterp(interpid):
_interpreters.run_string(interpid, textwrap.dedent(f'''
del sys.modules[{name!r}]
_testsinglephase._clear_globals()
_testinternalcapi.clear_extension({name!r}, {filename!r})
'''))

with self.subTest('without resetting; '
'already loaded in main interpreter'):
Expand Down Expand Up @@ -361,6 +372,10 @@ def test_singlephase_multiple_interpreters(self):
initialized = _testsinglephase.state_initialized()
if _initialized != initialized:
raise Exception((_initialized, initialized))
if _initialized != {initialized}:
raise Exception((_initialized, {initialized}))
if initialized != {initialized}:
raise Exception((initialized, {initialized}))

# Attrs set after loading are not in m_copy.
if hasattr(_testsinglephase, 'spam'):
Expand All @@ -381,6 +396,70 @@ def test_singlephase_multiple_interpreters(self):
# However, globals are still shared.
_interpreters.run_string(interp2, script)

_forget_extension(_testsinglephase)
for interpid in [interp1, interp2]:
clear_subinterp(interpid)

with self.subTest('without resetting; '
'already loaded in deleted interpreter'):

# Use an interpreter that gets destroyed right away.
ret = support.run_in_subinterp(textwrap.dedent(f'''
import _testsinglephase

# This is the first time loaded since reset.
init_count = _testsinglephase.initialized_count()
if init_count != 1:
raise Exception(init_count)

# Attrs set in the module init func are in m_copy.
_initialized = _testsinglephase._module_initialized
initialized = _testsinglephase.state_initialized()
if _initialized != initialized:
raise Exception((_initialized, initialized))
if _initialized == {initialized}:
raise Exception((_initialized, {initialized}))
if initialized == {initialized}:
raise Exception((initialized, {initialized}))

# Attrs set after loading are not in m_copy.
if hasattr(_testsinglephase, 'spam'):
raise Exception(_testsinglephase.spam)
_testsinglephase.spam = 'spam, spam, mash, spam, eggs, and spam'
'''))
self.assertEqual(ret, 0)

script = textwrap.dedent(f'''
import _testsinglephase

init_count = _testsinglephase.initialized_count()
if init_count != 2:
raise Exception(init_count)

# Attrs set in the module init func are in m_copy.
# Both of the following were set in module init,
# which didn't happen in this interpreter
# (unfortunately).
_initialized = _testsinglephase._module_initialized
initialized = _testsinglephase.state_initialized()
if _initialized != initialized:
raise Exception((_initialized, initialized))

# Attrs set after loading are not in m_copy.
if hasattr(_testsinglephase, 'spam'):
raise Exception(_testsinglephase.spam)
_testsinglephase.spam = 'spam, spam, spam, spam, ...'
''')

# The module's init func gets run again.
# The module's globals did not get destroyed.
_interpreters.run_string(interp1, script)

# The module's init func is not run again.
# The second interpreter copies the module's m_copy.
# However, globals are still shared.
_interpreters.run_string(interp2, script)

@requires_load_dynamic
def test_singlephase_variants(self):
# Exercise the most meaningful variants described in Python/import.c.
Expand Down