Skip to content

Commit 5753c73

Browse files
gh-66305: Fix a hang for a few seconds on Windows in the tempfile module
It occurred when trying to create a temporary file or subdirectory in a non-writable directory.
1 parent 704b915 commit 5753c73

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

Lib/tempfile.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,7 @@
5757
if hasattr(_os, 'O_BINARY'):
5858
_bin_openflags |= _os.O_BINARY
5959

60-
if hasattr(_os, 'TMP_MAX'):
61-
TMP_MAX = _os.TMP_MAX
62-
else:
63-
TMP_MAX = 10000
60+
TMP_MAX = 100
6461

6562
# This variable _was_ unused for legacy reasons, see issue 10354.
6663
# But as of 3.5 we actually use it at runtime so changing it would
@@ -213,10 +210,14 @@ def _get_default_tempdir(dirlist=None):
213210
except FileExistsError:
214211
pass
215212
except PermissionError:
216-
# This exception is thrown when a directory with the chosen name
217-
# already exists on windows.
218-
if (_os.name == 'nt' and _os.path.isdir(dir) and
219-
_os.access(dir, _os.W_OK)):
213+
# On Posix, this exception is raised when the user has no
214+
# write access to the parent directory.
215+
# On Windows, it is also raised when a directory with
216+
# the chosen name already exists, or if the parent directory
217+
# is not a directory.
218+
# We cannot distinguish between "directory-exists-error" and
219+
# "access-denied-error".
220+
if _os.name == 'nt' and _os.path.isdir(dir):
220221
continue
221222
break # no point trying more names in this directory
222223
except OSError:
@@ -258,10 +259,14 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type):
258259
except FileExistsError:
259260
continue # try again
260261
except PermissionError:
261-
# This exception is thrown when a directory with the chosen name
262-
# already exists on windows.
263-
if (_os.name == 'nt' and _os.path.isdir(dir) and
264-
_os.access(dir, _os.W_OK)):
262+
# On Posix, this exception is raised when the user has no
263+
# write access to the parent directory.
264+
# On Windows, it is also raised when a directory with
265+
# the chosen name already exists, or if the parent directory
266+
# is not a directory.
267+
# We cannot distinguish between "directory-exists-error" and
268+
# "access-denied-error".
269+
if _os.name == 'nt' and _os.path.isdir(dir) and seq < TMP_MAX - 1:
265270
continue
266271
else:
267272
raise
@@ -386,10 +391,14 @@ def mkdtemp(suffix=None, prefix=None, dir=None):
386391
except FileExistsError:
387392
continue # try again
388393
except PermissionError:
389-
# This exception is thrown when a directory with the chosen name
390-
# already exists on windows.
391-
if (_os.name == 'nt' and _os.path.isdir(dir) and
392-
_os.access(dir, _os.W_OK)):
394+
# On Posix, this exception is raised when the user has no
395+
# write access to the parent directory.
396+
# On Windows, it is also raised when a directory with
397+
# the chosen name already exists, or if the parent directory
398+
# is not a directory.
399+
# We cannot distinguish between "directory-exists-error" and
400+
# "access-denied-error".
401+
if _os.name == 'nt' and _os.path.isdir(dir) and seq < TMP_MAX - 1:
393402
continue
394403
else:
395404
raise
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed a hang for a few seconds on Windows in the :mod:`tempfile` module when
2+
trying to create a temporary file or subdirectory in a non-writable
3+
directory.

0 commit comments

Comments
 (0)