Skip to content

Commit 6c35f3b

Browse files
Tor ColvinTor Colvin
authored andcommitted
long path fixes
1 parent d18c75b commit 6c35f3b

File tree

4 files changed

+26
-0
lines changed

4 files changed

+26
-0
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ Tom Dalton
265265
Tom Viner
266266
Tomáš Gavenčiak
267267
Tomer Keren
268+
Tor Colvin
268269
Trevor Bekolay
269270
Tyler Goodlet
270271
Tzu-ping Chung

changelog/6755.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support deleting paths longer than 260 characters on windows created inside tmpdir.

src/_pytest/pathlib.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,23 @@ def chmod_rw(p: str) -> None:
9999
func(path)
100100
return True
101101

102+
def create_long_path(path: Path) -> Path:
103+
"""Construct a path which will work on Windows if greater
104+
than 260 characters. Resolves into a absolute path which
105+
bypasses the typical MAX_PATH limitation:
106+
https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation"""
107+
if sys.platform.startswith("win32"):
108+
path = path.resolve()
109+
# for the API
110+
if not str(path).startswith(r"\\?\"):
111+
path = Path(r"\\?\" + str(path))
112+
return path
102113

103114
def rm_rf(path: Path) -> None:
104115
"""Remove the path contents recursively, even if some elements
105116
are read-only.
106117
"""
118+
path = create_long_path(path)
107119
onerror = partial(on_rm_rf_error, start_path=path)
108120
shutil.rmtree(str(path), onerror=onerror)
109121

testing/test_pathlib.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,15 @@ def renamed_failed(*args):
8989
lock_path = get_lock_path(path)
9090
maybe_delete_a_numbered_dir(path)
9191
assert not lock_path.is_file()
92+
93+
def test_long_path_during_cleanup(tmp_path):
94+
"""Ensure that deleting long path works (particularly on Windows (#6775))."""
95+
path = tmp_path / ("a" * 200)
96+
if sys.platform == "win32":
97+
dirname = path.resolve()
98+
dirname = r"\\?\" + str(path)
99+
os.mkdir(dirname)
100+
101+
lock_path = get_lock_path(path)
102+
maybe_delete_a_numbered_dir(path)
103+
assert not lock_path.is_file()

0 commit comments

Comments
 (0)