@@ -6516,6 +6516,62 @@ def test_forkserver_requires_writeable_tempdir(self, mode):
65166516 _ , out , err = script_helper .assert_python_ok ('-c' , cmd , TMPDIR = TMPDIR )
65176517 self .assertEqual (out .decode ().strip (), "spawn" )
65186518
6519+ @unittest .skipIf (os .name == "nt" , "requires POSIX" )
6520+ @support .requires_non_root_user
6521+ def test_default_start_method_without_usable_tempdir (self ):
6522+ # Neither importing multiprocessing nor determining the default
6523+ # start method may fail when tempfile finds no usable temporary
6524+ # directory at all, and the default start method must be 'spawn'.
6525+ #
6526+ # See https://github.com/python/cpython/issues/155717.
6527+
6528+ cmd = '''if 1:
6529+ import os, tempfile
6530+ # Make TMPDIR the only candidate, so that tempfile.gettempdir()
6531+ # raises FileNotFoundError instead of falling back to /tmp.
6532+ tempfile._candidate_tempdir_list = lambda: [os.environ["TMPDIR"]]
6533+ try:
6534+ tempfile.gettempdir()
6535+ except FileNotFoundError:
6536+ pass
6537+ else:
6538+ raise AssertionError("TMPDIR is usable")
6539+
6540+ import multiprocessing
6541+ if __name__ == "__main__":
6542+ print(multiprocessing.get_start_method(),
6543+ multiprocessing.get_all_start_methods()[0])
6544+ '''
6545+
6546+ with support .os_helper .temp_dir () as root :
6547+ TMPDIR = pathlib .Path (root , "TMPDIR" )
6548+ TMPDIR .mkdir (mode = os .R_OK | os .X_OK )
6549+ _ , out , err = script_helper .assert_python_ok ('-c' , cmd , TMPDIR = TMPDIR )
6550+ self .assertEqual (out .decode ().split (), ["spawn" , "spawn" ])
6551+
6552+ def test_import_does_not_determine_default_start_method (self ):
6553+ # Determining the default start method requires checking that the
6554+ # temporary directory is writeable. That must not happen, nor may
6555+ # the modules it needs be loaded, when importing multiprocessing.
6556+ import_helper .ensure_lazy_imports (
6557+ "multiprocessing" , {"tempfile" , "shutil" , "subprocess" })
6558+
6559+ cmd = '''if 1:
6560+ import sys
6561+ import multiprocessing
6562+ print(multiprocessing.get_start_method(allow_none=True),
6563+ "tempfile" in sys.modules,
6564+ multiprocessing.get_start_method(),
6565+ multiprocessing.get_all_start_methods()[0])
6566+ '''
6567+ # -S: site customizations could import tempfile themselves.
6568+ _ , out , err = script_helper .assert_python_ok ('-S' , '-c' , cmd )
6569+ unset , probed , method , first = out .decode ().split ()
6570+ self .assertEqual (unset , "None" )
6571+ self .assertEqual (probed , "False" )
6572+ self .assertEqual (method , first )
6573+ self .assertIn (method , multiprocessing .get_all_start_methods ())
6574+
65196575
65206576@unittest .skipIf (sys .platform == "win32" ,
65216577 "test semantics don't make sense on Windows" )
0 commit comments