Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/osekit/core/json_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ def _serialize_path(value: Path, root_path: Path) -> str:
return str(value)

anchor = _anchor.get()
if anchor is not None and not value.is_relative_to(anchor):
if anchor is not None and not value.resolve().is_relative_to(anchor.resolve()):
# Path is outside the project: we store it as an absolute path.
return value.as_posix()
try:
return Path(os.path.relpath(path=value, start=root_path)).as_posix()
# Return value relative to the root_path
return Path(
os.path.relpath(path=value.resolve(), start=root_path.resolve())
).as_posix()
except ValueError:
# Value is not expressible as relative to root
return value.as_posix()
Expand Down
49 changes: 42 additions & 7 deletions tests/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -1052,14 +1052,34 @@ def test_spectro_dataset_serialization(
"""


def can_symlink(tmp_path: Path) -> bool:
@pytest.fixture
def create_symlink(tmp_path: Path) -> tuple[Path, Path]:
real_root = tmp_path / "cocteau"
real_root.mkdir(parents=True, exist_ok=True)

alias_root = tmp_path / "twins"

try:
test_link = tmp_path / "link_test"
test_link.symlink_to(tmp_path)
test_link.unlink()
except OSError:
return False
return True
alias_root.symlink_to(real_root)
except (OSError, NotImplementedError) as e:
pytest.skip(f"Symlink not permitted on this system:\n{e}")

return real_root, alias_root


def test_serialize_path_with_symlink(
tmp_path: Path,
create_symlink: tuple[Path, Path],
) -> None:
real_root, alias_root = create_symlink

target = "serpentskirt"

target_path = alias_root / target

result = _serialize_path(value=target_path, root_path=real_root)

assert result == target


def test_path_anchor() -> None:
Expand Down Expand Up @@ -1136,6 +1156,21 @@ def test_serialize_path_within_anchor(tmp_path: Path) -> None:
assert _serialize_path(value=value, root_path=root_path) == expected


def test_serialize_path_within_anchor_with_symlink(
tmp_path: Path, create_symlink: tuple[Path, Path]
) -> None:
real_root, alias_root = create_symlink

target = "fun"

value = alias_root / target

with path_anchor(anchor=real_root):
# Anchor is real_root, which should also be alias_root
# So the path should be serialized as relative
assert _serialize_path(value=value, root_path=alias_root) == target


def test_serialize_path_outside_anchor(tmp_path: Path) -> None:
value = tmp_path / "fun" / "top.wav"
anchor = tmp_path / "cool"
Expand Down
Loading