Skip to content
7 changes: 3 additions & 4 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
- needs release notes:
- all:
- changed-files:
- any-glob-to-any-file: 'changes/*.rst'
needs release notes:
- changed-files:
- any-glob-to-any-file: 'changes/*.rst'
15 changes: 10 additions & 5 deletions .github/workflows/needs_release_notes.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: "Pull Request Labeler"

on:
- pull_request_target
pull_request

jobs:
labeler:
Expand All @@ -11,7 +11,12 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
sync-labels: true
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Run Pull Request Labeler
uses: actions/[email protected]
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
sync-labels: true
1 change: 1 addition & 0 deletions changes/2533.bigfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Wrap sync fsspec filesystems with AsyncFileSystemWrapper in xarray.to_zarr
11 changes: 11 additions & 0 deletions src/zarr/storage/_fsspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ def from_url(
opts = {"asynchronous": True, **opts}

fs, path = url_to_fs(url, **opts)
if not fs.async_impl:
try:
from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper

fs = AsyncFileSystemWrapper(fs)
except ImportError as e:
raise ImportError(
f"The filesystem for URL '{url}' is synchronous, and the required "
"AsyncFileSystemWrapper is not available. Upgrade fsspec to version "
"2024.12.0 or later to enable this functionality."
) from e

# fsspec is not consistent about removing the scheme from the path, so check and strip it here
# https://github.com/fsspec/filesystem_spec/issues/1722
Expand Down
29 changes: 29 additions & 0 deletions tests/test_store/test_fsspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import pytest
from botocore.session import Session
from packaging.version import parse as parse_version

import zarr.api.asynchronous
from zarr.abc.store import OffsetByteRequest
Expand Down Expand Up @@ -215,3 +216,31 @@ async def test_empty_nonexistent_path(self, store_kwargs) -> None:
store_kwargs["path"] += "/abc"
store = await self.store_cls.open(**store_kwargs)
assert await store.is_empty("")


@pytest.mark.skipif(
parse_version(fsspec.__version__) < parse_version("2024.12.0"),
reason="No AsyncFileSystemWrapper",
)
def test_wrap_sync_filesystem():
"""The local fs is not async so we should expect it to be wrapped automatically"""
from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper

store = FsspecStore.from_url("local://test/path")

assert isinstance(store.fs, AsyncFileSystemWrapper)
assert store.fs.async_impl


@pytest.mark.skipif(
parse_version(fsspec.__version__) < parse_version("2024.12.0"),
reason="No AsyncFileSystemWrapper",
)
def test_no_wrap_async_filesystem():
"""An async fs should not be wrapped automatically; fsspec's https filesystem is such an fs"""
from fsspec.implementations.asyn_wrapper import AsyncFileSystemWrapper

store = FsspecStore.from_url("https://test/path")

assert not isinstance(store.fs, AsyncFileSystemWrapper)
assert store.fs.async_impl
Loading