diff --git a/changes/3372.misc.rst b/changes/3372.misc.rst new file mode 100644 index 0000000000..fe7da0d265 --- /dev/null +++ b/changes/3372.misc.rst @@ -0,0 +1,2 @@ +Make certain imports in ``zarr.abc.store`` local to method definitions. This minimizes the risk of +circular imports when adding new classes to ``zarr.abc.store``. \ No newline at end of file diff --git a/src/zarr/abc/store.py b/src/zarr/abc/store.py index 1fbdb3146c..53e981c3bd 100644 --- a/src/zarr/abc/store.py +++ b/src/zarr/abc/store.py @@ -6,10 +6,6 @@ from itertools import starmap from typing import TYPE_CHECKING, Protocol, runtime_checkable -from zarr.core.buffer.core import default_buffer_prototype -from zarr.core.common import concurrent_map -from zarr.core.config import config - if TYPE_CHECKING: from collections.abc import AsyncGenerator, AsyncIterator, Iterable from types import TracebackType @@ -438,6 +434,9 @@ async def getsize(self, key: str) -> int: # Note to implementers: this default implementation is very inefficient since # it requires reading the entire object. Many systems will have ways to get the # size of an object without reading it. + # avoid circular import + from zarr.core.buffer.core import default_buffer_prototype + value = await self.get(key, prototype=default_buffer_prototype()) if value is None: raise FileNotFoundError(key) @@ -476,6 +475,11 @@ async def getsize_prefix(self, prefix: str) -> int: # on to getting sizes. Ideally we would overlap those two, which should # improve tail latency and might reduce memory pressure (since not all keys # would be in memory at once). + + # avoid circular import + from zarr.core.common import concurrent_map + from zarr.core.config import config + keys = [(x,) async for x in self.list_prefix(prefix)] limit = config.get("async.concurrency") sizes = await concurrent_map(keys, self.getsize, limit=limit)