@@ -97,7 +97,6 @@ def require_frozen(module, *, skip=True):
9797def require_pure_python (module , * , skip = False ):
9898 _require_loader (module , SourceFileLoader , skip )
9999
100-
101100def remove_files (name ):
102101 for f in (name + ".py" ,
103102 name + ".pyc" ,
@@ -147,19 +146,34 @@ def _ready_to_import(name=None, source=""):
147146 del sys .modules [name ]
148147
149148
150- def requires_subinterpreters (meth ):
151- """Decorator to skip a test if subinterpreters are not supported."""
152- return unittest .skipIf (_interpreters is None ,
153- 'subinterpreters required' )(meth )
149+ if _testsinglephase is not None :
150+ def restore__testsinglephase (* , _orig = _testsinglephase ):
151+ # We started with the module imported and want to restore
152+ # it to its nominal state.
153+ _orig ._clear_globals ()
154+ _testinternalcapi .clear_extension ('_testsinglephase' , _orig .__file__ )
155+ import _testsinglephase
154156
155157
156158def requires_singlephase_init (meth ):
157159 """Decorator to skip if single-phase init modules are not supported."""
160+ if not isinstance (meth , type ):
161+ def meth (self , _meth = meth ):
162+ try :
163+ return _meth (self )
164+ finally :
165+ restore__testsinglephase ()
158166 meth = cpython_only (meth )
159167 return unittest .skipIf (_testsinglephase is None ,
160168 'test requires _testsinglephase module' )(meth )
161169
162170
171+ def requires_subinterpreters (meth ):
172+ """Decorator to skip a test if subinterpreters are not supported."""
173+ return unittest .skipIf (_interpreters is None ,
174+ 'subinterpreters required' )(meth )
175+
176+
163177class ModuleSnapshot (types .SimpleNamespace ):
164178 """A representation of a module for testing.
165179
@@ -1962,6 +1976,20 @@ def test_isolated_config(self):
19621976 with self .subTest (f'{ module } : strict, fresh' ):
19631977 self .check_compatible_fresh (module , strict = True , isolated = True )
19641978
1979+ @requires_subinterpreters
1980+ @requires_singlephase_init
1981+ def test_disallowed_reimport (self ):
1982+ # See https://github.com/python/cpython/issues/104621.
1983+ script = textwrap .dedent ('''
1984+ import _testsinglephase
1985+ print(_testsinglephase)
1986+ ''' )
1987+ interpid = _interpreters .create ()
1988+ with self .assertRaises (_interpreters .RunFailedError ):
1989+ _interpreters .run_string (interpid , script )
1990+ with self .assertRaises (_interpreters .RunFailedError ):
1991+ _interpreters .run_string (interpid , script )
1992+
19651993
19661994class TestSinglePhaseSnapshot (ModuleSnapshot ):
19671995
@@ -2017,6 +2045,10 @@ def setUpClass(cls):
20172045 # Start fresh.
20182046 cls .clean_up ()
20192047
2048+ @classmethod
2049+ def tearDownClass (cls ):
2050+ restore__testsinglephase ()
2051+
20202052 def tearDown (self ):
20212053 # Clean up the module.
20222054 self .clean_up ()
0 commit comments