Skip to content

Commit 7c192d8

Browse files
authored
make dirFS first class (#1201)
1 parent a50899e commit 7c192d8

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

fsspec/implementations/dirfs.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,35 @@
1+
from .. import filesystem
12
from ..asyn import AsyncFileSystem
23

34

45
class DirFileSystem(AsyncFileSystem):
5-
def __init__(self, path, fs, *args, **storage_options):
6+
def __init__(
7+
self,
8+
path=None,
9+
fs=None,
10+
fo=None,
11+
target_protocol=None,
12+
target_options=None,
13+
**storage_options,
14+
):
615
"""
716
Parameters
817
----------
918
path: str
1019
Path to the directory.
1120
fs: AbstractFileSystem
1221
An instantiated filesystem to wrap.
22+
target_protocol, target_options:
23+
if fs is none, construct it from these
24+
fo: str
25+
Alternate for path; do not provide both
1326
"""
14-
super().__init__(*args, **storage_options)
27+
super().__init__(**storage_options)
28+
if fs is None:
29+
fs = filesystem(protocol=target_protocol, **(target_options or {}))
30+
if (path is not None) ^ (fo is not None) is False:
31+
raise ValueError("Provide path or fo, not both")
32+
path = path or fo
1533

1634
if self.asynchronous and not fs.async_impl:
1735
raise ValueError("can't use asynchronous with non-async fs")
@@ -198,20 +216,26 @@ def info(self, path, **kwargs):
198216
return self.fs.info(self._join(path), **kwargs)
199217

200218
async def _ls(self, path, detail=True, **kwargs):
201-
ret = await self.fs._ls(self._join(path), detail=detail, **kwargs)
219+
ret = (await self.fs._ls(self._join(path), detail=detail, **kwargs)).copy()
202220
if detail:
221+
out = []
203222
for entry in ret:
223+
entry = entry.copy()
204224
entry["name"] = self._relpath(entry["name"])
205-
return ret
225+
out.append(entry)
226+
return out
206227

207228
return self._relpath(ret)
208229

209230
def ls(self, path, detail=True, **kwargs):
210-
ret = self.fs.ls(self._join(path), detail=detail, **kwargs)
231+
ret = self.fs.ls(self._join(path), detail=detail, **kwargs).copy()
211232
if detail:
233+
out = []
212234
for entry in ret:
235+
entry = entry.copy()
213236
entry["name"] = self._relpath(entry["name"])
214-
return ret
237+
out.append(entry)
238+
return out
215239

216240
return self._relpath(ret)
217241

fsspec/implementations/tests/test_dirfs.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,13 @@ def test_open(mocker, dirfs):
559559
dirfs.fs.open = mocker.Mock()
560560
assert dirfs.open("file", *ARGS, **KWARGS) == dirfs.fs.open.return_value
561561
dirfs.fs.open.assert_called_once_with(f"{PATH}/file", *ARGS, **KWARGS)
562+
563+
564+
def test_from_url(m):
565+
from fsspec.core import url_to_fs
566+
567+
m.pipe("inner/file", b"data")
568+
fs, _ = url_to_fs("dir::memory://inner")
569+
assert fs.ls("", False) == ["file"]
570+
assert fs.ls("", True)[0]["name"] == "file"
571+
assert fs.cat("file") == b"data"

fsspec/registry.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ def register_implementation(name, cls, clobber=True, errtxt=None):
185185
+ " Note: 'root' is the protocol name for xrootd storage systems,"
186186
+ " not referring to root directories",
187187
},
188+
"dir": {"class": "fsspec.implementations.dirfs.DirFileSystem"},
188189
}
189190

190191

0 commit comments

Comments
 (0)