Skip to content

Commit e3ccec3

Browse files
committed
Fix on windows, maybe?
1 parent 8b82a53 commit e3ccec3

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

src/outpack/util.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,21 @@ def assert_file_exists(path, *, workdir=None, name="File"):
8484

8585
def assert_relative_path(path: str, name: str):
8686
path = Path(path)
87-
if path.is_absolute():
87+
88+
# On Windows, this is not equivalent to path.is_absolute().
89+
# There are paths which are neither absolute nor relative, but somewhere
90+
# between the two. These are paths such as `C:foo` or `\foo`. The former has
91+
# a drive but no root, and the latter has a root but no drive. We want to
92+
# exclude both scenarios. On POSIX, drive will always be empty and this is
93+
# equivalent to calling `is_absolute()`.
94+
#
95+
# See https://github.com/python/cpython/issues/44626 for some discussion.
96+
# Unfortunately, while the issue was closed, the `is_relative` function
97+
# mentioned was never added.
98+
if path.drive or path.root:
8899
msg = f"Expected {name} path '{path}' to be a relative path"
89100
raise Exception(msg)
101+
90102
if ".." in path.parts:
91103
msg = f"Path '{path}' must not contain '..' component"
92104
raise Exception(msg)

tests/test_util.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22
import os
3+
import re
34

45
import pytest
56

@@ -69,22 +70,34 @@ def test_can_test_for_relative_path():
6970
assert_relative_path("foo.txt", "file")
7071
assert_relative_path("dir/foo.txt", "file")
7172

72-
with pytest.raises(
73-
Exception, match="Expected file path '/foo.txt' to be a relative path"
74-
):
73+
msg = "Expected file path '/foo.txt' to be a relative path"
74+
with pytest.raises(Exception, match=re.escape(msg)):
7575
assert_relative_path("/foo.txt", "file")
7676

77-
with pytest.raises(
78-
Exception, match="Path '../foo.txt' must not contain '..' component"
79-
):
77+
msg = "Path '../foo.txt' must not contain '..' component"
78+
with pytest.raises(Exception, match=re.escape(msg)):
8079
assert_relative_path("../foo.txt", "file")
8180

82-
with pytest.raises(
83-
Exception, match="Path 'aa/../foo.txt' must not contain '..' component"
84-
):
81+
msg = "Path 'aa/../foo.txt' must not contain '..' component"
82+
with pytest.raises(Exception, match=re.escape(msg)):
8583
assert_relative_path("aa/../foo.txt", "file")
8684

8785

86+
@pytest.mark.skipif(os.name != "nt", reason="Windows-specific test")
87+
def test_can_test_for_relative_path_windows():
88+
msg = "Expected file path 'C:\\aa\\foo.txt' to be a relative path"
89+
with pytest.raises(Exception, match=re.escape(msg)):
90+
assert_relative_path("C:\\aa\\foo.txt", "file")
91+
92+
msg = "Expected file path 'C:foo.txt' to be a relative path"
93+
with pytest.raises(Exception, match=re.escape(msg)):
94+
assert_relative_path("C:foo.txt", "file")
95+
96+
msg = "Expected file path '\\aa\\foo.txt' to be a relative path"
97+
with pytest.raises(Exception, match=re.escape(msg)):
98+
assert_relative_path("\\aa\\foo.txt", "file")
99+
100+
88101
def test_all_normal_files_recurses(tmp_path):
89102
helpers.touch_files(
90103
tmp_path / "foo.txt",

0 commit comments

Comments
 (0)