diff --git a/fsspec/implementations/dirfs.py b/fsspec/implementations/dirfs.py index 04f7479ad..b8119197d 100644 --- a/fsspec/implementations/dirfs.py +++ b/fsspec/implementations/dirfs.py @@ -66,7 +66,12 @@ def _relpath(self, path): return path if path == self.path: return "" + # S3FileSystem returns paths that do not start with a '/', so we + # need to remove the leading '/' from self.path if there is one there + # but not on the incoming path prefix = self.path + self.fs.sep + if not path.startswith(self.fs.sep) and self.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..b4a0164c6 100644 --- a/fsspec/implementations/tests/test_dirfs.py +++ b/fsspec/implementations/tests/test_dirfs.py @@ -90,6 +90,18 @@ def test_path(fs, root, rel, full): assert dirfs._relpath(full) == rel +@pytest.mark.parametrize( + "root, rel, full", + [ + ("/root", "foo", "root/foo"), + ("/root", "foo", "/root/foo"), + ], +) +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