Skip to content

Commit 45b1295

Browse files
committed
Updated mkpath to use pathlib.Path.mkdir.
1 parent 10078fe commit 45b1295

File tree

1 file changed

+16
-44
lines changed

1 file changed

+16
-44
lines changed

distutils/dir_util.py

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
33
Utility functions for manipulating directories and directory trees."""
44

5-
import errno
5+
import itertools
66
import os
7+
import pathlib
78

89
from ._log import log
910
from .errors import DistutilsFileError, DistutilsInternalError
@@ -13,7 +14,7 @@
1314
_path_created = set()
1415

1516

16-
def mkpath(name, mode=0o777, verbose=True, dry_run=False): # noqa: C901
17+
def mkpath(name, mode=0o777, verbose=True, dry_run=False):
1718
"""Create a directory and any missing ancestor directories.
1819
1920
If the directory already exists (or if 'name' is the empty string, which
@@ -22,12 +23,6 @@ def mkpath(name, mode=0o777, verbose=True, dry_run=False): # noqa: C901
2223
(eg. some sub-path exists, but is a file rather than a directory).
2324
If 'verbose' is true, log the directory created.
2425
Return the list of directories actually created.
25-
26-
os.makedirs is not used because:
27-
28-
a) It's new to Python 1.5.2, and
29-
b) it blows up if the directory already exists (in which case it should
30-
silently succeed).
3126
"""
3227

3328
global _path_created
@@ -36,47 +31,24 @@ def mkpath(name, mode=0o777, verbose=True, dry_run=False): # noqa: C901
3631
if not isinstance(name, str):
3732
raise DistutilsInternalError(f"mkpath: 'name' must be a string (got {name!r})")
3833

39-
name = os.path.normpath(name)
40-
41-
if verbose and not os.path.isdir(name):
42-
log.info("creating %s", name)
43-
44-
created_dirs = []
45-
if os.path.isdir(name) or name == '':
46-
return created_dirs
47-
if os.path.abspath(name) in _path_created:
48-
return created_dirs
34+
name = pathlib.Path(name)
4935

50-
(head, tail) = os.path.split(name)
51-
tails = [tail] # stack of lone dirs to create
36+
if str(name.absolute()) in _path_created:
37+
return
5238

53-
while head and tail and not os.path.isdir(head):
54-
(head, tail) = os.path.split(head)
55-
tails.insert(0, tail) # push next higher dir onto stack
39+
if verbose and not name.is_dir():
40+
log.info("creating %s", name)
5641

57-
# now 'head' contains the deepest directory that already exists
58-
# (that is, the child of 'head' in 'name' is the highest directory
59-
# that does *not* exist)
60-
for d in tails:
61-
# print "head = %s, d = %s: " % (head, d),
62-
head = os.path.join(head, d)
63-
abs_head = os.path.abspath(head)
42+
ancestry = itertools.chain((name,), name.parents)
43+
missing = (path for path in ancestry if not path.is_dir())
6444

65-
if abs_head in _path_created:
66-
continue
45+
try:
46+
dry_run or name.mkdir(mode=mode, parents=True, exist_ok=True)
47+
_path_created.add(name.absolute())
48+
except OSError as exc:
49+
raise DistutilsFileError(f"could not create '{name}': {exc.args[-1]}")
6750

68-
if not dry_run:
69-
try:
70-
os.mkdir(head, mode)
71-
except OSError as exc:
72-
if not (exc.errno == errno.EEXIST and os.path.isdir(head)):
73-
raise DistutilsFileError(
74-
f"could not create '{head}': {exc.args[-1]}"
75-
)
76-
created_dirs.append(head)
77-
78-
_path_created.add(abs_head)
79-
return created_dirs
51+
return list(map(str, missing))
8052

8153

8254
def create_tree(base_dir, files, mode=0o777, verbose=True, dry_run=False):

0 commit comments

Comments
 (0)