@@ -258,6 +258,9 @@ def __call__(self, *args, **kwds):
258258class  BaseTestCase (object ):
259259
260260    ALLOWED_TYPES  =  ('processes' , 'manager' , 'threads' )
261+     # If not empty, limit which start method suites run this class. 
262+     START_METHODS : set [str ] =  set ()
263+     start_method  =  None   # set by install_tests_in_module_dict() 
261264
262265    def  assertTimingAlmostEqual (self , a , b ):
263266        if  CHECK_TIMINGS :
@@ -6202,7 +6205,9 @@ def submain(): pass
62026205class  _TestSpawnedSysPath (BaseTestCase ):
62036206    """Test that sys.path is setup in forkserver and spawn processes.""" 
62046207
6205-     ALLOWED_TYPES  =  ('processes' ,)
6208+     ALLOWED_TYPES  =  {'processes' }
6209+     # Not applicable to fork which inherits everything from the process as is. 
6210+     START_METHODS  =  {"forkserver" , "spawn" }
62066211
62076212    def  setUp (self ):
62086213        self ._orig_sys_path  =  list (sys .path )
@@ -6214,11 +6219,8 @@ def setUp(self):
62146219        sys .path [:] =  [p  for  p  in  sys .path  if  p ]  # remove any existing ""s 
62156220        sys .path .insert (0 , self ._temp_dir )
62166221        sys .path .insert (0 , "" )  # Replaced with an abspath in child. 
6217-         try :
6218-             self ._ctx_forkserver  =  multiprocessing .get_context ("forkserver" )
6219-         except  ValueError :
6220-             self ._ctx_forkserver  =  None 
6221-         self ._ctx_spawn  =  multiprocessing .get_context ("spawn" )
6222+         self .assertIn (self .start_method , self .START_METHODS )
6223+         self ._ctx  =  multiprocessing .get_context (self .start_method )
62226224
62236225    def  tearDown (self ):
62246226        sys .path [:] =  self ._orig_sys_path 
@@ -6229,15 +6231,15 @@ def enq_imported_module_names(queue):
62296231        queue .put (tuple (sys .modules ))
62306232
62316233    def  test_forkserver_preload_imports_sys_path (self ):
6232-         ctx  =  self ._ctx_forkserver 
6233-         if  not  ctx :
6234-             self .skipTest ("requires forkserver start method." )
6234+         if  self ._ctx .get_start_method () !=  "forkserver" :
6235+             self .skipTest ("forkserver specific test." )
62356236        self .assertNotIn (self ._mod_name , sys .modules )
62366237        multiprocessing .forkserver ._forkserver ._stop ()  # Must be fresh. 
6237-         ctx .set_forkserver_preload (
6238+         self . _ctx .set_forkserver_preload (
62386239            ["test.test_multiprocessing_forkserver" , self ._mod_name ])
6239-         q  =  ctx .Queue ()
6240-         proc  =  ctx .Process (target = self .enq_imported_module_names , args = (q ,))
6240+         q  =  self ._ctx .Queue ()
6241+         proc  =  self ._ctx .Process (
6242+                 target = self .enq_imported_module_names , args = (q ,))
62416243        proc .start ()
62426244        proc .join ()
62436245        child_imported_modules  =  q .get ()
@@ -6255,23 +6257,19 @@ def enq_sys_path_and_import(queue, mod_name):
62556257            queue .put (None )
62566258
62576259    def  test_child_sys_path (self ):
6258-         for  ctx  in  (self ._ctx_spawn , self ._ctx_forkserver ):
6259-             if  not  ctx :
6260-                 continue 
6261-             with  self .subTest (f"{ ctx .get_start_method ()}  ):
6262-                 q  =  ctx .Queue ()
6263-                 proc  =  ctx .Process (target = self .enq_sys_path_and_import ,
6264-                                    args = (q , self ._mod_name ))
6265-                 proc .start ()
6266-                 proc .join ()
6267-                 child_sys_path  =  q .get ()
6268-                 import_error  =  q .get ()
6269-                 q .close ()
6270-                 self .assertNotIn ("" , child_sys_path )  # replaced by an abspath 
6271-                 self .assertIn (self ._temp_dir , child_sys_path )  # our addition 
6272-                 # ignore the first element, it is the absolute "" replacement 
6273-                 self .assertEqual (child_sys_path [1 :], sys .path [1 :])
6274-                 self .assertIsNone (import_error , msg = f"child could not import { self ._mod_name }  )
6260+         q  =  self ._ctx .Queue ()
6261+         proc  =  self ._ctx .Process (
6262+                 target = self .enq_sys_path_and_import , args = (q , self ._mod_name ))
6263+         proc .start ()
6264+         proc .join ()
6265+         child_sys_path  =  q .get ()
6266+         import_error  =  q .get ()
6267+         q .close ()
6268+         self .assertNotIn ("" , child_sys_path )  # replaced by an abspath 
6269+         self .assertIn (self ._temp_dir , child_sys_path )  # our addition 
6270+         # ignore the first element, it is the absolute "" replacement 
6271+         self .assertEqual (child_sys_path [1 :], sys .path [1 :])
6272+         self .assertIsNone (import_error , msg = f"child could not import { self ._mod_name }  )
62756273
62766274
62776275class  MiscTestCase (unittest .TestCase ):
@@ -6450,6 +6448,8 @@ def install_tests_in_module_dict(remote_globs, start_method,
64506448            if  base  is  BaseTestCase :
64516449                continue 
64526450            assert  set (base .ALLOWED_TYPES ) <=  ALL_TYPES , base .ALLOWED_TYPES 
6451+             if  base .START_METHODS  and  start_method  not  in base .START_METHODS :
6452+                 continue   # class not intended for this start method. 
64536453            for  type_  in  base .ALLOWED_TYPES :
64546454                if  only_type  and  type_  !=  only_type :
64556455                    continue 
@@ -6463,6 +6463,7 @@ class Temp(base, Mixin, unittest.TestCase):
64636463                    Temp  =  hashlib_helper .requires_hashdigest ('sha256' )(Temp )
64646464                Temp .__name__  =  Temp .__qualname__  =  newname 
64656465                Temp .__module__  =  __module__ 
6466+                 Temp .start_method  =  start_method 
64666467                remote_globs [newname ] =  Temp 
64676468        elif  issubclass (base , unittest .TestCase ):
64686469            if  only_type :
0 commit comments