diff --git a/examples/custom_dtype.py b/examples/custom_dtype.py index a98f3414f6..b9a47b8bc7 100644 --- a/examples/custom_dtype.py +++ b/examples/custom_dtype.py @@ -22,7 +22,6 @@ import pytest import zarr -from zarr.core.common import JSON, ZarrFormat from zarr.core.dtype import ZDType, data_type_registry from zarr.core.dtype.common import ( DataTypeValidationError, @@ -30,6 +29,8 @@ DTypeJSON, check_dtype_spec_v2, ) +from zarr.core.types import JSON +from zarr.types import ZarrFormat # This is the int2 array data type int2_dtype_cls = type(np.dtype("int2")) diff --git a/src/zarr/abc/codec.py b/src/zarr/abc/codec.py index f8a5447a70..51df240a73 100644 --- a/src/zarr/abc/codec.py +++ b/src/zarr/abc/codec.py @@ -5,7 +5,7 @@ from zarr.abc.metadata import Metadata from zarr.core.buffer import Buffer, NDBuffer -from zarr.core.common import ChunkCoords, concurrent_map +from zarr.core.common import concurrent_map from zarr.core.config import config if TYPE_CHECKING: @@ -18,6 +18,7 @@ from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType from zarr.core.indexing import SelectorTuple from zarr.core.metadata import ArrayMetadata + from zarr.core.types import ChunkCoords __all__ = [ "ArrayArrayCodec", diff --git a/src/zarr/abc/metadata.py b/src/zarr/abc/metadata.py index a56f986645..92cc9a63eb 100644 --- a/src/zarr/abc/metadata.py +++ b/src/zarr/abc/metadata.py @@ -6,7 +6,7 @@ if TYPE_CHECKING: from typing import Self - from zarr.core.common import JSON + from zarr.core.types import JSON from dataclasses import dataclass, fields diff --git a/src/zarr/abc/store.py b/src/zarr/abc/store.py index 1fbdb3146c..7fbd9cdce2 100644 --- a/src/zarr/abc/store.py +++ b/src/zarr/abc/store.py @@ -16,7 +16,7 @@ from typing import Any, Self, TypeAlias from zarr.core.buffer import Buffer, BufferPrototype - from zarr.core.common import BytesLike + from zarr.core.types import BytesLike __all__ = ["ByteGetter", "ByteSetter", "Store", "set_or_delete"] diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py index 78b68caf73..20d9da7ed2 100644 --- a/src/zarr/api/asynchronous.py +++ b/src/zarr/api/asynchronous.py @@ -22,12 +22,6 @@ from zarr.core.array_spec import ArrayConfigLike, parse_array_config from zarr.core.buffer import NDArrayLike from zarr.core.common import ( - JSON, - AccessModeLiteral, - ChunkCoords, - DimensionNames, - MemoryOrder, - ZarrFormat, _default_zarr_format, _warn_write_empty_chunks_kwarg, ) @@ -57,7 +51,15 @@ from zarr.abc.codec import Codec from zarr.core.buffer import NDArrayLikeOrScalar from zarr.core.chunk_key_encodings import ChunkKeyEncoding + from zarr.core.types import ( + JSON, + AccessModeLiteral, + ChunkCoords, + DimensionNames, + MemoryOrder, + ) from zarr.storage import StoreLike + from zarr.types import ZarrFormat # TODO: this type could use some more thought ArrayLike = AsyncArray[ArrayV2Metadata] | AsyncArray[ArrayV3Metadata] | Array | npt.NDArray[Any] diff --git a/src/zarr/api/synchronous.py b/src/zarr/api/synchronous.py index ed1ae2cf2a..5f27c8c9d3 100644 --- a/src/zarr/api/synchronous.py +++ b/src/zarr/api/synchronous.py @@ -30,17 +30,17 @@ from zarr.core.array_spec import ArrayConfigLike from zarr.core.buffer import NDArrayLike, NDArrayLikeOrScalar from zarr.core.chunk_key_encodings import ChunkKeyEncoding, ChunkKeyEncodingLike - from zarr.core.common import ( + from zarr.core.dtype import ZDTypeLike + from zarr.core.types import ( JSON, AccessModeLiteral, ChunkCoords, DimensionNames, MemoryOrder, ShapeLike, - ZarrFormat, ) - from zarr.core.dtype import ZDTypeLike from zarr.storage import StoreLike + from zarr.types import ZarrFormat __all__ = [ "array", diff --git a/src/zarr/codecs/blosc.py b/src/zarr/codecs/blosc.py index f89f127852..47580db0d6 100644 --- a/src/zarr/codecs/blosc.py +++ b/src/zarr/codecs/blosc.py @@ -12,7 +12,7 @@ from zarr.abc.codec import BytesBytesCodec from zarr.core.buffer.cpu import as_numpy_array_wrapper -from zarr.core.common import JSON, parse_enum, parse_named_configuration +from zarr.core.common import parse_enum, parse_named_configuration from zarr.core.dtype.common import HasItemSize from zarr.registry import register_codec @@ -21,6 +21,7 @@ from zarr.core.array_spec import ArraySpec from zarr.core.buffer import Buffer + from zarr.core.types import JSON class BloscShuffle(Enum): diff --git a/src/zarr/codecs/bytes.py b/src/zarr/codecs/bytes.py index 7576119c82..f3b99aadde 100644 --- a/src/zarr/codecs/bytes.py +++ b/src/zarr/codecs/bytes.py @@ -9,7 +9,7 @@ from zarr.abc.codec import ArrayBytesCodec from zarr.core.buffer import Buffer, NDArrayLike, NDBuffer -from zarr.core.common import JSON, parse_enum, parse_named_configuration +from zarr.core.common import parse_enum, parse_named_configuration from zarr.core.dtype.common import HasEndianness from zarr.registry import register_codec @@ -17,6 +17,7 @@ from typing import Self from zarr.core.array_spec import ArraySpec + from zarr.core.types import JSON class Endian(Enum): diff --git a/src/zarr/codecs/crc32c_.py b/src/zarr/codecs/crc32c_.py index c2e30f689a..16d94846ca 100644 --- a/src/zarr/codecs/crc32c_.py +++ b/src/zarr/codecs/crc32c_.py @@ -8,7 +8,7 @@ from crc32c import crc32c from zarr.abc.codec import BytesBytesCodec -from zarr.core.common import JSON, parse_named_configuration +from zarr.core.common import parse_named_configuration from zarr.registry import register_codec if TYPE_CHECKING: @@ -16,6 +16,7 @@ from zarr.core.array_spec import ArraySpec from zarr.core.buffer import Buffer + from zarr.core.types import JSON @dataclass(frozen=True) diff --git a/src/zarr/codecs/gzip.py b/src/zarr/codecs/gzip.py index 9e6515a4d1..a8193a5ac9 100644 --- a/src/zarr/codecs/gzip.py +++ b/src/zarr/codecs/gzip.py @@ -8,7 +8,7 @@ from zarr.abc.codec import BytesBytesCodec from zarr.core.buffer.cpu import as_numpy_array_wrapper -from zarr.core.common import JSON, parse_named_configuration +from zarr.core.common import parse_named_configuration from zarr.registry import register_codec if TYPE_CHECKING: @@ -16,6 +16,7 @@ from zarr.core.array_spec import ArraySpec from zarr.core.buffer import Buffer + from zarr.core.types import JSON def parse_gzip_level(data: JSON) -> int: diff --git a/src/zarr/codecs/sharding.py b/src/zarr/codecs/sharding.py index 888d258649..6b6e4e4156 100644 --- a/src/zarr/codecs/sharding.py +++ b/src/zarr/codecs/sharding.py @@ -36,8 +36,6 @@ ) from zarr.core.chunk_grids import ChunkGrid, RegularChunkGrid from zarr.core.common import ( - ChunkCoords, - ChunkCoordsLike, parse_enum, parse_named_configuration, parse_shapelike, @@ -52,14 +50,15 @@ morton_order_iter, ) from zarr.core.metadata.v3 import parse_codecs +from zarr.core.types import ChunkCoords, ChunkCoordsLike from zarr.registry import get_ndbuffer_class, get_pipeline_class, register_codec if TYPE_CHECKING: from collections.abc import Awaitable, Callable, Iterator from typing import Self - from zarr.core.common import JSON from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType + from zarr.core.types import JSON MAX_UINT_64 = 2**64 - 1 ShardMapping = Mapping[ChunkCoords, Buffer] diff --git a/src/zarr/codecs/transpose.py b/src/zarr/codecs/transpose.py index d6310d38a4..25ea8ec412 100644 --- a/src/zarr/codecs/transpose.py +++ b/src/zarr/codecs/transpose.py @@ -8,7 +8,7 @@ from zarr.abc.codec import ArrayArrayCodec from zarr.core.array_spec import ArraySpec -from zarr.core.common import JSON, ChunkCoordsLike, parse_named_configuration +from zarr.core.common import parse_named_configuration from zarr.registry import register_codec if TYPE_CHECKING: @@ -17,6 +17,7 @@ from zarr.core.buffer import NDBuffer from zarr.core.chunk_grids import ChunkGrid from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType + from zarr.core.types import JSON, ChunkCoordsLike def parse_transpose_order(data: JSON | Iterable[int]) -> tuple[int, ...]: diff --git a/src/zarr/codecs/vlen_utf8.py b/src/zarr/codecs/vlen_utf8.py index 28c64be1c0..69768ab178 100644 --- a/src/zarr/codecs/vlen_utf8.py +++ b/src/zarr/codecs/vlen_utf8.py @@ -8,13 +8,14 @@ from zarr.abc.codec import ArrayBytesCodec from zarr.core.buffer import Buffer, NDBuffer -from zarr.core.common import JSON, parse_named_configuration +from zarr.core.common import parse_named_configuration from zarr.registry import register_codec if TYPE_CHECKING: from typing import Self from zarr.core.array_spec import ArraySpec + from zarr.core.types import JSON # can use a global because there are no parameters diff --git a/src/zarr/codecs/zstd.py b/src/zarr/codecs/zstd.py index ead41e7b5f..98a4aac204 100644 --- a/src/zarr/codecs/zstd.py +++ b/src/zarr/codecs/zstd.py @@ -11,7 +11,7 @@ from zarr.abc.codec import BytesBytesCodec from zarr.core.buffer.cpu import as_numpy_array_wrapper -from zarr.core.common import JSON, parse_named_configuration +from zarr.core.common import parse_named_configuration from zarr.registry import register_codec if TYPE_CHECKING: @@ -19,6 +19,7 @@ from zarr.core.array_spec import ArraySpec from zarr.core.buffer import Buffer + from zarr.core.types import JSON def parse_zstd_level(data: JSON) -> int: diff --git a/src/zarr/core/_info.py b/src/zarr/core/_info.py index a5b14d573a..6b1adcfacd 100644 --- a/src/zarr/core/_info.py +++ b/src/zarr/core/_info.py @@ -8,8 +8,8 @@ import numcodecs.abc from zarr.abc.codec import ArrayArrayCodec, ArrayBytesCodec, BytesBytesCodec - from zarr.core.common import ZarrFormat from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType + from zarr.types import ZarrFormat @dataclasses.dataclass(kw_only=True) diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py index 311a0eb986..083549d0bc 100644 --- a/src/zarr/core/array.py +++ b/src/zarr/core/array.py @@ -50,15 +50,6 @@ V2ChunkKeyEncoding, ) from zarr.core.common import ( - JSON, - ZARR_JSON, - ZARRAY_JSON, - ZATTRS_JSON, - ChunkCoords, - DimensionNames, - MemoryOrder, - ShapeLike, - ZarrFormat, _default_zarr_format, _warn_order_kwarg, ceildiv, @@ -106,9 +97,7 @@ ArrayMetadata, ArrayMetadataDict, ArrayV2Metadata, - ArrayV2MetadataDict, ArrayV3Metadata, - ArrayV3MetadataDict, T_ArrayMetadata, ) from zarr.core.metadata.v2 import ( @@ -119,6 +108,18 @@ ) from zarr.core.metadata.v3 import parse_node_type_array from zarr.core.sync import sync +from zarr.core.types import ( + JSON, + ZARR_JSON, + ZARRAY_JSON, + ZATTRS_JSON, + ArrayMetadataJSON_V2, + ArrayMetadataJSON_V3, + ChunkCoords, + DimensionNames, + MemoryOrder, + ShapeLike, +) from zarr.errors import MetadataValidationError, ZarrDeprecationWarning, ZarrUserWarning from zarr.registry import ( _parse_array_array_codec, @@ -140,6 +141,7 @@ from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar from zarr.core.group import AsyncGroup from zarr.storage import StoreLike + from zarr.types import ZarrFormat # Array and AsyncArray are defined in the base ``zarr`` namespace @@ -294,7 +296,7 @@ class AsyncArray(Generic[T_ArrayMetadata]): @overload def __init__( self: AsyncArray[ArrayV2Metadata], - metadata: ArrayV2Metadata | ArrayV2MetadataDict, + metadata: ArrayV2Metadata | ArrayMetadataJSON_V2, store_path: StorePath, config: ArrayConfigLike | None = None, ) -> None: ... @@ -302,7 +304,7 @@ def __init__( @overload def __init__( self: AsyncArray[ArrayV3Metadata], - metadata: ArrayV3Metadata | ArrayV3MetadataDict, + metadata: ArrayV3Metadata | ArrayMetadataJSON_V3, store_path: StorePath, config: ArrayConfigLike | None = None, ) -> None: ... @@ -962,7 +964,7 @@ async def open( store_path = await make_store_path(store) metadata_dict = await get_array_metadata(store_path, zarr_format=zarr_format) # TODO: remove this cast when we have better type hints - _metadata_dict = cast("ArrayV3MetadataDict", metadata_dict) + _metadata_dict = cast("ArrayMetadataJSON_V3", metadata_dict) return cls(store_path=store_path, metadata=_metadata_dict) @property diff --git a/src/zarr/core/array_spec.py b/src/zarr/core/array_spec.py index 279bf6edf0..ad11d71e7f 100644 --- a/src/zarr/core/array_spec.py +++ b/src/zarr/core/array_spec.py @@ -4,7 +4,6 @@ from typing import TYPE_CHECKING, Any, Literal, Self, TypedDict, cast from zarr.core.common import ( - MemoryOrder, parse_bool, parse_fill_value, parse_order, @@ -16,8 +15,8 @@ from typing import NotRequired from zarr.core.buffer import BufferPrototype - from zarr.core.common import ChunkCoords from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType + from zarr.core.types import ChunkCoords, MemoryOrder class ArrayConfigParams(TypedDict): diff --git a/src/zarr/core/attributes.py b/src/zarr/core/attributes.py index e699c4f66d..0be81b5aba 100644 --- a/src/zarr/core/attributes.py +++ b/src/zarr/core/attributes.py @@ -3,7 +3,7 @@ from collections.abc import MutableMapping from typing import TYPE_CHECKING -from zarr.core.common import JSON +from zarr.core.types import JSON if TYPE_CHECKING: from collections.abc import Iterator diff --git a/src/zarr/core/buffer/core.py b/src/zarr/core/buffer/core.py index 07bdb8c26e..88d4437728 100644 --- a/src/zarr/core/buffer/core.py +++ b/src/zarr/core/buffer/core.py @@ -21,7 +21,7 @@ from typing import Self from zarr.codecs.bytes import Endian - from zarr.core.common import BytesLike, ChunkCoords + from zarr.core.types import BytesLike, ChunkCoords # Everything here is imported into ``zarr.core.buffer`` namespace. __all__: list[str] = [] diff --git a/src/zarr/core/buffer/cpu.py b/src/zarr/core/buffer/cpu.py index 9da0059d0b..4fbd5e6e36 100644 --- a/src/zarr/core/buffer/cpu.py +++ b/src/zarr/core/buffer/cpu.py @@ -20,7 +20,7 @@ from typing import Self from zarr.core.buffer.core import ArrayLike, NDArrayLike - from zarr.core.common import BytesLike, ChunkCoords + from zarr.core.types import BytesLike, ChunkCoords class Buffer(core.Buffer): diff --git a/src/zarr/core/buffer/gpu.py b/src/zarr/core/buffer/gpu.py index 4eca197222..8f731ad72a 100644 --- a/src/zarr/core/buffer/gpu.py +++ b/src/zarr/core/buffer/gpu.py @@ -23,7 +23,7 @@ from collections.abc import Iterable from typing import Self - from zarr.core.common import BytesLike, ChunkCoords + from zarr.core.types import BytesLike, ChunkCoords try: import cupy as cp diff --git a/src/zarr/core/chunk_grids.py b/src/zarr/core/chunk_grids.py index 7fa1fc7e38..8ba09dec57 100644 --- a/src/zarr/core/chunk_grids.py +++ b/src/zarr/core/chunk_grids.py @@ -14,10 +14,6 @@ from zarr.abc.metadata import Metadata from zarr.core.common import ( - JSON, - ChunkCoords, - ChunkCoordsLike, - ShapeLike, ceildiv, parse_named_configuration, parse_shapelike, @@ -29,6 +25,7 @@ from typing import Self from zarr.core.array import ShardsLike + from zarr.core.types import JSON, ChunkCoords, ChunkCoordsLike, ShapeLike def _guess_chunks( diff --git a/src/zarr/core/chunk_key_encodings.py b/src/zarr/core/chunk_key_encodings.py index 91dfc90365..1129a3491b 100644 --- a/src/zarr/core/chunk_key_encodings.py +++ b/src/zarr/core/chunk_key_encodings.py @@ -7,10 +7,10 @@ if TYPE_CHECKING: from typing import NotRequired + from zarr.core.types import JSON, ChunkCoords + from zarr.abc.metadata import Metadata from zarr.core.common import ( - JSON, - ChunkCoords, parse_named_configuration, ) diff --git a/src/zarr/core/codec_pipeline.py b/src/zarr/core/codec_pipeline.py index 3bc3c1cfc7..fb42764f35 100644 --- a/src/zarr/core/codec_pipeline.py +++ b/src/zarr/core/codec_pipeline.py @@ -14,7 +14,7 @@ Codec, CodecPipeline, ) -from zarr.core.common import ChunkCoords, concurrent_map +from zarr.core.common import concurrent_map from zarr.core.config import config from zarr.core.indexing import SelectorTuple, is_scalar from zarr.errors import ZarrUserWarning @@ -29,6 +29,7 @@ from zarr.core.buffer import Buffer, BufferPrototype, NDBuffer from zarr.core.chunk_grids import ChunkGrid from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType + from zarr.core.types import ChunkCoords T = TypeVar("T") U = TypeVar("U") diff --git a/src/zarr/core/common.py b/src/zarr/core/common.py index 4c0247426e..8354e393e4 100644 --- a/src/zarr/core/common.py +++ b/src/zarr/core/common.py @@ -5,66 +5,30 @@ import math import operator import warnings -from collections.abc import Iterable, Mapping, Sequence from enum import Enum from itertools import starmap from typing import ( TYPE_CHECKING, Any, - Final, - Generic, Literal, - TypedDict, TypeVar, cast, overload, ) -from typing_extensions import ReadOnly - from zarr.core.config import config as zarr_config + +# This JSON import must be outside the type-checking block to avoid breaking numcodecs. see +# https://github.com/zarr-developers/numcodecs/issues/773. +# This can be changed when the circular dependency between zarr python and numcodecs is resolved. +from zarr.core.types import JSON, MEMORY_ORDER, MemoryOrder from zarr.errors import ZarrRuntimeWarning if TYPE_CHECKING: - from collections.abc import Awaitable, Callable, Iterator - - -ZARR_JSON = "zarr.json" -ZARRAY_JSON = ".zarray" -ZGROUP_JSON = ".zgroup" -ZATTRS_JSON = ".zattrs" -ZMETADATA_V2_JSON = ".zmetadata" - -BytesLike = bytes | bytearray | memoryview -ShapeLike = tuple[int, ...] | int -ChunkCoords = tuple[int, ...] -ChunkCoordsLike = Iterable[int] -ZarrFormat = Literal[2, 3] -NodeType = Literal["array", "group"] -JSON = str | int | float | Mapping[str, "JSON"] | Sequence["JSON"] | None -MemoryOrder = Literal["C", "F"] -AccessModeLiteral = Literal["r", "r+", "a", "w", "w-"] -ANY_ACCESS_MODE: Final = "r", "r+", "a", "w", "w-" -DimensionNames = Iterable[str | None] | None - -TName = TypeVar("TName", bound=str) -TConfig = TypeVar("TConfig", bound=Mapping[str, object]) - - -class NamedConfig(TypedDict, Generic[TName, TConfig]): - """ - A typed dictionary representing an object with a name and configuration, where the configuration - is a mapping of string keys to values, e.g. another typed dictionary or a JSON object. - - This class is generic with two type parameters: the type of the name (``TName``) and the type of - the configuration (``TConfig``). - """ - - name: ReadOnly[TName] - """The name of the object.""" + from collections.abc import Awaitable, Callable, Iterable, Iterator - configuration: ReadOnly[TConfig] - """The configuration of the object.""" + from zarr.core.types import ChunkCoords + from zarr.types import ZarrFormat def product(tup: ChunkCoords) -> int: @@ -186,10 +150,10 @@ def parse_fill_value(data: Any) -> Any: return data -def parse_order(data: Any) -> Literal["C", "F"]: - if data in ("C", "F"): +def parse_order(data: Any) -> MemoryOrder: + if data in MEMORY_ORDER: return cast("Literal['C', 'F']", data) - raise ValueError(f"Expected one of ('C', 'F'), got {data} instead.") + raise ValueError(f"Expected one of {MEMORY_ORDER}, got {data} instead.") def parse_bool(data: Any) -> bool: diff --git a/src/zarr/core/dtype/__init__.py b/src/zarr/core/dtype/__init__.py index bf09a7501e..e3eaf37e01 100644 --- a/src/zarr/core/dtype/__init__.py +++ b/src/zarr/core/dtype/__init__.py @@ -32,14 +32,13 @@ ) if TYPE_CHECKING: - from zarr.core.common import ZarrFormat + from zarr.types import ZarrFormat from collections.abc import Mapping import numpy as np import numpy.typing as npt -from zarr.core.common import JSON from zarr.core.dtype.npy.string import ( FixedLengthUTF32, FixedLengthUTF32JSON_V2, @@ -49,6 +48,7 @@ ) from zarr.core.dtype.registry import DataTypeRegistry from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType +from zarr.core.types import JSON __all__ = [ "Bool", diff --git a/src/zarr/core/dtype/common.py b/src/zarr/core/dtype/common.py index 652b5fdbe3..ac1e9ff753 100644 --- a/src/zarr/core/dtype/common.py +++ b/src/zarr/core/dtype/common.py @@ -15,7 +15,7 @@ from typing_extensions import ReadOnly -from zarr.core.common import NamedConfig +from zarr.core.types import NamedConfig from zarr.errors import UnstableSpecificationWarning EndiannessStr = Literal["little", "big"] diff --git a/src/zarr/core/dtype/npy/bool.py b/src/zarr/core/dtype/npy/bool.py index 37371cd0cd..88197ab6b3 100644 --- a/src/zarr/core/dtype/npy/bool.py +++ b/src/zarr/core/dtype/npy/bool.py @@ -15,7 +15,8 @@ from zarr.core.dtype.wrapper import TBaseDType, ZDType if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat @dataclass(frozen=True, kw_only=True, slots=True) diff --git a/src/zarr/core/dtype/npy/bytes.py b/src/zarr/core/dtype/npy/bytes.py index b7c764dcd9..0cba7e3e75 100644 --- a/src/zarr/core/dtype/npy/bytes.py +++ b/src/zarr/core/dtype/npy/bytes.py @@ -3,11 +3,10 @@ import base64 import re from dataclasses import dataclass -from typing import ClassVar, Literal, Self, TypedDict, TypeGuard, cast, overload +from typing import TYPE_CHECKING, ClassVar, Literal, Self, TypedDict, TypeGuard, cast, overload import numpy as np -from zarr.core.common import JSON, NamedConfig, ZarrFormat from zarr.core.dtype.common import ( DataTypeValidationError, DTypeConfig_V2, @@ -20,6 +19,10 @@ ) from zarr.core.dtype.npy.common import check_json_str from zarr.core.dtype.wrapper import TBaseDType, ZDType +from zarr.core.types import JSON, NamedConfig + +if TYPE_CHECKING: + from zarr.types import ZarrFormat BytesLike = np.bytes_ | str | bytes | int diff --git a/src/zarr/core/dtype/npy/common.py b/src/zarr/core/dtype/npy/common.py index 67644449a0..39594a5999 100644 --- a/src/zarr/core/dtype/npy/common.py +++ b/src/zarr/core/dtype/npy/common.py @@ -28,7 +28,8 @@ ) if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat IntLike = SupportsInt | SupportsIndex | bytes | str FloatLike = SupportsIndex | SupportsFloat | bytes | str diff --git a/src/zarr/core/dtype/npy/complex.py b/src/zarr/core/dtype/npy/complex.py index 2f432a9e0a..e451dac98b 100644 --- a/src/zarr/core/dtype/npy/complex.py +++ b/src/zarr/core/dtype/npy/complex.py @@ -36,7 +36,8 @@ from zarr.core.dtype.wrapper import TBaseDType, ZDType if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat @dataclass(frozen=True) diff --git a/src/zarr/core/dtype/npy/float.py b/src/zarr/core/dtype/npy/float.py index 3113bc5b61..941b9281f6 100644 --- a/src/zarr/core/dtype/npy/float.py +++ b/src/zarr/core/dtype/npy/float.py @@ -29,7 +29,8 @@ from zarr.core.dtype.wrapper import TBaseDType, ZDType if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat @dataclass(frozen=True) diff --git a/src/zarr/core/dtype/npy/int.py b/src/zarr/core/dtype/npy/int.py index 01a79142a3..d8a223dc59 100644 --- a/src/zarr/core/dtype/npy/int.py +++ b/src/zarr/core/dtype/npy/int.py @@ -31,7 +31,8 @@ from zarr.core.dtype.wrapper import TBaseDType, ZDType if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat _NumpyIntDType = ( np.dtypes.Int8DType diff --git a/src/zarr/core/dtype/npy/string.py b/src/zarr/core/dtype/npy/string.py index 32375a1c71..f45317d10f 100644 --- a/src/zarr/core/dtype/npy/string.py +++ b/src/zarr/core/dtype/npy/string.py @@ -16,7 +16,6 @@ import numpy as np -from zarr.core.common import NamedConfig from zarr.core.dtype.common import ( DataTypeValidationError, DTypeConfig_V2, @@ -34,10 +33,12 @@ get_endianness_from_numpy_dtype, ) from zarr.core.dtype.wrapper import TDType_co, ZDType +from zarr.core.types import NamedConfig if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat from zarr.core.dtype.wrapper import TBaseDType + from zarr.core.types import JSON + from zarr.types import ZarrFormat _NUMPY_SUPPORTS_VLEN_STRING = hasattr(np.dtypes, "StringDType") diff --git a/src/zarr/core/dtype/npy/structured.py b/src/zarr/core/dtype/npy/structured.py index a0e3b0fbd4..5089116ed1 100644 --- a/src/zarr/core/dtype/npy/structured.py +++ b/src/zarr/core/dtype/npy/structured.py @@ -6,7 +6,6 @@ import numpy as np -from zarr.core.common import NamedConfig from zarr.core.dtype.common import ( DataTypeValidationError, DTypeConfig_V2, @@ -23,9 +22,11 @@ check_json_str, ) from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType +from zarr.core.types import NamedConfig if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat StructuredScalarLike = list[object] | tuple[object, ...] | bytes | int diff --git a/src/zarr/core/dtype/npy/time.py b/src/zarr/core/dtype/npy/time.py index d523e16940..7bf1a925af 100644 --- a/src/zarr/core/dtype/npy/time.py +++ b/src/zarr/core/dtype/npy/time.py @@ -18,7 +18,6 @@ import numpy as np from typing_extensions import ReadOnly -from zarr.core.common import NamedConfig from zarr.core.dtype.common import ( DataTypeValidationError, DTypeConfig_V2, @@ -35,9 +34,11 @@ get_endianness_from_numpy_dtype, ) from zarr.core.dtype.wrapper import TBaseDType, ZDType +from zarr.core.types import NamedConfig if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat TimeDeltaLike = str | int | bytes | np.timedelta64 | timedelta | None DateTimeLike = str | int | bytes | np.datetime64 | datetime | None diff --git a/src/zarr/core/dtype/registry.py b/src/zarr/core/dtype/registry.py index cb9ab50044..c83009654e 100644 --- a/src/zarr/core/dtype/registry.py +++ b/src/zarr/core/dtype/registry.py @@ -14,8 +14,8 @@ if TYPE_CHECKING: from importlib.metadata import EntryPoint - from zarr.core.common import ZarrFormat from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType + from zarr.types import ZarrFormat # This class is different from the other registry classes, which inherit from diff --git a/src/zarr/core/dtype/wrapper.py b/src/zarr/core/dtype/wrapper.py index 776aea81d8..53fe56c944 100644 --- a/src/zarr/core/dtype/wrapper.py +++ b/src/zarr/core/dtype/wrapper.py @@ -39,8 +39,9 @@ import numpy as np if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat from zarr.core.dtype.common import DTypeJSON, DTypeSpec_V2, DTypeSpec_V3 + from zarr.core.types import JSON + from zarr.types import ZarrFormat # This the upper bound for the scalar types we support. It's numpy scalars + str, # because the new variable-length string dtype in numpy does not have a corresponding scalar type diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py index 4bdc7b549f..be478a4b5c 100644 --- a/src/zarr/core/group.py +++ b/src/zarr/core/group.py @@ -35,6 +35,12 @@ from zarr.core.attributes import Attributes from zarr.core.buffer import default_buffer_prototype from zarr.core.common import ( + parse_shapelike, +) +from zarr.core.config import config +from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata +from zarr.core.sync import SyncMixin, sync +from zarr.core.types import ( JSON, ZARR_JSON, ZARRAY_JSON, @@ -45,12 +51,7 @@ DimensionNames, NodeType, ShapeLike, - ZarrFormat, - parse_shapelike, ) -from zarr.core.config import config -from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata -from zarr.core.sync import SyncMixin, sync from zarr.errors import ( ContainsArrayError, ContainsGroupError, @@ -77,8 +78,9 @@ from zarr.core.array_spec import ArrayConfig, ArrayConfigLike from zarr.core.buffer import Buffer, BufferPrototype from zarr.core.chunk_key_encodings import ChunkKeyEncodingLike - from zarr.core.common import MemoryOrder from zarr.core.dtype import ZDTypeLike + from zarr.core.types import MemoryOrder + from zarr.types import ZarrFormat logger = logging.getLogger("zarr.group") diff --git a/src/zarr/core/indexing.py b/src/zarr/core/indexing.py index 15cf6f0f1a..c3cf01422c 100644 --- a/src/zarr/core/indexing.py +++ b/src/zarr/core/indexing.py @@ -33,7 +33,7 @@ from zarr.core.array import Array, AsyncArray from zarr.core.buffer import NDArrayLikeOrScalar from zarr.core.chunk_grids import ChunkGrid - from zarr.core.common import ChunkCoords + from zarr.core.types import ChunkCoords IntSequence = list[int] | npt.NDArray[np.intp] diff --git a/src/zarr/core/metadata/__init__.py b/src/zarr/core/metadata/__init__.py index 43b5ec98fe..05c34981d2 100644 --- a/src/zarr/core/metadata/__init__.py +++ b/src/zarr/core/metadata/__init__.py @@ -1,17 +1,18 @@ from typing import TypeAlias, TypeVar -from .v2 import ArrayV2Metadata, ArrayV2MetadataDict -from .v3 import ArrayV3Metadata, ArrayV3MetadataDict +from ..types import ArrayMetadataJSON_V2, ArrayMetadataJSON_V3 +from .v2 import ArrayV2Metadata +from .v3 import ArrayV3Metadata ArrayMetadata: TypeAlias = ArrayV2Metadata | ArrayV3Metadata -ArrayMetadataDict: TypeAlias = ArrayV2MetadataDict | ArrayV3MetadataDict +ArrayMetadataDict: TypeAlias = ArrayMetadataJSON_V2 | ArrayMetadataJSON_V3 T_ArrayMetadata = TypeVar("T_ArrayMetadata", ArrayV2Metadata, ArrayV3Metadata) __all__ = [ "ArrayMetadata", "ArrayMetadataDict", + "ArrayMetadataJSON_V2", + "ArrayMetadataJSON_V3", "ArrayV2Metadata", - "ArrayV2MetadataDict", "ArrayV3Metadata", - "ArrayV3MetadataDict", ] diff --git a/src/zarr/core/metadata/common.py b/src/zarr/core/metadata/common.py index 44d3eb292b..1ff6c2fd08 100644 --- a/src/zarr/core/metadata/common.py +++ b/src/zarr/core/metadata/common.py @@ -3,7 +3,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from zarr.core.common import JSON + from zarr.core.types import JSON def parse_attributes(data: dict[str, JSON] | None) -> dict[str, JSON]: diff --git a/src/zarr/core/metadata/v2.py b/src/zarr/core/metadata/v2.py index 9ad6b3bc42..a60392d71c 100644 --- a/src/zarr/core/metadata/v2.py +++ b/src/zarr/core/metadata/v2.py @@ -3,7 +3,7 @@ import warnings from collections.abc import Iterable, Sequence from functools import cached_property -from typing import TYPE_CHECKING, Any, TypeAlias, TypedDict, cast +from typing import TYPE_CHECKING, Any, TypeAlias, cast import numcodecs.abc @@ -11,6 +11,7 @@ from zarr.core.chunk_grids import RegularChunkGrid from zarr.core.dtype import get_data_type_from_json from zarr.core.dtype.common import OBJECT_CODEC_IDS, DTypeSpec_V2 +from zarr.core.types import JSON, ZARRAY_JSON, ZATTRS_JSON, MemoryOrder from zarr.errors import ZarrUserWarning if TYPE_CHECKING: @@ -19,7 +20,6 @@ import numpy.typing as npt from zarr.core.buffer import Buffer, BufferPrototype - from zarr.core.common import ChunkCoords from zarr.core.dtype.wrapper import ( TBaseDType, TBaseScalar, @@ -27,6 +27,7 @@ TScalar_co, ZDType, ) + from zarr.core.types import ChunkCoords import json from dataclasses import dataclass, field, fields, replace @@ -37,25 +38,11 @@ from zarr.core.array_spec import ArrayConfig, ArraySpec from zarr.core.chunk_key_encodings import parse_separator from zarr.core.common import ( - JSON, - ZARRAY_JSON, - ZATTRS_JSON, - MemoryOrder, parse_shapelike, ) from zarr.core.config import config, parse_indexing_order from zarr.core.metadata.common import parse_attributes - -class ArrayV2MetadataDict(TypedDict): - """ - A typed dictionary model for Zarr format 2 metadata. - """ - - zarr_format: Literal[2] - attributes: dict[str, JSON] - - # Union of acceptable types for v2 compressors CompressorLikev2: TypeAlias = dict[str, JSON] | numcodecs.abc.Codec | None diff --git a/src/zarr/core/metadata/v3.py b/src/zarr/core/metadata/v3.py index 6f79fb4b09..1282195c74 100644 --- a/src/zarr/core/metadata/v3.py +++ b/src/zarr/core/metadata/v3.py @@ -1,19 +1,20 @@ from __future__ import annotations -from typing import TYPE_CHECKING, TypedDict +from typing import TYPE_CHECKING from zarr.abc.metadata import Metadata from zarr.core.buffer.core import default_buffer_prototype from zarr.core.dtype import VariableLengthUTF8, ZDType, get_data_type_from_json from zarr.core.dtype.common import check_dtype_spec_v3 +from zarr.core.types import JSON, ZARR_JSON, ChunkCoords, DimensionNames if TYPE_CHECKING: from typing import Self from zarr.core.buffer import Buffer, BufferPrototype from zarr.core.chunk_grids import ChunkGrid - from zarr.core.common import JSON, ChunkCoords from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar + from zarr.core.types import ChunkCoords import json @@ -26,10 +27,6 @@ from zarr.core.chunk_grids import ChunkGrid, RegularChunkGrid from zarr.core.chunk_key_encodings import ChunkKeyEncoding, ChunkKeyEncodingLike from zarr.core.common import ( - JSON, - ZARR_JSON, - ChunkCoords, - DimensionNames, parse_named_configuration, parse_shapelike, ) @@ -127,15 +124,6 @@ def parse_storage_transformers(data: object) -> tuple[dict[str, JSON], ...]: ) -class ArrayV3MetadataDict(TypedDict): - """ - A typed dictionary model for zarr v3 metadata. - """ - - zarr_format: Literal[3] - attributes: dict[str, JSON] - - @dataclass(frozen=True, kw_only=True) class ArrayV3Metadata(Metadata): shape: ChunkCoords diff --git a/src/zarr/core/sync_group.py b/src/zarr/core/sync_group.py index 39d8a17992..ca2d54b937 100644 --- a/src/zarr/core/sync_group.py +++ b/src/zarr/core/sync_group.py @@ -14,8 +14,8 @@ from zarr.abc.store import Store from zarr.core.array import Array - from zarr.core.common import ZarrFormat from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata + from zarr.types import ZarrFormat def create_nodes( diff --git a/src/zarr/core/types.py b/src/zarr/core/types.py new file mode 100644 index 0000000000..ffb785633c --- /dev/null +++ b/src/zarr/core/types.py @@ -0,0 +1,122 @@ +"""Type definitions and typed constants for Zarr data structures.""" + +from __future__ import annotations + +from collections.abc import Iterable, Mapping, Sequence +from typing import Final, Generic, Literal, NotRequired, TypeVar + +from typing_extensions import ReadOnly, TypedDict + +NodeType = Literal["array", "group"] +"""The names of the nodes in a Zarr hierarchy.""" + + +BytesLike = bytes | bytearray | memoryview + +ChunkCoords = tuple[int, ...] + +ShapeLike = tuple[int, ...] | int +"""A shape, either as a tuple of integers or a single integer.""" + +JSON = str | int | float | Mapping[str, "JSON"] | Sequence["JSON"] | None +"""A JSON value.""" + +MemoryOrder = Literal["C", "F"] +"""Memory order represented as a string using NumPy / Zarr V2 conventions.""" + +MEMORY_ORDER: Final = "C", "F" + +DimensionSeparator_V2 = Literal[".", "/"] +"""The possible values for the dimension separator in Zarr V2 array metadata.""" + +ChunkCoordsLike = Iterable[int] +AccessModeLiteral = Literal["r", "r+", "a", "w", "w-"] +ACCESS_MODE_LITERAL: Final = "r", "r+", "a", "w", "w-" + +DimensionNames = Iterable[str | None] | None +"""The possible types for the dimension names in Zarr V3 array metadata.""" + + +TName = TypeVar("TName", bound=str) +TConfig = TypeVar("TConfig", bound=Mapping[str, object]) + + +class NamedConfig(TypedDict, Generic[TName, TConfig]): + """ + A typed dictionary representing an object with a name and configuration, where the configuration + is a mapping of string keys to values, e.g. another typed dictionary or a JSON object. + + This class is generic with two type parameters: the type of the name (``TName``) and the type of + the configuration (``TConfig``). + """ + + name: ReadOnly[TName] + """The name of the object.""" + + configuration: ReadOnly[TConfig] + """The configuration of the object.""" + + +ZARR_JSON: Final = "zarr.json" +ZARRAY_JSON: Final = ".zarray" +ZGROUP_JSON: Final = ".zgroup" +ZATTRS_JSON: Final = ".zattrs" +ZMETADATA_V2_JSON: Final = ".zmetadata" + + +class CodecJSON_V2(TypedDict, Generic[TName]): + """The JSON representation of a codec for Zarr V2""" + + id: ReadOnly[TName] + + +class GroupMetadataJSON_V2(TypedDict): + """ + A typed dictionary model for Zarr format 2 group metadata. + """ + + zarr_format: Literal[2] + + +class ArrayMetadataJSON_V2(TypedDict): + """ + A typed dictionary model for Zarr format 2 metadata. + """ + + zarr_format: Literal[2] + shape: tuple[int, ...] + chunks: tuple[int, ...] + dtype: str | tuple[tuple[str, object], ...] + compressor: CodecJSON_V2[str] | None + fill_value: object | None + order: MemoryOrder + filters: tuple[CodecJSON_V2[str], ...] | None + dimension_separator: NotRequired[DimensionSeparator_V2] + + +class GroupMetadataJSON_V3(TypedDict): + """ + A typed dictionary model for Zarr format 2 group metadata. + """ + + zarr_format: Literal[3] + node_type: Literal["group"] + attributes: NotRequired[Mapping[str, JSON]] + + +class ArrayMetadataJSON_V3(TypedDict): + """ + A typed dictionary model for zarr v3 metadata. + """ + + zarr_format: Literal[3] + node_type: Literal["array"] + data_type: str | NamedConfig[str, Mapping[str, object]] + shape: tuple[int, ...] + chunk_grid: NamedConfig[str, Mapping[str, object]] + chunk_key_encoding: NamedConfig[str, Mapping[str, object]] + fill_value: object + codecs: tuple[str | NamedConfig[str, Mapping[str, object]], ...] + attributes: NotRequired[Mapping[str, JSON]] + storage_transformers: NotRequired[tuple[NamedConfig[str, Mapping[str, object]], ...]] + dimension_names: NotRequired[tuple[str | None]] diff --git a/src/zarr/registry.py b/src/zarr/registry.py index fc3ffd7f7c..9363f12808 100644 --- a/src/zarr/registry.py +++ b/src/zarr/registry.py @@ -20,7 +20,7 @@ CodecPipeline, ) from zarr.core.buffer import Buffer, NDBuffer - from zarr.core.common import JSON + from zarr.core.types import JSON __all__ = [ "Registry", diff --git a/src/zarr/storage/_common.py b/src/zarr/storage/_common.py index 3a63b30e9b..8ba6ee663a 100644 --- a/src/zarr/storage/_common.py +++ b/src/zarr/storage/_common.py @@ -7,13 +7,12 @@ from zarr.abc.store import ByteRequest, Store from zarr.core.buffer import Buffer, default_buffer_prototype -from zarr.core.common import ( - ANY_ACCESS_MODE, +from zarr.core.types import ( + ACCESS_MODE_LITERAL, ZARR_JSON, ZARRAY_JSON, ZGROUP_JSON, AccessModeLiteral, - ZarrFormat, ) from zarr.errors import ContainsArrayAndGroupError, ContainsArrayError, ContainsGroupError from zarr.storage._local import LocalStore @@ -28,6 +27,7 @@ if TYPE_CHECKING: from zarr.core.buffer import BufferPrototype + from zarr.types import ZarrFormat def _dereference_path(root: str, path: str) -> str: @@ -103,8 +103,8 @@ async def open(cls, store: Store, path: str, mode: AccessModeLiteral | None = No if mode is None: return await cls._create_open_instance(store, path) - if mode not in ANY_ACCESS_MODE: - raise ValueError(f"Invalid mode: {mode}, expected one of {ANY_ACCESS_MODE}") + if mode not in ACCESS_MODE_LITERAL: + raise ValueError(f"Invalid mode: {mode}, expected one of {ACCESS_MODE_LITERAL}") if store.read_only: # Don't allow write operations on a read-only store diff --git a/src/zarr/storage/_fsspec.py b/src/zarr/storage/_fsspec.py index bbb934cc7d..f71bc49563 100644 --- a/src/zarr/storage/_fsspec.py +++ b/src/zarr/storage/_fsspec.py @@ -26,7 +26,7 @@ from fsspec.mapping import FSMap from zarr.core.buffer import BufferPrototype - from zarr.core.common import BytesLike + from zarr.core.types import BytesLike ALLOWED_EXCEPTIONS: tuple[type[Exception], ...] = ( diff --git a/src/zarr/storage/_obstore.py b/src/zarr/storage/_obstore.py index e1469a991e..3a34dd87d5 100644 --- a/src/zarr/storage/_obstore.py +++ b/src/zarr/storage/_obstore.py @@ -23,7 +23,7 @@ from obstore.store import ObjectStore as _UpstreamObjectStore from zarr.core.buffer import Buffer, BufferPrototype - from zarr.core.common import BytesLike + from zarr.core.types import BytesLike __all__ = ["ObjectStore"] diff --git a/src/zarr/storage/_wrapper.py b/src/zarr/storage/_wrapper.py index f21d378191..700caadf06 100644 --- a/src/zarr/storage/_wrapper.py +++ b/src/zarr/storage/_wrapper.py @@ -9,7 +9,7 @@ from zarr.abc.store import ByteRequest from zarr.core.buffer import Buffer, BufferPrototype - from zarr.core.common import BytesLike + from zarr.core.types import BytesLike from zarr.abc.store import Store diff --git a/src/zarr/testing/buffer.py b/src/zarr/testing/buffer.py index 8cbfb2414a..05eb65f36f 100644 --- a/src/zarr/testing/buffer.py +++ b/src/zarr/testing/buffer.py @@ -13,7 +13,7 @@ from collections.abc import Iterable from typing import Self - from zarr.core.common import ChunkCoords + from zarr.core.types import ChunkCoords __all__ = [ diff --git a/src/zarr/testing/strategies.py b/src/zarr/testing/strategies.py index d0726c3dd9..64d3527557 100644 --- a/src/zarr/testing/strategies.py +++ b/src/zarr/testing/strategies.py @@ -16,13 +16,14 @@ from zarr.core.array import Array from zarr.core.chunk_grids import RegularChunkGrid from zarr.core.chunk_key_encodings import DefaultChunkKeyEncoding -from zarr.core.common import JSON, ZarrFormat from zarr.core.dtype import get_data_type_from_native_dtype from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata from zarr.core.sync import sync +from zarr.core.types import JSON from zarr.storage import MemoryStore, StoreLike from zarr.storage._common import _dereference_path from zarr.storage._utils import normalize_path +from zarr.types import ZarrFormat # Copied from Xarray _attr_keys = st.text(st.characters(), min_size=1) diff --git a/src/zarr/testing/utils.py b/src/zarr/testing/utils.py index 3cb7f5cb99..1d915f3a93 100644 --- a/src/zarr/testing/utils.py +++ b/src/zarr/testing/utils.py @@ -7,7 +7,7 @@ from zarr.core.buffer import Buffer if TYPE_CHECKING: - from zarr.core.common import BytesLike + from zarr.core.types import BytesLike __all__ = ["assert_bytes_equal"] diff --git a/src/zarr/types.py b/src/zarr/types.py new file mode 100644 index 0000000000..2aff88d13b --- /dev/null +++ b/src/zarr/types.py @@ -0,0 +1,20 @@ +"""Public type definitions and constants""" + +from typing import Literal + +from zarr.core.types import ( + ArrayMetadataJSON_V2, + ArrayMetadataJSON_V3, + GroupMetadataJSON_V2, + GroupMetadataJSON_V3, +) + +__all__ = [ + "ArrayMetadataJSON_V2", + "ArrayMetadataJSON_V3", + "GroupMetadataJSON_V2", + "GroupMetadataJSON_V3", + "ZarrFormat", +] +ZarrFormat = Literal[2, 3] +"""The versions of Zarr that are supported.""" diff --git a/tests/conftest.py b/tests/conftest.py index a1bf423c06..d2e3094a02 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,7 +21,7 @@ _parse_chunk_key_encoding, ) from zarr.core.chunk_grids import RegularChunkGrid, _auto_partition -from zarr.core.common import JSON, DimensionNames, parse_shapelike +from zarr.core.common import parse_shapelike from zarr.core.config import config as zarr_config from zarr.core.dtype import ( get_data_type_from_native_dtype, @@ -41,8 +41,15 @@ from zarr.abc.codec import Codec from zarr.core.array import CompressorsLike, FiltersLike, SerializerLike, ShardsLike from zarr.core.chunk_key_encodings import ChunkKeyEncoding, ChunkKeyEncodingLike - from zarr.core.common import ChunkCoords, MemoryOrder, ShapeLike, ZarrFormat from zarr.core.dtype.wrapper import ZDType + from zarr.core.types import ( + JSON, + ChunkCoords, + DimensionNames, + MemoryOrder, + ShapeLike, + ) + from zarr.types import ZarrFormat async def parse_store( diff --git a/tests/package_with_entrypoint/__init__.py b/tests/package_with_entrypoint/__init__.py index ae86378cb5..9bcc50802e 100644 --- a/tests/package_with_entrypoint/__init__.py +++ b/tests/package_with_entrypoint/__init__.py @@ -17,7 +17,7 @@ from typing import Any, ClassVar, Literal, Self from zarr.core.array_spec import ArraySpec - from zarr.core.common import ZarrFormat + from zarr.types import ZarrFormat class TestEntrypointCodec(ArrayBytesCodec): diff --git a/tests/test_api.py b/tests/test_api.py index 12acf80589..e1b40e91f5 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -15,7 +15,8 @@ from pathlib import Path from zarr.abc.store import Store - from zarr.core.common import JSON, MemoryOrder, ZarrFormat + from zarr.core.types import JSON, MemoryOrder + from zarr.types import ZarrFormat import contextlib from typing import Literal diff --git a/tests/test_array.py b/tests/test_array.py index 74201a4017..09b3857fa5 100644 --- a/tests/test_array.py +++ b/tests/test_array.py @@ -41,7 +41,7 @@ from zarr.core.buffer import NDArrayLike, NDArrayLikeOrScalar, default_buffer_prototype from zarr.core.chunk_grids import _auto_partition from zarr.core.chunk_key_encodings import ChunkKeyEncodingParams -from zarr.core.common import JSON, ZarrFormat, ceildiv +from zarr.core.common import ceildiv from zarr.core.dtype import ( DateTime64, Float32, @@ -69,11 +69,13 @@ ZarrUserWarning, ) from zarr.storage import LocalStore, MemoryStore, StorePath +from zarr.types import ZarrFormat from .test_dtype.conftest import zdtype_examples if TYPE_CHECKING: from zarr.core.metadata.v3 import ArrayV3Metadata + from zarr.core.types import JSON @pytest.mark.parametrize("store", ["local", "memory", "zip"], indirect=["store"]) diff --git a/tests/test_attributes.py b/tests/test_attributes.py index 4ce40e2cb0..5746419f6f 100644 --- a/tests/test_attributes.py +++ b/tests/test_attributes.py @@ -8,7 +8,7 @@ import zarr.core.attributes import zarr.storage from tests.conftest import deep_nan_equal -from zarr.core.common import ZarrFormat +from zarr.types import ZarrFormat @pytest.mark.parametrize("zarr_format", [2, 3]) diff --git a/tests/test_codecs/test_codecs.py b/tests/test_codecs/test_codecs.py index a2dad41a1b..c774049521 100644 --- a/tests/test_codecs/test_codecs.py +++ b/tests/test_codecs/test_codecs.py @@ -28,7 +28,7 @@ from zarr.abc.codec import Codec from zarr.abc.store import Store from zarr.core.buffer.core import NDArrayLikeOrScalar - from zarr.core.common import ChunkCoords, MemoryOrder + from zarr.core.types import ChunkCoords, MemoryOrder @dataclass(frozen=True) diff --git a/tests/test_codecs/test_transpose.py b/tests/test_codecs/test_transpose.py index 06ec668ad3..45ac6e454f 100644 --- a/tests/test_codecs/test_transpose.py +++ b/tests/test_codecs/test_transpose.py @@ -5,7 +5,7 @@ from zarr import AsyncArray, config from zarr.abc.store import Store from zarr.codecs import TransposeCodec -from zarr.core.common import MemoryOrder +from zarr.core.types import MemoryOrder from zarr.storage import StorePath from .test_codecs import _AsyncArrayProxy diff --git a/tests/test_common.py b/tests/test_common.py index 0944c3375a..64ecb442fb 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -6,13 +6,12 @@ import pytest from zarr.core.common import ( - ANY_ACCESS_MODE, - AccessModeLiteral, parse_name, parse_shapelike, product, ) from zarr.core.config import parse_indexing_order +from zarr.core.types import ACCESS_MODE_LITERAL, AccessModeLiteral if TYPE_CHECKING: from collections.abc import Iterable @@ -28,7 +27,7 @@ def test_access_modes() -> None: """ Test that the access modes type and variable for run-time checking are equivalent. """ - assert set(ANY_ACCESS_MODE) == set(get_args(AccessModeLiteral)) + assert set(ACCESS_MODE_LITERAL) == set(get_args(AccessModeLiteral)) # todo: test diff --git a/tests/test_dtype/test_npy/test_common.py b/tests/test_dtype/test_npy/test_common.py index bd77866fc0..81eb794fc6 100644 --- a/tests/test_dtype/test_npy/test_common.py +++ b/tests/test_dtype/test_npy/test_common.py @@ -32,7 +32,8 @@ ) if TYPE_CHECKING: - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat json_float_v2_roundtrip_cases: tuple[tuple[JSONFloatV2, float | np.floating[Any]], ...] = ( diff --git a/tests/test_dtype_registry.py b/tests/test_dtype_registry.py index aedda5272c..c27a93b193 100644 --- a/tests/test_dtype_registry.py +++ b/tests/test_dtype_registry.py @@ -31,7 +31,7 @@ if TYPE_CHECKING: from collections.abc import Generator - from zarr.core.common import ZarrFormat + from zarr.types import ZarrFormat from .test_dtype.conftest import zdtype_examples diff --git a/tests/test_group.py b/tests/test_group.py index e5cfe82daa..05f866fda7 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -60,7 +60,8 @@ from _pytest.compat import LEGACY_PATH from zarr.core.buffer.core import Buffer - from zarr.core.common import JSON, ZarrFormat + from zarr.core.types import JSON + from zarr.types import ZarrFormat @pytest.fixture(params=["local", "memory", "zip"]) diff --git a/tests/test_indexing.py b/tests/test_indexing.py index 24b4b65505..8a1fe417ae 100644 --- a/tests/test_indexing.py +++ b/tests/test_indexing.py @@ -33,7 +33,7 @@ from zarr.core.buffer import BufferPrototype from zarr.core.buffer.core import Buffer - from zarr.core.common import ChunkCoords + from zarr.core.types import ChunkCoords @pytest.fixture diff --git a/tests/test_info.py b/tests/test_info.py index 28c8803c83..5a81b338f9 100644 --- a/tests/test_info.py +++ b/tests/test_info.py @@ -4,8 +4,8 @@ from zarr.codecs.bytes import BytesCodec from zarr.core._info import ArrayInfo, GroupInfo, human_readable_size -from zarr.core.common import ZarrFormat from zarr.core.dtype.npy.int import Int32 +from zarr.types import ZarrFormat ZARR_FORMATS = [2, 3] diff --git a/tests/test_metadata/test_consolidated.py b/tests/test_metadata/test_consolidated.py index e23444cf93..e4f38cfc3f 100644 --- a/tests/test_metadata/test_consolidated.py +++ b/tests/test_metadata/test_consolidated.py @@ -27,7 +27,7 @@ if TYPE_CHECKING: from zarr.abc.store import Store - from zarr.core.common import ZarrFormat + from zarr.types import ZarrFormat @pytest.fixture diff --git a/tests/test_metadata/test_v3.py b/tests/test_metadata/test_v3.py index 4f385afa6d..df40527ea7 100644 --- a/tests/test_metadata/test_v3.py +++ b/tests/test_metadata/test_v3.py @@ -27,7 +27,7 @@ from typing import Any from zarr.abc.codec import Codec - from zarr.core.common import JSON + from zarr.core.types import JSON from zarr.core.metadata.v3 import ( diff --git a/tests/test_properties.py b/tests/test_properties.py index 705cfd1b59..2938df44d7 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -7,6 +7,7 @@ from numpy.testing import assert_array_equal from zarr.core.buffer import default_buffer_prototype +from zarr.core.types import ZARR_JSON, ZARRAY_JSON pytest.importorskip("hypothesis") @@ -15,9 +16,9 @@ from hypothesis import assume, given, settings from zarr.abc.store import Store -from zarr.core.common import ZARR_JSON, ZARRAY_JSON, ZATTRS_JSON from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata from zarr.core.sync import sync +from zarr.core.types import ZATTRS_JSON from zarr.testing.strategies import ( array_metadata, arrays, diff --git a/tests/test_store/test_core.py b/tests/test_store/test_core.py index a3850de90f..04dd53dcb3 100644 --- a/tests/test_store/test_core.py +++ b/tests/test_store/test_core.py @@ -6,7 +6,7 @@ import zarr from zarr import Group -from zarr.core.common import AccessModeLiteral, ZarrFormat +from zarr.core.types import AccessModeLiteral from zarr.storage import FsspecStore, LocalStore, MemoryStore, StoreLike, StorePath, ZipStore from zarr.storage._common import contains_array, contains_group, make_store_path from zarr.storage._utils import ( @@ -16,6 +16,7 @@ _relativize_path, normalize_path, ) +from zarr.types import ZarrFormat @pytest.fixture( diff --git a/tests/test_store/test_fsspec.py b/tests/test_store/test_fsspec.py index 82a96b5d1e..e931dae61d 100644 --- a/tests/test_store/test_fsspec.py +++ b/tests/test_store/test_fsspec.py @@ -27,7 +27,7 @@ import botocore.client import s3fs - from zarr.core.common import JSON + from zarr.core.types import JSON # Warning filter due to https://github.com/boto/boto3/issues/3889 diff --git a/tests/test_store/test_memory.py b/tests/test_store/test_memory.py index 0b6bae757d..3149e2fa15 100644 --- a/tests/test_store/test_memory.py +++ b/tests/test_store/test_memory.py @@ -15,7 +15,7 @@ from zarr.testing.utils import gpu_test if TYPE_CHECKING: - from zarr.core.common import ZarrFormat + from zarr.types import ZarrFormat # TODO: work out where this warning is coming from and fix it