Skip to content

Commit 552d240

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

File tree

4 files changed

+43
-12
lines changed

4 files changed

+43
-12
lines changed

+stdlib/proximate_to.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
%% PROXIMATE_TO relative path to base
2-
% optional: mex
32
%
43
%%% Inputs
54
% * base {mustBeTextScalar}

+stdlib/python_version.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function v = python_version()
2+
3+
pe = pyenv();
4+
v = pe.Version;
5+
6+
end

+stdlib/relative_to.m

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
%% RELATIVE_TO relative path to base
2-
% optional: mex
32
%
43
%%% Inputs
54
% * base {mustBeTextScalar}
@@ -8,6 +7,7 @@
87
% * rel {mustBeTextScalar}
98
%
109
% Note: Java Path.relativize has an algorithm so different that we choose not to use it.
10+
% javaPathObject(base).relativize(javaPathObject(other))
1111
% https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html#relativize-java.nio.file.Path-
1212

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

test/TestRelative.m

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,41 @@ 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, {
3742
{"a/b/c/d", "a/b", fullfile("..", "..")}, ...
3843
{"a/b", "a/c", fullfile("..", "c")}, ...
3944
{"a/b", "c", fullfile("..", "..", "c")}, ...
4045
{"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.
46+
{"a/b", "a", ".."}, ...
47+
}];
48+
end
4549

4650
if ispc
47-
p = [p, ...
48-
{{"C:/a/b", "C:/", fullfile("..", "..")}, ...
51+
52+
if stdlib.has_dotnet() || stdlib.python_version() >= "3.12"
53+
p = [p, { ...
54+
{"C:/a/b", "C:/", fullfile("..", "..")}, ...
55+
{"c:/a/b", "c:/a", ".."}, ...
56+
{"c:\a/b\c/d", "c:/a\b", fullfile("..", "..")}
57+
}];
58+
end
59+
60+
p = [p, {
4961
{"C:/", "C:/a/b", fullfile("a", "b")}, ...
5062
{"c:/a/b", "c:/a/b", "."}, ...
51-
{"c:/a/b", "c:/a", ".."}, ...
52-
{"c:\a/b\c/d", "c:/a\b", fullfile("..", "..")}, ...
5363
{"C:/path", "D:/path", ""}, ...
5464
{"D:/a/b", "c", ""}}];
5565
% note: on Windows the drive letter should be uppercase!
66+
5667
else
57-
p = [p, ...
68+
69+
p = [p, ...
5870
{{"", "a", "a"}, ...
5971
{"/dev/null", "/dev/null", "."}, ...
6072
{"/a/b", "c", ""}}];

0 commit comments

Comments
 (0)