Visitar URL original
GH-84559: Deprecate fork being the multiprocessing default. by gpshead · Pull Request #100618 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
address CI test failures?
  • Loading branch information
gpshead committed Dec 31, 2022
commit df83fba6c7c3727664dda2e644decd9e423f3b50
5 changes: 4 additions & 1 deletion Lib/multiprocessing/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class TimeoutError(ProcessError):
class AuthenticationError(ProcessError):
pass

class DefaultsDeprecationWarning(DeprecationWarning):
pass

#
# Base type for contexts. Bound methods of an instance of this type are included in __all__ of __init__.py
#
Expand Down Expand Up @@ -293,7 +296,7 @@ def _warn(cls, stacklevel):
"application's start method if you want to use 'fork'."
" The 'spawn' and 'forkserver' start methods are safer "
"depending on the platform and application.",
category=DeprecationWarning,
category=DefaultsDeprecationWarning,
stacklevel=stacklevel,
)

Expand Down
21 changes: 13 additions & 8 deletions Lib/test/_test_multiprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4098,9 +4098,10 @@ def test_shared_memory_SharedMemoryServer_ignores_sigint(self):
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()
Expand Down Expand Up @@ -4967,11 +4968,13 @@ def run_in_grandchild(cls, conn):
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()
Expand All @@ -4982,8 +4985,10 @@ def run_in_child(cls):
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'))
Expand Down
18 changes: 12 additions & 6 deletions Lib/test/test_multiprocessing_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from inspect import currentframe, getframeinfo
import multiprocessing
from multiprocessing.context import DefaultsDeprecationWarning
import sys
from test.support import threading_helper
import unittest
Expand All @@ -27,31 +28,36 @@ def setUp(self):

def test_default_fork_start_method_warning_process(self):
with warnings.catch_warnings(record=True) as ws:
warnings.simplefilter('always')
warnings.simplefilter('ignore')
warnings.filterwarnings('always', category=DefaultsDeprecationWarning)
process = multiprocessing.Process(target=do_nothing)
process.start() # warning should point here.
join_process(process)
self.assertEqual(len(ws), 1, msg=[str(x) for x in ws])
self.assertIsInstance(ws[0].message, DefaultsDeprecationWarning)
self.assertIn(__file__, ws[0].filename)
self.assertEqual(getframeinfo(currentframe()).lineno-4, ws[0].lineno)
self.assertIn("'fork'", str(ws[0].message))
self.assertIn("start_method API", 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('always')
warnings.simplefilter('ignore')
warnings.filterwarnings('always', category=DefaultsDeprecationWarning)
pool = multiprocessing.Pool(1) # warning should point here.
pool.terminate()
pool.join()
self.assertEqual(len(ws), 1, msg=[str(x) for x in ws])
self.assertIsInstance(ws[0].message, DefaultsDeprecationWarning)
self.assertIn(__file__, ws[0].filename)
self.assertEqual(getframeinfo(currentframe()).lineno-5, ws[0].lineno)
self.assertIn("'fork'", str(ws[0].message))
self.assertIn("start_method API", str(ws[0].message))
self.assertEqual(len(ws), 1, msg=[str(x) for x in ws])

def test_no_warning_when_using_explicit_fork_mp_context(self):
def test_no_mp_warning_when_using_explicit_fork_context(self):
with warnings.catch_warnings(record=True) as ws:
warnings.simplefilter('always') # Enable all warnings.
warnings.simplefilter('ignore')
warnings.filterwarnings('always', category=DefaultsDeprecationWarning)
fork_mp = multiprocessing.get_context('fork')
pool = fork_mp.Pool(1)
pool.terminate()
Expand Down