diff --git a/src/catkin_pkg/workspaces.py b/src/catkin_pkg/workspaces.py index d6f42730..6eb0e19d 100644 --- a/src/catkin_pkg/workspaces.py +++ b/src/catkin_pkg/workspaces.py @@ -92,8 +92,11 @@ def order_paths(paths_to_order, prefix_paths): def _is_equal_or_in_parents(dir_, path): - dir_ = os.path.normcase(os.path.realpath(dir_)) - path = os.path.normcase(os.path.realpath(path)) + # On Windows, when a symlink points to a path which uses 8.3/short filenames, it doesn't + # appear that `os.path.realpath` will resolve both redirections in the same invocation. + # We need to work around this non-idempotence by invoking the function twice. + dir_ = os.path.normcase(os.path.realpath(os.path.realpath(dir_))) + path = os.path.normcase(os.path.realpath(os.path.realpath(path))) return path == dir_ or path.startswith(dir_ + os.sep) diff --git a/test/test_workspaces.py b/test/test_workspaces.py index be5a76ad..4729c3de 100644 --- a/test/test_workspaces.py +++ b/test/test_workspaces.py @@ -2,6 +2,7 @@ import os import shutil +import sys import tempfile import unittest @@ -43,6 +44,9 @@ def test_order_paths(self): self.assertEqual(['foo' + os.sep + 'bim', 'bar'], order_paths(['bar', 'foo' + os.sep + 'bim'], ['foo'])) def test_order_paths_with_symlink(self): + if os.name == 'nt' and sys.version_info < (3, 8): + self.skipTest('symlinks are not resolved on Windows prior to Python 3.8') + root_dir = tempfile.mkdtemp() try: foo = os.path.join(root_dir, 'foo')