diff --git a/fsspec/implementations/dirfs.py b/fsspec/implementations/dirfs.py index 04f7479ad..6a28909da 100644 --- a/fsspec/implementations/dirfs.py +++ b/fsspec/implementations/dirfs.py @@ -64,9 +64,15 @@ def _relpath(self, path): if isinstance(path, str): if not self.path: return path - if path == self.path: + # We need to account for S3FileSystem returning paths that do not + # start with a '/' + if path == self.path or ( + self.path.startswith(self.fs.sep) and path == self.path[1:] + ): return "" prefix = self.path + self.fs.sep + if self.path.startswith(self.fs.sep) and not path.startswith(self.fs.sep): + prefix = prefix[1:] assert path.startswith(prefix) return path[len(prefix) :] return [self._relpath(_path) for _path in path] diff --git a/fsspec/implementations/tests/test_dirfs.py b/fsspec/implementations/tests/test_dirfs.py index c04ba66a7..990ab11de 100644 --- a/fsspec/implementations/tests/test_dirfs.py +++ b/fsspec/implementations/tests/test_dirfs.py @@ -82,6 +82,8 @@ def test_dirfs(fs, asyncfs): ("", "foo", "foo"), ("root", "", "root"), ("root", "foo", "root/foo"), + ("/root", "", "/root"), + ("/root", "foo", "/root/foo"), ], ) def test_path(fs, root, rel, full): @@ -90,6 +92,18 @@ def test_path(fs, root, rel, full): assert dirfs._relpath(full) == rel +@pytest.mark.parametrize( + "root, rel, full", + [ + ("/root", "foo", "root/foo"), + ("/root", "", "root"), + ], +) +def test_path_no_leading_slash(fs, root, rel, full): + dirfs = DirFileSystem(root, fs) + assert dirfs._relpath(full) == rel + + def test_sep(mocker, dirfs): sep = mocker.Mock() dirfs.fs.sep = sep