Skip to content

Commit 1f79847

Browse files
authored
Merge pull request #4737 from pypa/feature/distutils-251797602
Merge bugfixes from distutils
2 parents 566e47d + 42e0625 commit 1f79847

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

newsfragments/+f0b61194.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Merge with pypa/distutils@251797602, including fix for dirutil.mkpath handling in pypa/distutils#304.

setuptools/_distutils/dir_util.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ def wrap(self, func):
3232
def wrapper(path, *args, **kwargs):
3333
if path.absolute() in self:
3434
return
35+
result = func(path, *args, **kwargs)
3536
self.add(path.absolute())
36-
return func(path, *args, **kwargs)
37+
return result
3738

3839
return wrapper
3940

@@ -44,29 +45,23 @@ def wrapper(path, *args, **kwargs):
4445

4546
@functools.singledispatch
4647
@wrapper
47-
def mkpath(name: pathlib.Path, mode=0o777, verbose=True, dry_run=False):
48+
def mkpath(name: pathlib.Path, mode=0o777, verbose=True, dry_run=False) -> None:
4849
"""Create a directory and any missing ancestor directories.
4950
5051
If the directory already exists (or if 'name' is the empty string, which
5152
means the current directory, which of course exists), then do nothing.
5253
Raise DistutilsFileError if unable to create some directory along the way
5354
(eg. some sub-path exists, but is a file rather than a directory).
5455
If 'verbose' is true, log the directory created.
55-
Return the list of directories actually created.
5656
"""
5757
if verbose and not name.is_dir():
5858
log.info("creating %s", name)
5959

60-
ancestry = itertools.chain((name,), name.parents)
61-
missing = (path for path in ancestry if not path.is_dir())
62-
6360
try:
6461
dry_run or name.mkdir(mode=mode, parents=True, exist_ok=True)
6562
except OSError as exc:
6663
raise DistutilsFileError(f"could not create '{name}': {exc.args[-1]}")
6764

68-
return list(map(str, missing))
69-
7065

7166
@mkpath.register
7267
def _(name: str, *args, **kwargs):

setuptools/_distutils/tests/test_dir_util.py

+22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for distutils.dir_util."""
22

33
import os
4+
import pathlib
45
import stat
56
import unittest.mock as mock
67
from distutils import dir_util, errors
@@ -110,3 +111,24 @@ def test_copy_tree_exception_in_listdir(self):
110111
):
111112
src = self.tempdirs[-1]
112113
dir_util.copy_tree(src, None)
114+
115+
def test_mkpath_exception_uncached(self, monkeypatch, tmp_path):
116+
"""
117+
Caching should not remember failed attempts.
118+
119+
pypa/distutils#304
120+
"""
121+
122+
class FailPath(pathlib.Path):
123+
def mkdir(self, *args, **kwargs):
124+
raise OSError("Failed to create directory")
125+
126+
target = tmp_path / 'foodir'
127+
128+
with pytest.raises(errors.DistutilsFileError):
129+
mkpath(FailPath(target))
130+
131+
assert not target.exists()
132+
133+
mkpath(target)
134+
assert target.exists()

0 commit comments

Comments
 (0)