Skip to content

Commit 77ade1f

Browse files
Fix the test for read-only tempdir. Reduce the number of attempts even more.
1 parent 5753c73 commit 77ade1f

File tree

2 files changed

+41
-31
lines changed

2 files changed

+41
-31
lines changed

Lib/tempfile.py

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

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

6265
# This variable _was_ unused for legacy reasons, see issue 10354.
6366
# But as of 3.5 we actually use it at runtime so changing it would
@@ -210,14 +213,10 @@ def _get_default_tempdir(dirlist=None):
210213
except FileExistsError:
211214
pass
212215
except PermissionError:
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):
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)):
221220
continue
222221
break # no point trying more names in this directory
223222
except OSError:
@@ -259,14 +258,10 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type):
259258
except FileExistsError:
260259
continue # try again
261260
except PermissionError:
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:
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)):
270265
continue
271266
else:
272267
raise
@@ -391,14 +386,10 @@ def mkdtemp(suffix=None, prefix=None, dir=None):
391386
except FileExistsError:
392387
continue # try again
393388
except PermissionError:
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:
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)):
402393
continue
403394
else:
404395
raise

Lib/test/test_tempfile.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,17 +330,36 @@ def _mock_candidate_names(*names):
330330
class TestBadTempdir:
331331
def test_read_only_directory(self):
332332
with _inside_empty_temp_dir():
333-
oldmode = mode = os.stat(tempfile.tempdir).st_mode
334-
mode &= ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)
335-
os.chmod(tempfile.tempdir, mode)
333+
probe = os.path.join(tempfile.tempdir, 'probe')
334+
if os.name == 'nt':
335+
cmd = ['icacls', tempfile.tempdir, '/deny', 'Everyone:(W)']
336+
stdout = None if support.verbose > 1 else subprocess.DEVNULL
337+
subprocess.run(cmd, check=True, stdout=stdout)
338+
else:
339+
oldmode = mode = os.stat(tempfile.tempdir).st_mode
340+
mode &= ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)
341+
mode = stat.S_IREAD
342+
os.chmod(tempfile.tempdir, mode)
336343
try:
337-
if os.access(tempfile.tempdir, os.W_OK):
344+
# Check that the directory is read-only.
345+
try:
346+
os.mkdir(probe)
347+
except PermissionError:
348+
pass
349+
else:
350+
os.rmdir(probe)
338351
self.skipTest("can't set the directory read-only")
352+
# gh-66305: Now it takes a split second, but previously
353+
# it took about 10 days on Windows.
339354
with self.assertRaises(PermissionError):
340355
self.make_temp()
341-
self.assertEqual(os.listdir(tempfile.tempdir), [])
342356
finally:
343-
os.chmod(tempfile.tempdir, oldmode)
357+
if os.name == 'nt':
358+
cmd = ['icacls', tempfile.tempdir, '/grant:r', 'Everyone:(M)']
359+
subprocess.run(cmd, check=True, stdout=stdout)
360+
else:
361+
os.chmod(tempfile.tempdir, oldmode)
362+
self.assertEqual(os.listdir(tempfile.tempdir), [])
344363

345364
def test_nonexisting_directory(self):
346365
with _inside_empty_temp_dir():

0 commit comments

Comments
 (0)