cpython: 1134198e23bd (original) (raw)
--- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -166,6 +166,13 @@ def _get_default_tempdir(): return dir except FileExistsError: pass
except PermissionError:[](#l1.7)
# This exception is thrown when a directory with the chosen name[](#l1.8)
# already exists on windows.[](#l1.9)
if (_os.name == 'nt' and _os.path.isdir(dir) and[](#l1.10)
_os.access(dir, _os.W_OK)):[](#l1.11)
continue[](#l1.12)
raise FileNotFoundError(_errno.ENOENT, @@ -204,7 +211,8 @@ def _mkstemp_inner(dir, pre, suf, flags) except PermissionError: # This exception is thrown when a directory with the chosen name # already exists on windows.break # no point trying more names in this directory[](#l1.13) except OSError:[](#l1.14) break # no point trying more names in this directory[](#l1.15)
if _os.name == 'nt':[](#l1.21)
if (_os.name == 'nt' and _os.path.isdir(dir) and[](#l1.22)
_os.access(dir, _os.W_OK)):[](#l1.23) continue[](#l1.24) else:[](#l1.25) raise[](#l1.26)
@@ -296,6 +304,14 @@ def mkdtemp(suffix="", prefix=template, return file except FileExistsError: continue # try again
except PermissionError:[](#l1.31)
# This exception is thrown when a directory with the chosen name[](#l1.32)
# already exists on windows.[](#l1.33)
if (_os.name == 'nt' and _os.path.isdir(dir) and[](#l1.34)
_os.access(dir, _os.W_OK)):[](#l1.35)
continue[](#l1.36)
else:[](#l1.37)
raise[](#l1.38)
raise FileExistsError(_errno.EEXIST, "No usable temporary directory name found")
--- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -275,7 +275,39 @@ def _mock_candidate_names(*names): lambda: iter(names)) -class TestMkstempInner(BaseTestCase): +class TestBadTempdir: +
- def test_read_only_directory(self):
with _inside_empty_temp_dir():[](#l2.11)
oldmode = mode = os.stat(tempfile.tempdir).st_mode[](#l2.12)
mode &= ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)[](#l2.13)
os.chmod(tempfile.tempdir, mode)[](#l2.14)
try:[](#l2.15)
if os.access(tempfile.tempdir, os.W_OK):[](#l2.16)
self.skipTest("can't set the directory read-only")[](#l2.17)
with self.assertRaises(PermissionError):[](#l2.18)
self.make_temp()[](#l2.19)
self.assertEqual(os.listdir(tempfile.tempdir), [])[](#l2.20)
finally:[](#l2.21)
os.chmod(tempfile.tempdir, oldmode)[](#l2.22)
- def test_nonexisting_directory(self):
with _inside_empty_temp_dir():[](#l2.25)
tempdir = os.path.join(tempfile.tempdir, 'nonexistent')[](#l2.26)
with support.swap_attr(tempfile, 'tempdir', tempdir):[](#l2.27)
with self.assertRaises(FileNotFoundError):[](#l2.28)
self.make_temp()[](#l2.29)
- def test_non_directory(self):
with _inside_empty_temp_dir():[](#l2.32)
tempdir = os.path.join(tempfile.tempdir, 'file')[](#l2.33)
open(tempdir, 'wb').close()[](#l2.34)
with support.swap_attr(tempfile, 'tempdir', tempdir):[](#l2.35)
with self.assertRaises((NotADirectoryError, FileNotFoundError)):[](#l2.36)
self.make_temp()[](#l2.37)
+ + +class TestMkstempInner(TestBadTempdir, BaseTestCase): """Test the internal function _mkstemp_inner.""" class mkstemped: @@ -390,7 +422,7 @@ class TestMkstempInner(BaseTestCase): os.lseek(f.fd, 0, os.SEEK_SET) self.assertEqual(os.read(f.fd, 20), b"blat")
@@ -401,11 +433,11 @@ class TestMkstempInner(BaseTestCase): # the chosen name already exists with _inside_empty_temp_dir(), [](#l2.55) _mock_candidate_names('aaa', 'aaa', 'bbb'):
(fd1, name1) = self.default_mkstemp_inner()[](#l2.57)
(fd1, name1) = self.make_temp()[](#l2.58) os.close(fd1)[](#l2.59) self.assertTrue(name1.endswith('aaa'))[](#l2.60)
(fd2, name2) = self.default_mkstemp_inner()[](#l2.62)
(fd2, name2) = self.make_temp()[](#l2.63) os.close(fd2)[](#l2.64) self.assertTrue(name2.endswith('bbb'))[](#l2.65)
@@ -417,7 +449,7 @@ class TestMkstempInner(BaseTestCase): dir = tempfile.mkdtemp() self.assertTrue(dir.endswith('aaa'))
(fd, name) = self.default_mkstemp_inner()[](#l2.71)
(fd, name) = self.make_temp()[](#l2.72) os.close(fd)[](#l2.73) self.assertTrue(name.endswith('bbb'))[](#l2.74)
@@ -529,9 +561,12 @@ class TestMkstemp(BaseTestCase): os.rmdir(dir) -class TestMkdtemp(BaseTestCase): +class TestMkdtemp(TestBadTempdir, BaseTestCase): """Test mkdtemp()."""
+ def do_create(self, dir=None, pre="", suf=""): if dir is None: dir = tempfile.gettempdir()
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -52,6 +52,11 @@ Core and Builtins Library ------- +- Issue #22107: tempfile.gettempdir() and tempfile.mkdtemp() now try again