Skip to content

Commit 97cabb9

Browse files
committed
Issue #25583: Merge makedirs fix from 3.4 into 3.5
2 parents 82f9fea + a82642f commit 97cabb9

3 files changed

Lines changed: 11 additions & 3 deletions

File tree

Lib/os.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ def makedirs(name, mode=0o777, exist_ok=False):
230230
try:
231231
makedirs(head, mode, exist_ok)
232232
except FileExistsError:
233-
# be happy if someone already created the path
233+
# Defeats race condition when another thread created the path
234234
pass
235235
cdir = curdir
236236
if isinstance(tail, bytes):
@@ -239,8 +239,10 @@ def makedirs(name, mode=0o777, exist_ok=False):
239239
return
240240
try:
241241
mkdir(name, mode)
242-
except OSError as e:
243-
if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name):
242+
except OSError:
243+
# Cannot rely on checking for EEXIST, since the operating system
244+
# could give priority to other errors like EACCES or EROFS
245+
if not exist_ok or not path.isdir(name):
244246
raise
245247

246248
def removedirs(name):

Lib/test/test_os.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,9 @@ def test_exist_ok_existing_directory(self):
10401040
os.makedirs(path, mode=mode, exist_ok=True)
10411041
os.umask(old_mask)
10421042

1043+
# Issue #25583: A drive root could raise PermissionError on Windows
1044+
os.makedirs(os.path.abspath('/'), exist_ok=True)
1045+
10431046
def test_exist_ok_s_isgid_directory(self):
10441047
path = os.path.join(support.TESTFN, 'dir1')
10451048
S_ISGID = stat.S_ISGID

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ Core and Builtins
7777
Library
7878
-------
7979

80+
- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True)
81+
when the OS gives priority to errors such as EACCES over EEXIST.
82+
8083
- Issue #25593: Change semantics of EventLoop.stop() in asyncio.
8184

8285
- Issue #6973: When we know a subprocess.Popen process has died, do

0 commit comments

Comments
 (0)