Skip to content

Commit 3c173f9

Browse files
committed
Handle fsspec.FSMap as zarr's store (use FSStore)
1 parent 1af77b6 commit 3c173f9

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

zarr/_storage/v3.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,16 @@ def _normalize_store_arg_v3(store: Any, storage_options=None, mode="r") -> BaseS
567567
return store
568568
if isinstance(store, os.PathLike):
569569
store = os.fspath(store)
570+
if FSStore._fsspec_installed():
571+
import fsspec
572+
if isinstance(store, fsspec.FSMap):
573+
return FSStoreV3(store.root,
574+
fs=store.fs,
575+
mode=mode,
576+
check=store.check,
577+
create=store.create,
578+
missing_exceptions=store.missing_exceptions,
579+
**(storage_options or {}))
570580
if isinstance(store, str):
571581
if "://" in store or "::" in store:
572582
store = FSStoreV3(store, mode=mode, **(storage_options or {}))

zarr/storage.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ def _normalize_store_arg_v2(store: Any, storage_options=None, mode="r") -> BaseS
139139
return store
140140
if isinstance(store, os.PathLike):
141141
store = os.fspath(store)
142+
if FSStore._fsspec_installed():
143+
import fsspec
144+
if isinstance(store, fsspec.FSMap):
145+
return FSStore(store.root,
146+
fs=store.fs,
147+
mode=mode,
148+
check=store.check,
149+
create=store.create,
150+
missing_exceptions=store.missing_exceptions,
151+
**(storage_options or {}))
142152
if isinstance(store, str):
143153
if "://" in store or "::" in store:
144154
return FSStore(store, mode=mode, **(storage_options or {}))
@@ -1308,6 +1318,8 @@ def __init__(self, url, normalize_keys=False, key_separator=None,
13081318
create=False,
13091319
missing_exceptions=None,
13101320
**storage_options):
1321+
if not self._fsspec_installed(): # pragma: no cover
1322+
raise ImportError("`fsspec` is required to use zarr's FSStore")
13111323
import fsspec
13121324

13131325
mapper_options = {"check": check, "create": create}
@@ -1479,6 +1491,13 @@ def clear(self):
14791491
raise ReadOnlyError()
14801492
self.map.clear()
14811493

1494+
@classmethod
1495+
def _fsspec_installed(cls):
1496+
"""Returns true if fsspec is installed"""
1497+
import importlib.util
1498+
1499+
return importlib.util.find_spec("fsspec") is not None
1500+
14821501

14831502
class TempStore(DirectoryStore):
14841503
"""Directory store using a temporary directory for storage.

zarr/tests/test_storage.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,10 +2556,15 @@ def test_normalize_store_arg(tmpdir):
25562556
assert isinstance(store, Class)
25572557

25582558
if have_fsspec:
2559+
import fsspec
2560+
25592561
path = tempfile.mkdtemp()
25602562
store = normalize_store_arg("file://" + path, zarr_version=2, mode='w')
25612563
assert isinstance(store, FSStore)
25622564

2565+
store = normalize_store_arg(fsspec.get_mapper("file://" + path))
2566+
assert isinstance(store, FSStore)
2567+
25632568

25642569
def test_meta_prefix_6853():
25652570

zarr/tests/test_storage_v3.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,16 @@ def test_normalize_store_arg_v3(tmpdir):
467467
normalize_store_arg(str(fn), zarr_version=3, mode='w', storage_options={"some": "kwargs"})
468468

469469
if have_fsspec:
470+
import fsspec
471+
470472
path = tempfile.mkdtemp()
471473
store = normalize_store_arg("file://" + path, zarr_version=3, mode='w')
472474
assert isinstance(store, FSStoreV3)
473475
assert 'zarr.json' in store
474476

477+
store = normalize_store_arg(fsspec.get_mapper("file://" + path), zarr_version=3)
478+
assert isinstance(store, FSStoreV3)
479+
475480
fn = tmpdir.join('store.n5')
476481
with pytest.raises(NotImplementedError):
477482
normalize_store_arg(str(fn), zarr_version=3, mode='w')

0 commit comments

Comments
 (0)