diff --git a/src/datajoint/storage.py b/src/datajoint/storage.py index 39a21ce46..4069212fb 100644 --- a/src/datajoint/storage.py +++ b/src/datajoint/storage.py @@ -418,7 +418,7 @@ def _full_path(self, path: str | PurePosixPath) -> str: elif self.protocol == "file": location = self.spec.get("location", "") if location: - return str(Path(location) / path) + return (Path(location) / path).as_posix() return path else: return self._require_adapter().full_path(self.spec, path) diff --git a/tests/unit/test_storage_adapter.py b/tests/unit/test_storage_adapter.py index a8ef4a99a..38a9d31f7 100644 --- a/tests/unit/test_storage_adapter.py +++ b/tests/unit/test_storage_adapter.py @@ -1,14 +1,17 @@ """Tests for the StorageAdapter plugin system.""" +from pathlib import PureWindowsPath + import pytest import datajoint as dj +from datajoint import storage from datajoint.errors import DataJointError from datajoint.storage import StorageBackend from datajoint.storage_adapter import ( + _COMMON_STORE_KEYS, StorageAdapter, _adapter_registry, - _COMMON_STORE_KEYS, get_storage_adapter, ) @@ -193,6 +196,17 @@ def test_unsupported_protocol_get_url_raises(self): with pytest.raises(DataJointError, match="Unsupported storage protocol"): backend.get_url("schema/file.dat") + def test_file_protocol_full_path_uses_forward_slashes(self, monkeypatch): + """`_full_path` must return forward slashes to match fsspec's walk() + output (gc.py relies on this for string-prefix stripping).""" + # monkeypatch to PureWindowsPath so that the test is platform-independent + monkeypatch.setattr(storage, "Path", PureWindowsPath) + backend = StorageBackend.__new__(StorageBackend) + backend.spec = {"protocol": "file", "location": "data\\blobs"} + backend.protocol = "file" + result = backend._full_path("schema/ab/cd/hash123") + assert result == "data/blobs/schema/ab/cd/hash123" + class TestGetStoreSpecPluginDelegation: """Tests for plugin protocol handling in Config.get_store_spec()."""