From 8d51dd33a58607e7bec67811431ca0ccdaa07768 Mon Sep 17 00:00:00 2001 From: Max Jones <14077947+maxrjones@users.noreply.github.com> Date: Thu, 3 Jul 2025 06:44:47 -0400 Subject: [PATCH 1/2] Remove breaking check about `auto_mkdir` for FSSpecStore (#3193) * Remove breaking check from _make_async * Update expected error * Change import structure to protect against AttributeError * changelog * add test to ensure that we can create a read-only copy of the store with auto_mkdir=False * only test if the async wrapper is available --------- Co-authored-by: Davis Bennett (cherry picked from commit 5a24487f09d499c91ce25f24af910c2ede055b5a) --- changes/3193.bugfix.rst | 2 ++ src/zarr/storage/_fsspec.py | 8 ++------ tests/test_store/test_fsspec.py | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 changes/3193.bugfix.rst diff --git a/changes/3193.bugfix.rst b/changes/3193.bugfix.rst new file mode 100644 index 0000000000..a6e387c10c --- /dev/null +++ b/changes/3193.bugfix.rst @@ -0,0 +1,2 @@ +Removed an unnecessary check from ``_fsspec._make_async`` that would raise an exception when +creating a read-only store backed by a local file system with ``auto_mkdir`` set to ``False``. \ No newline at end of file diff --git a/src/zarr/storage/_fsspec.py b/src/zarr/storage/_fsspec.py index 4f6929456e..a1b05a7630 100644 --- a/src/zarr/storage/_fsspec.py +++ b/src/zarr/storage/_fsspec.py @@ -56,19 +56,15 @@ def _make_async(fs: AbstractFileSystem) -> AsyncFileSystem: fs_dict["asynchronous"] = True return fsspec.AbstractFileSystem.from_json(json.dumps(fs_dict)) - # Wrap sync filesystems with the async wrapper - if type(fs) is fsspec.implementations.local.LocalFileSystem and not fs.auto_mkdir: - raise ValueError( - f"LocalFilesystem {fs} was created with auto_mkdir=False but Zarr requires the filesystem to automatically create directories" - ) if fsspec_version < parse_version("2024.12.0"): raise ImportError( f"The filesystem '{fs}' is synchronous, and the required " "AsyncFileSystemWrapper is not available. Upgrade fsspec to version " "2024.12.0 or later to enable this functionality." ) + from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper - return fsspec.implementations.asyn_wrapper.AsyncFileSystemWrapper(fs, asynchronous=True) + return AsyncFileSystemWrapper(fs, asynchronous=True) class FsspecStore(Store): diff --git a/tests/test_store/test_fsspec.py b/tests/test_store/test_fsspec.py index 1a989525e3..026b25f8fc 100644 --- a/tests/test_store/test_fsspec.py +++ b/tests/test_store/test_fsspec.py @@ -365,7 +365,7 @@ def test_open_fsmap_file_raises(tmp_path: pathlib.Path) -> None: fsspec = pytest.importorskip("fsspec.implementations.local") fs = fsspec.LocalFileSystem(auto_mkdir=False) mapper = fs.get_mapper(tmp_path) - with pytest.raises(ValueError, match="LocalFilesystem .*"): + with pytest.raises(FileNotFoundError, match="No such file or directory: .*"): array_roundtrip(mapper) @@ -426,3 +426,17 @@ async def test_delete_dir_wrapped_filesystem(tmp_path: Path) -> None: assert await store.exists("foo-bar/zarr.json") assert not await store.exists("foo/zarr.json") assert not await store.exists("foo/c/0") + + +@pytest.mark.skipif( + parse_version(fsspec.__version__) < parse_version("2024.12.0"), + reason="No AsyncFileSystemWrapper", +) +async def test_with_read_only_auto_mkdir(tmp_path: Path) -> None: + """ + Test that creating a read-only copy of a store backed by the local file system does not error + if auto_mkdir is False. + """ + + store_w = FsspecStore.from_url(f"file://{tmp_path}", storage_options={"auto_mkdir": False}) + _ = store_w.with_read_only() From c7218a36f49c8550c06e2aecada153154734f837 Mon Sep 17 00:00:00 2001 From: Altay Sansal Date: Thu, 3 Jul 2025 04:06:24 -0500 Subject: [PATCH 2/2] Add missing import for AsyncFileSystemWrapper for `_make_async` in `_fsspec.py` (#3195) * Add missing import for AsyncFileSystemWrapper in `_fsspec.py` * Add missing changelog entry for AsyncFileSystemWrapper import fix * Move AsyncFileSystemWrapper import past the version check in `_fsspec.py` * Add newline after AsyncFileSystemWrapper import in `_fsspec.py` * Simplify import statement for AsyncFileSystemWrapper in `_fsspec.py` --------- Co-authored-by: Altay Sansal (cherry picked from commit 97aa42f551c2e970f66ee629cb31ce426e659b7b) --- changes/3195.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/3195.bugfix.rst diff --git a/changes/3195.bugfix.rst b/changes/3195.bugfix.rst new file mode 100644 index 0000000000..44a7ce9105 --- /dev/null +++ b/changes/3195.bugfix.rst @@ -0,0 +1 @@ +Add missing import for AsyncFileSystemWrapper for _make_async in _fsspec.py \ No newline at end of file