1010import os
1111import itertools
1212import sys
13+ import tempfile
1314import weakref
1415import atexit
1516import threading # we want threading to install it's
@@ -143,6 +144,7 @@ def is_abstract_socket_namespace(address):
143144 # On Windows platforms, we do not create AF_UNIX sockets.
144145 _SUN_PATH_MAX = None if os .name == 'nt' else 92
145146
147+
146148def _remove_temp_dir (rmtree , tempdir ):
147149 rmtree (tempdir )
148150
@@ -152,7 +154,8 @@ def _remove_temp_dir(rmtree, tempdir):
152154 if current_process is not None :
153155 current_process ._config ['tempdir' ] = None
154156
155- def _get_base_temp_dir (tempfile ):
157+
158+ def _get_base_temp_dir ():
156159 """Get a temporary directory where socket files will be created.
157160
158161 To prevent additional imports, pass a pre-imported 'tempfile' module.
@@ -208,12 +211,13 @@ def _get_base_temp_dir(tempfile):
208211 assert len (base_system_tempdir ) + 14 + 14 < _SUN_PATH_MAX
209212 return base_system_tempdir
210213
214+
211215def get_temp_dir ():
212216 # get name of a temp directory which will be automatically cleaned up
213217 tempdir = process .current_process ()._config .get ('tempdir' )
214218 if tempdir is None :
215- import shutil , tempfile
216- base_tempdir = _get_base_temp_dir (tempfile )
219+ import shutil
220+ base_tempdir = _get_base_temp_dir ()
217221 tempdir = tempfile .mkdtemp (prefix = 'pymp-' , dir = base_tempdir )
218222 info ('created temp directory %s' , tempdir )
219223 # keep a strong reference to shutil.rmtree(), since the finalizer
@@ -223,6 +227,27 @@ def get_temp_dir():
223227 process .current_process ()._config ['tempdir' ] = tempdir
224228 return tempdir
225229
230+
231+ def _has_writeable_tempdir ():
232+ # 'forkserver' requires writeable temporary files. This function must
233+ # is called for defining the default context's start method.
234+ #
235+ # See: https://github.com/python/cpython/issues/155717.
236+
237+ path = _get_base_temp_dir ()
238+ if path is None :
239+ return False
240+
241+ # os.access() is advisory and racy. It can lie on read-only filesystems,
242+ # NFS/network mounts, containers, and immutable-flag files, so we simply
243+ # try to create a file to check if this works and delete it otherwise.
244+ try :
245+ with tempfile .NamedTemporaryFile (dir = path ):
246+ return True
247+ except OSError :
248+ return False
249+
250+
226251#
227252# Support for reinitialization of objects when bootstrapping a child process
228253#
0 commit comments