Skip to content

Commit b3007ac

Browse files
committed
relative,proximate: can use python
1 parent ca3954d commit b3007ac

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

+stdlib/relative_to.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
% * rel {mustBeTextScalar}
99
%
1010
% Note: Java Path.relativize has an algorithm so different that we choose not to use it.
11+
% javaPathObject(base).relativize(javaPathObject(other))
1112
% https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html#relativize-java.nio.file.Path-
1213

1314
function rel = relative_to(base, other)
@@ -38,6 +39,20 @@
3839
% https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getrelativepath
3940
rel = string(System.IO.Path.GetRelativePath(base, other));
4041
end
42+
elseif stdlib.has_python()
43+
try
44+
bp = py.pathlib.Path(other);
45+
if stdlib.python_version() >= "3.12"
46+
r = bp.relative_to(base, pyargs(walk_up=true));
47+
else
48+
r = bp.relative_to(base);
49+
end
50+
rel = string(py.str(r));
51+
catch e
52+
if e.identifier == "MATLAB:Python:PyException" && startsWith(e.message, 'Python Error: ValueError')
53+
rel = "";
54+
end
55+
end
4156
else
4257
error('no supported relative path method found, please install .NET or "buildtool mex"')
4358
end

test/TestRelative.m

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,39 @@ function test_proximate_to(tc, pp)
3232
{"Hello", "Hello/", "."}, ...
3333
{"a/./b", "a/b", "."}, ...
3434
{"a/b", "a/./b", "."}, ...
35-
{"./a/b", "./a/c", fullfile("..", "c")}, ...
3635
{"/", "/", "."}, ...
36+
{"a/b", "a/b", "."} ...
37+
};
38+
% NOTE: ".." in relative_to(base) is ambiguous including for python.pathlib, C++ <filesystem>, etc.
39+
40+
if stdlib.has_dotnet() || stdlib.python_version() >= "3.12"
41+
p = [p, {
42+
{"/a/b", "/a/c", fullfile("..", "c")}, ...
3743
{"a/b/c/d", "a/b", fullfile("..", "..")}, ...
3844
{"a/b", "a/c", fullfile("..", "c")}, ...
3945
{"a/b", "c", fullfile("..", "..", "c")}, ...
4046
{"c", "a/b", fullfile("..", "a", "b")}, ...
41-
{"a/b", "a/b", "."}, ...
42-
{"a/b", "a", ".."}
43-
};
44-
% NOTE: ".." in relative_to(base) is ambiguous including for python.pathlib, C++ <filesystem>, etc.
47+
{"a/b", "a", ".."}, ...
48+
}];
49+
end
4550

4651
if ispc
47-
p = [p, ...
48-
{{"C:/a/b", "C:/", fullfile("..", "..")}, ...
49-
{"C:/", "C:/a/b", fullfile("a", "b")}, ...
50-
{"c:/a/b", "c:/a/b", "."}, ...
52+
53+
if stdlib.has_dotnet() || stdlib.python_version() >= "3.12"
54+
p = [p, { ...
55+
{"C:/a/b", "C:/", fullfile("..", "..")}, ...
5156
{"c:/a/b", "c:/a", ".."}, ...
5257
{"c:\a/b\c/d", "c:/a\b", fullfile("..", "..")}, ...
58+
}];
59+
end
60+
61+
p = [p, {
62+
{"C:/", "C:/a/b", fullfile("a", "b")}, ...
63+
{"c:/a/b", "c:/a/b", "."}, ...
5364
{"C:/path", "D:/path", ""}, ...
5465
{"D:/a/b", "c", ""}}];
5566
% note: on Windows the drive letter should be uppercase!
67+
5668
else
5769
p = [p, ...
5870
{{"", "a", "a"}, ...

0 commit comments

Comments
 (0)