@@ -7155,9 +7155,8 @@ def test_datetime_from_timestamp(self):
71557155
71567156                    self .assertEqual (dt_orig , dt_rt )
71577157
7158-     def  assert_python_in_subinterp (self , check_if_ok : bool , script ,
7159-                                    setup = '_testcapi.test_datetime_capi()' ,
7160-                                    config = 'isolated' ):
7158+     def  assert_python_in_subinterp (self , check_if_ok , script , init = '' ,
7159+                                    fini = '' , repeat = 1 , config = 'isolated' ):
71617160        # iOS requires the use of the custom framework loader, 
71627161        # not the ExtensionFileLoader. 
71637162        if  sys .platform  ==  "ios" :
@@ -7166,40 +7165,41 @@ def assert_python_in_subinterp(self, check_if_ok: bool, script,
71667165            extension_loader  =  "ExtensionFileLoader" 
71677166
71687167        code  =  textwrap .dedent (f''' 
7169-             import textwrap 
7170-             from test import support 
7171- 
7172-             subcode = textwrap.dedent(""" 
7173-                 if { _interpreters  is  None }  
7174-                     import _testcapi 
7175-                 else: 
7176-                     import importlib.machinery 
7177-                     import importlib.util 
7178-                     fullname = '_testcapi_datetime' 
7179-                     origin = importlib.util.find_spec('_testcapi').origin 
7180-                     loader = importlib.machinery.{ extension_loader }  
7181-                     spec = importlib.util.spec_from_loader(fullname, loader) 
7182-                     _testcapi = importlib.util.module_from_spec(spec) 
7183-                     spec.loader.exec_module(_testcapi) 
7184- 
7185-             $SCRIPT$ 
7186-             """) 
7187- 
7188-             import _testcapi 
7189-             $SETUP$ 
7190- 
7168+             subinterp_code = """ 
71917169            if { _interpreters  is  None }  
7192-                 ret = support.run_in_subinterp(subcode)  
7170+                 import _testcapi  
71937171            else: 
7194-                 import _interpreters 
7195-                 config = _interpreters.new_config('{ config }  
7196-                 ret = support.run_in_subinterp_with_config(subcode, **config) 
7172+                 import importlib.machinery 
7173+                 import importlib.util 
7174+                 fullname = '_testcapi_datetime' 
7175+                 origin = importlib.util.find_spec('_testcapi').origin 
7176+                 loader = importlib.machinery.{ extension_loader }  
7177+                 spec = importlib.util.spec_from_loader(fullname, loader) 
7178+                 _testcapi = importlib.util.module_from_spec(spec) 
7179+                 spec.loader.exec_module(_testcapi) 
7180+             INDEX = $INDEX$ 
7181+             setup = _testcapi.test_datetime_capi  # call it if needed 
7182+             $SCRIPT$ 
7183+             """ 
71977184
7198-             assert ret == 0 
7185+             import _testcapi 
7186+             from test import support 
7187+             setup = _testcapi.test_datetime_capi 
7188+             $INIT$ 
71997189
7200-         ''' ).rstrip ()
7201-         code  =  code .replace ('$SETUP$' , setup )
7202-         code  =  code .replace ('$SCRIPT$' , textwrap .indent (script , '\x20 ' * 4 ))
7190+             for idx in range({ repeat }  
7191+                 subcode = subinterp_code.replace('$INDEX$', str(idx)) 
7192+                 if { _interpreters  is  None }  
7193+                     ret = support.run_in_subinterp(subcode) 
7194+                 else: 
7195+                     import _interpreters 
7196+                     config = _interpreters.new_config('{ config }  
7197+                     ret = support.run_in_subinterp_with_config(subcode, **config) 
7198+                 assert ret == 0 
7199+             $FINI$ 
7200+         ''' )
7201+         code  =  code .replace ('$INIT$' , init ).replace ('$FINI$' , fini )
7202+         code  =  code .replace ('$SCRIPT$' , script )
72037203
72047204        if  check_if_ok :
72057205            res  =  script_helper .assert_python_ok ('-c' , code )
@@ -7213,18 +7213,18 @@ def run(type_checker, obj):
72137213                if not type_checker(obj, True): 
72147214                    raise TypeError(f'{{type(obj)}} is not C API type') 
72157215
7216-             _testcapi.test_datetime_capi () 
7216+             setup () 
72177217            import _datetime 
72187218            run(_testcapi.datetime_check_date,     _datetime.date.today()) 
72197219            run(_testcapi.datetime_check_datetime, _datetime.datetime.now()) 
72207220            run(_testcapi.datetime_check_time,     _datetime.time(12, 30)) 
72217221            run(_testcapi.datetime_check_delta,    _datetime.timedelta(1)) 
72227222            run(_testcapi.datetime_check_tzinfo,   _datetime.tzinfo()) 
72237223            """ )
7224-         self .assert_python_in_subinterp (True , script ,  '' )
7224+         self .assert_python_in_subinterp (True , script )
72257225        if  _interpreters  is  not None :
72267226            with  self .subTest (name  :=  'legacy' ):
7227-                 self .assert_python_in_subinterp (True , script , '' ,  name )
7227+                 self .assert_python_in_subinterp (True , script , config = name )
72287228
72297229
72307230class  ExtensionModuleTests (unittest .TestCase ):
@@ -7331,38 +7331,34 @@ def test_no_leak(self):
73317331        self .assertIn (b'[0 refs, 0 blocks]' , res .err )
73327332
73337333    def  test_static_type_on_subinterp (self ):
7334-         script  =  textwrap .dedent (f """
7334+         script  =  textwrap .dedent (""" 
73357335            date = _testcapi.get_capi_types()['date'] 
73367336            date.today 
73377337            """ )
7338-         # Fail before loaded 
73397338        with  self .subTest ('[PyDateTime_IMPORT] main: yes, sub: no' ):
7340-             self .assert_python_in_subinterp (False , script )
7339+             # FIXME: Segfault 
7340+             self .assert_python_in_subinterp (False , script , 'setup()' )
73417341
7342-         # OK after loaded 
7343-         script2  =  f'_testcapi.test_datetime_capi()\n { script }  
7342+         with_setup  =  'setup()'  +  script 
73447343        with  self .subTest ('[PyDateTime_IMPORT] main: no, sub: yes' ):
7345-             self .assert_python_in_subinterp (True , script2 ,  setup = '' )
7344+             self .assert_python_in_subinterp (True , with_setup )
73467345
73477346        with  self .subTest ('[PyDateTime_IMPORT] main: yes, sub: yes' ):
7348-             # Check if each test_datetime_capi() calls PyDateTime_IMPORT 
7349-             self .assert_python_in_subinterp (True , script2 )
7347+             # Check if PyDateTime_IMPORT is invoked not only once 
7348+             self .assert_python_in_subinterp (True , with_setup , 'setup()' )
7349+             self .assert_python_in_subinterp (True , 'setup()' , fini = with_setup )
7350+             self .assert_python_in_subinterp (True , with_setup , repeat = 2 )
73507351
7351-         script3  =  f 'import _datetime\n { script } ' 
7352-         with  self .subTest ('Regular  import' ):
7353-             self .assert_python_in_subinterp (True , script3 )
7352+         with_import  =  'import _datetime'    +   script 
7353+         with  self .subTest ('Explicit  import' ):
7354+             self .assert_python_in_subinterp (True , with_import ,  'setup()' )
73547355
7355-         script4  =  textwrap .dedent (f""" 
7356-             import sys 
7357-             assert '_datetime' not in sys.modules 
7356+         with_import  =  textwrap .dedent (""" 
73587357            timedelta = _testcapi.get_capi_types()['timedelta'] 
73597358            timedelta(days=1) 
7360-             assert '_datetime' in sys.modules 
7361-             date = _testcapi.get_capi_types()['date'] 
7362-             date.today 
7363-             """ )
7359+             """ ) +  script 
73647360        with  self .subTest ('Implicit import' ):
7365-             self .assert_python_in_subinterp (True , script4 )
7361+             self .assert_python_in_subinterp (True , with_import ,  'setup()' )
73667362
73677363    def  test_static_type_at_shutdown (self ):
73687364        # gh-132413 
@@ -7390,7 +7386,7 @@ def gen():
73907386            res  =  script_helper .assert_python_ok ('-c' , script )
73917387            self .assertFalse (res .err )
73927388        with  self .subTest ('Subinterpreter' ):
7393-             res  =  self .assert_python_in_subinterp (True , script ,  setup = '' )
7389+             res  =  self .assert_python_in_subinterp (True , script )
73947390            self .assertFalse (res .err )
73957391
73967392        script  =  textwrap .dedent (""" 
@@ -7445,17 +7441,12 @@ def gen():
74457441            next(it) 
74467442            """ )
74477443        with  self .subTest ('[PyDateTime_IMPORT] main: yes, sub: no' ):
7448-             res  =  self .assert_python_in_subinterp (True , script )
7444+             res  =  self .assert_python_in_subinterp (True , script ,  'setup()' )
74497445            self .assertIn (b'ImportError: sys.meta_path is None' , res .err )
74507446
7451-         script2  =  f'_testcapi.test_datetime_capi() \n { script } ' 
7447+         with_import  =  'setup()'   +   script 
74527448        with  self .subTest ('[PyDateTime_IMPORT] main: no, sub: yes' ):
7453-             res  =  self .assert_python_in_subinterp (True , script2 , setup = '' )
7454-             self .assertFalse (res .err )
7455- 
7456-         with  self .subTest ('[PyDateTime_IMPORT] main: yes, sub: yes' ):
7457-             # Check if each test_datetime_capi() calls PyDateTime_IMPORT 
7458-             res  =  self .assert_python_in_subinterp (True , script2 )
7449+             res  =  self .assert_python_in_subinterp (True , with_import )
74597450            self .assertFalse (res .err )
74607451
74617452
0 commit comments