Skip to content

Commit f315df3

Browse files
committed
Issue #18849: Fixed a Windows-specific tempfile bug where collision with an
existing directory caused mkstemp and related APIs to fail instead of retrying. Report and fix by Vlad Shcherbina.
1 parent 43c6ef1 commit f315df3

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

‎Lib/tempfile.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,13 @@ def _mkstemp_inner(dir, pre, suf, flags):
219219
return (fd, _os.path.abspath(file))
220220
except FileExistsError:
221221
continue # try again
222+
except PermissionError:
223+
# This exception is thrown when a directory with the chosen name
224+
# already exists on windows.
225+
if _os.name == 'nt':
226+
continue
227+
else:
228+
raise
222229

223230
raise FileExistsError(_errno.EEXIST,
224231
"No usable temporary file name found")

‎Lib/test/test_tempfile.py‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,32 @@ def test_textmode(self):
372372
os.lseek(f.fd, 0, os.SEEK_SET)
373373
self.assertEqual(os.read(f.fd, 20), b"blat")
374374

375+
def test_collision_with_existing_directory(self):
376+
# _mkstemp_inner tries another name when a directory with
377+
# the chosen name already exists
378+
container_dir = tempfile.mkdtemp()
379+
try:
380+
def mock_get_candidate_names():
381+
return iter(['aaa', 'aaa', 'bbb'])
382+
with support.swap_attr(tempfile,
383+
'_get_candidate_names',
384+
mock_get_candidate_names):
385+
dir = tempfile.mkdtemp(dir=container_dir)
386+
self.assertTrue(dir.endswith('aaa'))
387+
388+
flags = tempfile._bin_openflags
389+
(fd, name) = tempfile._mkstemp_inner(container_dir,
390+
tempfile.template,
391+
'',
392+
flags)
393+
try:
394+
self.assertTrue(name.endswith('bbb'))
395+
finally:
396+
os.close(fd)
397+
os.unlink(name)
398+
finally:
399+
support.rmtree(container_dir)
400+
375401

376402
class TestGetTempPrefix(BaseTestCase):
377403
"""Test gettempprefix()."""

‎Misc/ACKS‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,7 @@ Daniel Shahaf
11211121
Ha Shao
11221122
Mark Shannon
11231123
Richard Shapiro
1124+
Vlad Shcherbina
11241125
Justin Sheehy
11251126
Charlie Shepherd
11261127
Bruce Sherwood

‎Misc/NEWS‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,10 @@ Library
280280
- Issue #18113: Fixed a refcount leak in the curses.panel module's
281281
set_userptr() method. Reported by Atsuo Ishimoto.
282282

283+
- Issue #18849: Fixed a Windows-specific tempfile bug where collision with an
284+
existing directory caused mkstemp and related APIs to fail instead of
285+
retrying. Report and fix by Vlad Shcherbina.
286+
283287
C API
284288
-----
285289

0 commit comments

Comments
 (0)