summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/_test_multiprocessing.py21
-rw-r--r--Lib/test/_test_venv_multiprocessing.py1
-rw-r--r--Lib/test/test_asyncio/test_events.py9
-rw-r--r--Lib/test/test_concurrent_futures.py19
-rw-r--r--Lib/test/test_fcntl.py8
-rw-r--r--Lib/test/test_logging.py5
-rw-r--r--Lib/test/test_multiprocessing_defaults.py82
-rw-r--r--Lib/test/test_pickle.py2
-rw-r--r--Lib/test/test_re.py3
9 files changed, 135 insertions, 15 deletions
diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py
index 2fa75eb..e4a60a4 100644
--- a/Lib/test/_test_multiprocessing.py
+++ b/Lib/test/_test_multiprocessing.py
@@ -4098,9 +4098,10 @@ class _TestSharedMemory(BaseTestCase):
def test_shared_memory_SharedMemoryManager_reuses_resource_tracker(self):
# bpo-36867: test that a SharedMemoryManager uses the
# same resource_tracker process as its parent.
- cmd = '''if 1:
+ cmd = f'''if 1:
from multiprocessing.managers import SharedMemoryManager
-
+ from multiprocessing import set_start_method
+ set_start_method({multiprocessing.get_start_method()!r})
smm = SharedMemoryManager()
smm.start()
@@ -4967,11 +4968,13 @@ class TestFlags(unittest.TestCase):
conn.send(tuple(sys.flags))
@classmethod
- def run_in_child(cls):
+ def run_in_child(cls, start_method):
import json
- r, w = multiprocessing.Pipe(duplex=False)
- p = multiprocessing.Process(target=cls.run_in_grandchild, args=(w,))
- p.start()
+ mp = multiprocessing.get_context(start_method)
+ r, w = mp.Pipe(duplex=False)
+ p = mp.Process(target=cls.run_in_grandchild, args=(w,))
+ with warnings.catch_warnings(category=DeprecationWarning):
+ p.start()
grandchild_flags = r.recv()
p.join()
r.close()
@@ -4982,8 +4985,10 @@ class TestFlags(unittest.TestCase):
def test_flags(self):
import json
# start child process using unusual flags
- prog = ('from test._test_multiprocessing import TestFlags; ' +
- 'TestFlags.run_in_child()')
+ prog = (
+ 'from test._test_multiprocessing import TestFlags; '
+ f'TestFlags.run_in_child({multiprocessing.get_start_method()!r})'
+ )
data = subprocess.check_output(
[sys.executable, '-E', '-S', '-O', '-c', prog])
child_flags, grandchild_flags = json.loads(data.decode('ascii'))
diff --git a/Lib/test/_test_venv_multiprocessing.py b/Lib/test/_test_venv_multiprocessing.py
index af72e91..044a0c6 100644
--- a/Lib/test/_test_venv_multiprocessing.py
+++ b/Lib/test/_test_venv_multiprocessing.py
@@ -30,6 +30,7 @@ def test_func():
def main():
+ multiprocessing.set_start_method('spawn')
test_pool = multiprocessing.Process(target=test_func)
test_pool.start()
test_pool.join()
diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py
index 214544b..b906905 100644
--- a/Lib/test/test_asyncio/test_events.py
+++ b/Lib/test/test_asyncio/test_events.py
@@ -4,6 +4,7 @@ import collections.abc
import concurrent.futures
import functools
import io
+import multiprocessing
import os
import platform
import re
@@ -2762,7 +2763,13 @@ class GetEventLoopTestsMixin:
support.skip_if_broken_multiprocessing_synchronize()
async def main():
- pool = concurrent.futures.ProcessPoolExecutor()
+ if multiprocessing.get_start_method() == 'fork':
+ # Avoid 'fork' DeprecationWarning.
+ mp_context = multiprocessing.get_context('forkserver')
+ else:
+ mp_context = None
+ pool = concurrent.futures.ProcessPoolExecutor(
+ mp_context=mp_context)
result = await self.loop.run_in_executor(
pool, _test_get_event_loop_new_process__sub_proc)
pool.shutdown()
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
index b3520ae..4493cd3 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -18,6 +18,7 @@ import sys
import threading
import time
import unittest
+import warnings
import weakref
from pickle import PicklingError
@@ -571,6 +572,24 @@ class ProcessPoolShutdownTest(ExecutorShutdownTest):
assert all([r == abs(v) for r, v in zip(res, range(-5, 5))])
+@unittest.skipIf(mp.get_all_start_methods()[0] != "fork", "non-fork default.")
+class ProcessPoolExecutorDefaultForkWarning(unittest.TestCase):
+ def test_fork_default_warns(self):
+ with self.assertWarns(mp.context.DefaultForkDeprecationWarning):
+ with futures.ProcessPoolExecutor(2):
+ pass
+
+ def test_explicit_fork_does_not_warn(self):
+ with warnings.catch_warnings(record=True) as ws:
+ warnings.simplefilter("ignore")
+ warnings.filterwarnings(
+ 'always', category=mp.context.DefaultForkDeprecationWarning)
+ ctx = mp.get_context("fork") # Non-default fork context.
+ with futures.ProcessPoolExecutor(2, mp_context=ctx):
+ pass
+ self.assertEqual(len(ws), 0, msg=[str(x) for x in ws])
+
+
create_executor_tests(ProcessPoolShutdownTest,
executor_mixins=(ProcessPoolForkMixin,
ProcessPoolForkserverMixin,
diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py
index fc8c393..113c780 100644
--- a/Lib/test/test_fcntl.py
+++ b/Lib/test/test_fcntl.py
@@ -1,11 +1,11 @@
"""Test program for the fcntl C module.
"""
+import multiprocessing
import platform
import os
import struct
import sys
import unittest
-from multiprocessing import Process
from test.support import verbose, cpython_only
from test.support.import_helper import import_module
from test.support.os_helper import TESTFN, unlink
@@ -160,7 +160,8 @@ class TestFcntl(unittest.TestCase):
self.f = open(TESTFN, 'wb+')
cmd = fcntl.LOCK_EX | fcntl.LOCK_NB
fcntl.lockf(self.f, cmd)
- p = Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd))
+ mp = multiprocessing.get_context('spawn')
+ p = mp.Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd))
p.start()
p.join()
fcntl.lockf(self.f, fcntl.LOCK_UN)
@@ -171,7 +172,8 @@ class TestFcntl(unittest.TestCase):
self.f = open(TESTFN, 'wb+')
cmd = fcntl.LOCK_SH | fcntl.LOCK_NB
fcntl.lockf(self.f, cmd)
- p = Process(target=try_lockf_on_other_process, args=(TESTFN, cmd))
+ mp = multiprocessing.get_context('spawn')
+ p = mp.Process(target=try_lockf_on_other_process, args=(TESTFN, cmd))
p.start()
p.join()
fcntl.lockf(self.f, fcntl.LOCK_UN)
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 072056d..8a12d57 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -4759,8 +4759,9 @@ class LogRecordTest(BaseTest):
# In other processes, processName is correct when multiprocessing in imported,
# but it is (incorrectly) defaulted to 'MainProcess' otherwise (bpo-38762).
import multiprocessing
- parent_conn, child_conn = multiprocessing.Pipe()
- p = multiprocessing.Process(
+ mp = multiprocessing.get_context('spawn')
+ parent_conn, child_conn = mp.Pipe()
+ p = mp.Process(
target=self._extract_logrecord_process_name,
args=(2, LOG_MULTI_PROCESSING, child_conn,)
)
diff --git a/Lib/test/test_multiprocessing_defaults.py b/Lib/test/test_multiprocessing_defaults.py
new file mode 100644
index 0000000..1da4c06
--- /dev/null
+++ b/Lib/test/test_multiprocessing_defaults.py
@@ -0,0 +1,82 @@
+"""Test default behavior of multiprocessing."""
+
+from inspect import currentframe, getframeinfo
+import multiprocessing
+from multiprocessing.context import DefaultForkDeprecationWarning
+import sys
+from test.support import threading_helper
+import unittest
+import warnings
+
+
+def do_nothing():
+ pass
+
+
+# Process has the same API as Thread so this helper works.
+join_process = threading_helper.join_thread
+
+
+class DefaultWarningsTest(unittest.TestCase):
+
+ @unittest.skipIf(sys.platform in ('win32', 'darwin'),
+ 'The default is not "fork" on Windows or macOS.')
+ def setUp(self):
+ self.assertEqual(multiprocessing.get_start_method(), 'fork')
+ self.assertIsInstance(multiprocessing.get_context(),
+ multiprocessing.context._DefaultForkContext)
+
+ def test_default_fork_start_method_warning_process(self):
+ with warnings.catch_warnings(record=True) as ws:
+ warnings.simplefilter('ignore')
+ warnings.filterwarnings('always', category=DefaultForkDeprecationWarning)
+ process = multiprocessing.Process(target=do_nothing)
+ process.start() # warning should point here.
+ join_process(process)
+ self.assertIsInstance(ws[0].message, DefaultForkDeprecationWarning)
+ self.assertIn(__file__, ws[0].filename)
+ self.assertEqual(getframeinfo(currentframe()).lineno-4, ws[0].lineno)
+ self.assertIn("'fork'", str(ws[0].message))
+ self.assertIn("get_context", str(ws[0].message))
+ self.assertEqual(len(ws), 1, msg=[str(x) for x in ws])
+
+ def test_default_fork_start_method_warning_pool(self):
+ with warnings.catch_warnings(record=True) as ws:
+ warnings.simplefilter('ignore')
+ warnings.filterwarnings('always', category=DefaultForkDeprecationWarning)
+ pool = multiprocessing.Pool(1) # warning should point here.
+ pool.terminate()
+ pool.join()
+ self.assertIsInstance(ws[0].message, DefaultForkDeprecationWarning)
+ self.assertIn(__file__, ws[0].filename)
+ self.assertEqual(getframeinfo(currentframe()).lineno-5, ws[0].lineno)
+ self.assertIn("'fork'", str(ws[0].message))
+ self.assertIn("get_context", str(ws[0].message))
+ self.assertEqual(len(ws), 1, msg=[str(x) for x in ws])
+
+ def test_default_fork_start_method_warning_manager(self):
+ with warnings.catch_warnings(record=True) as ws:
+ warnings.simplefilter('ignore')
+ warnings.filterwarnings('always', category=DefaultForkDeprecationWarning)
+ manager = multiprocessing.Manager() # warning should point here.
+ manager.shutdown()
+ self.assertIsInstance(ws[0].message, DefaultForkDeprecationWarning)
+ self.assertIn(__file__, ws[0].filename)
+ self.assertEqual(getframeinfo(currentframe()).lineno-4, ws[0].lineno)
+ self.assertIn("'fork'", str(ws[0].message))
+ self.assertIn("get_context", str(ws[0].message))
+ self.assertEqual(len(ws), 1, msg=[str(x) for x in ws])
+
+ def test_no_mp_warning_when_using_explicit_fork_context(self):
+ with warnings.catch_warnings(record=True) as ws:
+ warnings.simplefilter('ignore')
+ warnings.filterwarnings('always', category=DefaultForkDeprecationWarning)
+ fork_mp = multiprocessing.get_context('fork')
+ pool = fork_mp.Pool(1)
+ pool.terminate()
+ pool.join()
+ self.assertEqual(len(ws), 0, msg=[str(x) for x in ws])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py
index 44fdca7..80e7a4d 100644
--- a/Lib/test/test_pickle.py
+++ b/Lib/test/test_pickle.py
@@ -533,6 +533,8 @@ class CompatPickleTests(unittest.TestCase):
def test_multiprocessing_exceptions(self):
module = import_helper.import_module('multiprocessing.context')
for name, exc in get_exceptions(module):
+ if issubclass(exc, Warning):
+ continue
with self.subTest(name):
self.assertEqual(reverse_mapping('multiprocessing.context', name),
('multiprocessing', name))
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 11628a2..eacb1a7 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -2431,7 +2431,8 @@ class ReTests(unittest.TestCase):
input_js = '''a(function() {
///////////////////////////////////////////////////////////////////
});'''
- p = multiprocessing.Process(target=pattern.sub, args=('', input_js))
+ mp = multiprocessing.get_context('spawn')
+ p = mp.Process(target=pattern.sub, args=('', input_js))
p.start()
p.join(SHORT_TIMEOUT)
try: