8000 gh-117378: Only run the new multiprocessing SysPath test when appropr… · miss-islington/cpython@ecec36d · GitHub
[go: up one dir, main page]

Skip to content

Commit ecec36d

Browse files
gpsheadmiss-islington
authored andcommitted
pythongh-117378: Only run the new multiprocessing SysPath test when appropriate (pythonGH-126635)
The first version had it running two forkserver and one spawn tests underneath each of the _fork, _forkserver, and _spawn test suites that build off the generic one. This adds to the existing complexity of the multiprocessing test suite by offering BaseTestCase classes another attribute to control which suites they are invoked under. Practicality vs purity here. :/ Net result: we don't over-run the new test and their internal logic is simplified. (cherry picked from commit ca878b6) Co-authored-by: Gregory P. Smith <greg@krypto.org>
1 parent 9473ae9 commit ecec36d

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

Lib/test/_test_multiprocessing.py

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ def __call__(self, *args, **kwds):
258258
class 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:
@@ -6349,7 +6352,9 @@ def test_atexit(self):
63496352
class _TestSpawnedSysPath(BaseTestCase):
63506353
"""Test that sys.path is setup in forkserver and spawn processes."""
63516354

6352-
ALLOWED_TYPES = ('processes',)
6355+
ALLOWED_TYPES = {'processes'}
6356+
# Not applicable to fork which inherits everything from the process as is.
6357+
START_METHODS = {"forkserver", "spawn"}
63536358

63546359
def setUp(self):
63556360
self._orig_sys_path = list(sys.path)
@@ -6361,11 +6366,8 @@ def setUp(self):
63616366
sys.path[:] = [p for p in sys.path if p] # remove any existing ""s
63626367
sys.path.insert(0, self._temp_dir)
63636368
sys.path.insert(0, "") # Replaced with an abspath in child.
6364-
try:
6365-
self._ctx_forkserver = multiprocessing.get_context("forkserver")
6366-
except ValueError:
6367-
self._ctx_forkserver = None
6368-
self._ctx_spawn = multiprocessing.get_context("spawn")
6369+
self.assertIn(self.start_method, self.START_METHODS)
6370+
self._ctx = multiprocessing.get_context(self.start_method)
63696371

63706372
def tearDown(self):
63716373
sys.path[:] = self._orig_sys_path
@@ -6376,15 +6378,15 @@ def enq_imported_module_names(queue):
63766378
queue.put(tuple(sys.modules))
63776379

63786380
def test_forkserver_preload_imports_sys_path(self):
6379-
ctx = self._ctx_forkserver
6380-
if not ctx:
6381-
self.skipTest("requires forkserver start method.")
6381+
if self._ctx.get_start_method() != "forkserver":
6382+
self.skipTest("forkserver specific test.")
63826383
self.assertNotIn(self._mod_name, sys.modules)
63836384
multiprocessing.forkserver._forkserver._stop() # Must be fresh.
6384-
ctx.set_forkserver_preload(
6385+
self._ctx.set_forkserver_preload(
63856386
["test.test_multiprocessing_forkserver", self._mod_name])
6386-
q = ctx.Queue()
6387-
proc = ctx.Process(target=self.enq_imported_module_names, args=(q,))
6387+
q = self._ctx.Queue()
6388+
proc = self._ctx.Process(
6389+
target=self.enq_imported_module_names, args=(q,))
63886390
proc.start()
63896391
proc.join()
63906392
child_imported_modules = q.get()
@@ -6402,23 +6404,19 @@ def enq_sys_path_and_import(queue, mod_name):
64026404
queue.put(None)
64036405

64046406
def test_child_sys_path(self):
6405-
for ctx in (self._ctx_spawn, self._ctx_forkserver):
6406-
if not ctx:
6407-
continue
6408-
with self.subTest(f"{ctx.get_start_method()} start method"):
6409-
q = ctx.Queue()
6410-
proc = ctx.Process(target=self.enq_sys_path_and_import,
6411-
args=(q, self._mod_name))
6412-
proc.start()
6413-
proc.join()
6414-
child_sys_path = q.get()
6415-
import_error = q.get()
6416-
q.close()
6417-
self.assertNotIn("", child_sys_path) # replaced by an abspath
6418-
self.assertIn(self._temp_dir, child_sys_path) # our addition
6419-
# ignore the first element, it is the absolute "" replacement
6420-
self.assertEqual(child_sys_path[1:], sys.path[1:])
6421-
self.assertIsNone(import_error, msg=f"child could not import {self._mod_name}")
6407+
q = self._ctx.Queue()
6408+
proc = self._ctx.Process(
6409+
target=self.enq_sys_path_and_import, args=(q, self._mod_name))
6410+
proc.start()
6411+
proc.join()
6412+
child_sys_path = q.get()
6413+
import_error = q.get()
6414+
q.close()
6415+
self.assertNotIn("", child_sys_path) # replaced by an abspath
6416+
self.assertIn(self._temp_dir, child_sys_path) # our addition
6417+
# ignore the first element, it is the absolute "" replacement
6418+
self.assertEqual(child_sys_path[1:], sys.path[1:])
6419+
self.assertIsNone(import_error, msg=f"child could not import {self._mod_name}")
64226420

64236421

64246422
class MiscTestCase(unittest.TestCase):
@@ -6615,6 +6613,8 @@ def install_tests_in_module_dict(remote_globs, start_method,
66156613
if base is BaseTestCase:
66166614
continue
66176615
assert set(base.ALLOWED_TYPES) <= ALL_TYPES, base.ALLOWED_TYPES
6616+
if base.START_METHODS and start_method not in base.START_METHODS:
6617+
continue # class not intended for this start method.
66186618
for type_ in base.ALLOWED_TYPES:
66196619
if only_type and type_ != only_type:
66206620
continue
@@ -6628,6 +6628,7 @@ class Temp(base, Mixin, unittest.TestCase):
66286628
Temp = hashlib_helper.requires_hashdigest('sha256')(Temp)
66296629
Temp.__name__ = Temp.__qualname__ = newname
66306630
Temp.__module__ = __module__
6631+
Temp.start_method = start_method
66316632
remote_globs[newname] = Temp
66326633
elif issubclass(base, unittest.TestCase):
66336634
if only_type:

0 commit comments

Comments
 (0)
0