Kaydet (Commit) af7b9ec5 authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka Kaydeden (comit) GitHub

bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) (#805)

when the OS gives priority to errors such as EACCES over EEXIST.
üst 8988945c
...@@ -1220,25 +1220,23 @@ class Path(PurePath): ...@@ -1220,25 +1220,23 @@ class Path(PurePath):
os.close(fd) os.close(fd)
def mkdir(self, mode=0o777, parents=False, exist_ok=False): def mkdir(self, mode=0o777, parents=False, exist_ok=False):
"""
Create a new directory at this given path.
"""
if self._closed: if self._closed:
self._raise_closed() self._raise_closed()
if not parents: try:
try: self._accessor.mkdir(self, mode)
self._accessor.mkdir(self, mode) except FileNotFoundError:
except FileExistsError: if not parents or self.parent == self:
if not exist_ok or not self.is_dir(): raise
raise self.parent.mkdir(parents=True)
else: self._accessor.mkdir(self, mode)
try: except OSError:
self._accessor.mkdir(self, mode) # Cannot rely on checking for EEXIST, since the operating system
except FileExistsError: # could give priority to other errors like EACCES or EROFS
if not exist_ok or not self.is_dir(): if not exist_ok or not self.is_dir():
raise raise
except OSError as e:
if e.errno != ENOENT or self.parent == self:
raise
self.parent.mkdir(parents=True)
self._accessor.mkdir(self, mode)
def chmod(self, mode): def chmod(self, mode):
""" """
......
...@@ -1776,6 +1776,11 @@ class _BasePathTest(object): ...@@ -1776,6 +1776,11 @@ class _BasePathTest(object):
self.assertTrue(p.exists()) self.assertTrue(p.exists())
self.assertEqual(p.stat().st_ctime, st_ctime_first) self.assertEqual(p.stat().st_ctime, st_ctime_first)
def test_mkdir_exist_ok_root(self):
# Issue #25803: A drive root could raise PermissionError on Windows
self.cls('/').resolve().mkdir(exist_ok=True)
self.cls('/').resolve().mkdir(parents=True, exist_ok=True)
@only_nt # XXX: not sure how to test this on POSIX @only_nt # XXX: not sure how to test this on POSIX
def test_mkdir_with_unknown_drive(self): def test_mkdir_with_unknown_drive(self):
for d in 'ZYXWVUTSRQPONMLKJIHGFEDCBA': for d in 'ZYXWVUTSRQPONMLKJIHGFEDCBA':
......
...@@ -287,6 +287,9 @@ Extension Modules ...@@ -287,6 +287,9 @@ Extension Modules
Library Library
------- -------
- bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True)
when the OS gives priority to errors such as EACCES over EEXIST.
- bpo-29861: Release references to tasks, their arguments and their results - bpo-29861: Release references to tasks, their arguments and their results
as soon as they are finished in multiprocessing.Pool. as soon as they are finished in multiprocessing.Pool.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment