Skip to content

zarr_metadata.v2

zarr_metadata.v2

Zarr v2 metadata types, and the front door to the v2 definitions.

Each document type is in the submodule for its node or file: array (.zarray), group (.zgroup), attributes (.zattrs) and consolidated (.zmetadata). The codecs and data types are in codec and data_type, and the v2 kinds and scope are in definition.

This module also exports every v2 definition (GZIP_CODEC_V2, FLOAT_DATA_TYPE_V2, ...), the scope CORE_V2, and the scope class ZarrV2Context, so that one import builds or updates a scope. Each is the same object as in its own submodule, where a definition's configuration types and constants are.

zarr_metadata.v2.array

Zarr v2 array metadata types.

ZARR_V2_ARRAY_DIMENSION_SEPARATOR module-attribute

ZARR_V2_ARRAY_DIMENSION_SEPARATOR: Final = ('.', '/')

Tuple of permitted values for the dimension_separator field of v2 array metadata.

ZARR_V2_ARRAY_METADATA_STORE_KEY module-attribute

ZARR_V2_ARRAY_METADATA_STORE_KEY: Final[
    ZarrV2ArrayMetadataStoreKey
] = ".zarray"

The store key a v2 array's metadata document is persisted under.

ZARR_V2_ARRAY_ORDER module-attribute

ZARR_V2_ARRAY_ORDER: Final = ('C', 'F')

Tuple of permitted values for the order field of v2 array metadata.

ZarrV2ArrayDimensionSeparator module-attribute

ZarrV2ArrayDimensionSeparator = Literal['.', '/']

Literal type of permitted values for the dimension_separator field of v2 array metadata.

"." (legacy default) joins chunk grid coordinates as 0.0, 0.1, ... "/" joins them as 0/0, 0/1, ... yielding nested directories.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

ZarrV2ArrayMetadataStoreKey module-attribute

ZarrV2ArrayMetadataStoreKey = Literal['.zarray']

Literal type of the store key holding a v2 array's metadata document.

ZarrV2ArrayOrder module-attribute

ZarrV2ArrayOrder = Literal['C', 'F']

Literal type of permitted values for the order field of v2 array metadata.

"C" (row-major) or "F" (column-major) — the in-chunk byte layout.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

__all__ module-attribute

__all__ = [
    "ZARR_V2_ARRAY_DIMENSION_SEPARATOR",
    "ZARR_V2_ARRAY_METADATA_STORE_KEY",
    "ZARR_V2_ARRAY_ORDER",
    "ZarrV2ArrayDimensionSeparator",
    "ZarrV2ArrayMetadataJSON",
    "ZarrV2ArrayMetadataStoreKey",
    "ZarrV2ArrayOrder",
    "ZarrV2ZArrayJSON",
]

ZarrV2ArrayMetadataJSON

Bases: TypedDict

Zarr v2 array metadata document, in-memory merged form.

Models the union of .zarray (the spec-defined fields, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L51-L92) and .zattrs (user attributes, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L323-L330). On disk, attributes live in a sibling .zattrs file and are not part of .zarray; this type folds them in as the attributes field so a single TypedDict represents the complete in-memory state of a v2 array node. Consumers that read or write a real .zarray file should split / merge attributes accordingly, or use ZarrV2ZArrayJSON (strict on-disk) plus ZarrV2ZAttrsJSON directly.

The type is open: other keys "SHOULD NOT be present ... and SHOULD be ignored by implementations" (https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L91-L92), and each other member is a JSON value.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

Source code in src/zarr_metadata/v2/array.py
class ZarrV2ArrayMetadataJSON(TypedDict, extra_items=JSONValue):
    """
    Zarr v2 array metadata document, in-memory merged form.

    Models the union of `.zarray` (the spec-defined fields, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L51-L92)
    and `.zattrs` (user attributes, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L323-L330). On disk, attributes live in a sibling `.zattrs` file
    and are not part of `.zarray`; this type folds them in as the
    `attributes` field so a single TypedDict represents the complete
    in-memory state of a v2 array node. Consumers that read or write a
    real `.zarray` file should split / merge `attributes` accordingly,
    or use `ZarrV2ZArrayJSON` (strict on-disk) plus `ZarrV2ZAttrsJSON` directly.

    The type is open: other keys "SHOULD NOT be present ... and SHOULD be ignored by
    implementations" (https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L91-L92), and each
    other member is a JSON value.

    See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html
    """

    zarr_format: Literal[2]
    shape: tuple[Annotated[int, Ge(0)], ...]
    chunks: tuple[Annotated[int, Ge(0)], ...]
    dtype: ZarrV2DataTypeMetadata
    compressor: ZarrV2CodecMetadata | None
    fill_value: JSONValue
    order: ZarrV2ArrayOrder
    filters: tuple[ZarrV2CodecMetadata, ...] | None
    dimension_separator: NotRequired[ZarrV2ArrayDimensionSeparator]
    attributes: NotRequired[Mapping[str, JSONValue]]
    """User attributes from the sibling `.zattrs` file (not part of `.zarray`).

    See the class docstring for the rationale behind the merged representation.
    """

attributes instance-attribute

User attributes from the sibling .zattrs file (not part of .zarray).

See the class docstring for the rationale behind the merged representation.

chunks instance-attribute

chunks: tuple[Annotated[int, Ge(0)], ...]

compressor instance-attribute

compressor: ZarrV2CodecMetadata | None

dimension_separator instance-attribute

dtype instance-attribute

fill_value instance-attribute

fill_value: JSONValue

filters instance-attribute

filters: tuple[ZarrV2CodecMetadata, ...] | None

order instance-attribute

shape instance-attribute

shape: tuple[Annotated[int, Ge(0)], ...]

zarr_format instance-attribute

zarr_format: Literal[2]

ZarrV2ZArrayJSON

Bases: TypedDict

On-disk .zarray file content.

Strict shape of the JSON document persisted at <path>/.zarray for a v2 array. User attributes live in a sibling .zattrs file and are NOT part of this type; see ZarrV2ZAttrsJSON.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

Source code in src/zarr_metadata/v2/array.py
class ZarrV2ZArrayJSON(TypedDict):
    """
    On-disk `.zarray` file content.

    Strict shape of the JSON document persisted at `<path>/.zarray` for
    a v2 array. User attributes live in a sibling `.zattrs` file and are
    NOT part of this type; see `ZarrV2ZAttrsJSON`.

    See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html
    """

    zarr_format: Literal[2]
    shape: tuple[Annotated[int, Ge(0)], ...]
    chunks: tuple[Annotated[int, Ge(0)], ...]
    dtype: ZarrV2DataTypeMetadata
    compressor: ZarrV2CodecMetadata | None
    fill_value: JSONValue
    order: ZarrV2ArrayOrder
    filters: tuple[ZarrV2CodecMetadata, ...] | None
    dimension_separator: NotRequired[ZarrV2ArrayDimensionSeparator]

chunks instance-attribute

chunks: tuple[Annotated[int, Ge(0)], ...]

compressor instance-attribute

compressor: ZarrV2CodecMetadata | None

dimension_separator instance-attribute

dtype instance-attribute

fill_value instance-attribute

fill_value: JSONValue

filters instance-attribute

filters: tuple[ZarrV2CodecMetadata, ...] | None

order instance-attribute

shape instance-attribute

shape: tuple[Annotated[int, Ge(0)], ...]

zarr_format instance-attribute

zarr_format: Literal[2]

zarr_metadata.v2.group

Zarr v2 group metadata types.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

ZARR_V2_GROUP_METADATA_STORE_KEY module-attribute

ZARR_V2_GROUP_METADATA_STORE_KEY: Final[
    ZarrV2GroupMetadataStoreKey
] = ".zgroup"

The store key a v2 group's metadata document is persisted under.

ZarrV2GroupMetadataStoreKey module-attribute

ZarrV2GroupMetadataStoreKey = Literal['.zgroup']

Literal type of the store key holding a v2 group's metadata document.

__all__ module-attribute

__all__ = [
    "ZARR_V2_GROUP_METADATA_STORE_KEY",
    "ZarrV2GroupMetadataJSON",
    "ZarrV2GroupMetadataStoreKey",
    "ZarrV2ZGroupJSON",
]

ZarrV2GroupMetadataJSON

Bases: TypedDict

Zarr v2 group metadata document, in-memory merged form.

Models the union of .zgroup (the spec-defined zarr_format field, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L306-L313) and .zattrs (user attributes, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L323-L330). On disk these are persisted as two separate files; this type folds them so a single TypedDict represents the complete in-memory state of a v2 group node. Consumers that read or write the real on-disk files should use ZarrV2ZGroupJSON (strict .zgroup) plus ZarrV2ZAttrsJSON directly.

The type is closed: .zgroup holds no other keys ("Other keys MUST NOT be present", https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L313), and attributes is the only member folded in.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

Source code in src/zarr_metadata/v2/group.py
class ZarrV2GroupMetadataJSON(TypedDict, closed=True):
    """
    Zarr v2 group metadata document, in-memory merged form.

    Models the union of `.zgroup` (the spec-defined `zarr_format` field,
    https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L306-L313) and `.zattrs` (user attributes, https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L323-L330). On disk these are persisted as two
    separate files; this type folds them so a single TypedDict represents
    the complete in-memory state of a v2 group node. Consumers that read
    or write the real on-disk files should use `ZarrV2ZGroupJSON` (strict
    `.zgroup`) plus `ZarrV2ZAttrsJSON` directly.

    The type is closed: `.zgroup` holds no other keys ("Other keys MUST NOT be present",
    https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L313),
    and `attributes` is the only member folded in.

    See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html
    """

    zarr_format: Literal[2]
    attributes: NotRequired[Mapping[str, JSONValue]]

attributes instance-attribute

zarr_format instance-attribute

zarr_format: Literal[2]

ZarrV2ZGroupJSON

Bases: TypedDict

On-disk .zgroup file content.

Strict shape of the JSON document persisted at <path>/.zgroup for a v2 group. The spec defines exactly one field and forbids others. User attributes live in a sibling .zattrs file and are NOT part of this type; see ZarrV2ZAttrsJSON. https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L306-L313

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

Source code in src/zarr_metadata/v2/group.py
class ZarrV2ZGroupJSON(TypedDict, closed=True):
    """
    On-disk `.zgroup` file content.

    Strict shape of the JSON document persisted at `<path>/.zgroup` for
    a v2 group. The spec defines exactly one field and forbids others. User
    attributes live in a sibling `.zattrs` file and are NOT part of this
    type; see `ZarrV2ZAttrsJSON`.
      https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L306-L313

    See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html
    """

    zarr_format: Literal[2]

zarr_format instance-attribute

zarr_format: Literal[2]

zarr_metadata.v2.attributes

Zarr v2 user-attributes file content.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

ZARR_V2_ATTRIBUTES_STORE_KEY module-attribute

ZARR_V2_ATTRIBUTES_STORE_KEY: Final[
    ZarrV2AttributesStoreKey
] = ".zattrs"

The store key a v2 node's user attributes are persisted under.

Shared by arrays and groups: both node types keep their attributes in a sibling .zattrs file.

ZarrV2AttributesStoreKey module-attribute

ZarrV2AttributesStoreKey = Literal['.zattrs']

Literal type of the store key holding a v2 node's user attributes.

ZarrV2ZAttrsJSON module-attribute

ZarrV2ZAttrsJSON = Mapping[str, JSONValue]

On-disk .zattrs file content.

A JSON object holding user-defined attributes for a v2 array or group. Spec-defined keys for arrays / groups live in sibling .zarray / .zgroup files (modeled by ZarrV2ZArrayJSON / ZarrV2ZGroupJSON). This type does not constrain the keys or values of the attributes mapping. https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L323-L330

__all__ module-attribute

__all__ = [
    "ZARR_V2_ATTRIBUTES_STORE_KEY",
    "ZarrV2AttributesStoreKey",
    "ZarrV2ZAttrsJSON",
]

zarr_metadata.v2.codec

Zarr v2 codecs: the configuration shape, and one definition per numcodecs id that this package models.

In v2, compressors and filters are numcodecs configuration dicts: a required id field naming the codec, plus codec-specific parameters.

Each codec's definition and parameter TypedDict are in its submodule (checksum, compression, filters, vlen). This module holds the configuration shape and CODECS_V2, the tuple of every definition.

__all__ module-attribute

__all__ = ['CODECS_V2', 'ZarrV2CodecMetadata']

ZarrV2CodecMetadata

Bases: TypedDict

A numcodecs configuration dict, used as a v2 compressor or filter.

The required id field names the codec; codec-specific parameters (e.g. cname, clevel for blosc) appear as extra fields.

See the "compressor" and "filters" sections of https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html

Source code in src/zarr_metadata/v2/_field_json.py
class ZarrV2CodecMetadata(TypedDict, extra_items=JSONValue):
    """
    A numcodecs configuration dict, used as a v2 compressor or filter.

    The required `id` field names the codec; codec-specific parameters
    (e.g. `cname`, `clevel` for blosc) appear as extra fields.

    See the "compressor" and "filters" sections of
    https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html
    """

    id: str

id instance-attribute

id: str

zarr_metadata.v2.codec.checksum

The v2 checksums that numcodecs 0.16 configures: crc32, crc32c, adler32 and fletcher32.

ADLER32_CODEC_V2 module-attribute

ADLER32_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="adler32",
    configuration=ZarrV2Checksum32Parameters,
    canonical=_checksum_canonical,
)

numcodecs.Adler32.

CRC32C_CODEC_V2 module-attribute

CRC32C_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="crc32c",
    configuration=ZarrV2Checksum32Parameters,
    canonical=_crc32c_canonical,
)

numcodecs.CRC32C. Its location defaults to the end.

CRC32_CODEC_V2 module-attribute

CRC32_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="crc32",
    configuration=ZarrV2Checksum32Parameters,
    canonical=_checksum_canonical,
)

numcodecs.CRC32.

FLETCHER32_CODEC_V2 module-attribute

FLETCHER32_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="fletcher32", configuration=EmptyConfiguration
)

numcodecs.Fletcher32. It has no configuration.

__all__ module-attribute

__all__ = [
    "ADLER32_CODEC_V2",
    "CRC32C_CODEC_V2",
    "CRC32_CODEC_V2",
    "FLETCHER32_CODEC_V2",
    "ZarrV2Checksum32Parameters",
]

ZarrV2Checksum32Parameters

Bases: TypedDict

numcodecs.CRC32(location=None) and the other 32-bit checksums. location is where the checksum is placed. When it is omitted or null, numcodecs places it at the start for crc32 and adler32, and at the end for crc32c.

Source code in src/zarr_metadata/v2/codec/checksum.py
class ZarrV2Checksum32Parameters(TypedDict, closed=True):
    """`numcodecs.CRC32(location=None)` and the other 32-bit checksums. `location` is where the checksum is placed. When it is omitted or null, numcodecs places it at the start for crc32 and adler32, and at the end for crc32c."""

    location: NotRequired[ReadOnly[Literal["start", "end"] | None]]

location instance-attribute

location: NotRequired[
    ReadOnly[Literal["start", "end"] | None]
]

zarr_metadata.v2.codec.compression

The v2 compressors that numcodecs 0.16 configures: zlib, gzip, bz2, lzma, blosc, zstd and lz4.

Each parameter that numcodecs gives a default is optional. numcodecs writes the full object with get_config(). The canonical form of each codec fills in those defaults, so a configuration that leaves out a parameter and one that writes its default are one codec.

BLOSC_CODEC_V2 module-attribute

BLOSC_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="blosc",
    configuration=ZarrV2BloscParameters,
    canonical=_blosc_canonical,
)

numcodecs.Blosc.

BZ2_CODEC_V2 module-attribute

BZ2_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="bz2",
    configuration=ZarrV2Bz2Parameters,
    canonical=_bz2_canonical,
)

numcodecs.BZ2.

GZIP_CODEC_V2 module-attribute

GZIP_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="gzip",
    configuration=ZarrV2GzipParameters,
    canonical=_gzip_canonical,
)

numcodecs.GZip.

LZ4_CODEC_V2 module-attribute

LZ4_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="lz4",
    configuration=ZarrV2Lz4Parameters,
    canonical=_lz4_canonical,
)

numcodecs.LZ4.

LZMA_CODEC_V2 module-attribute

LZMA_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="lzma",
    configuration=ZarrV2LzmaParameters,
    canonical=_lzma_canonical,
)

numcodecs.LZMA.

ZLIB_CODEC_V2 module-attribute

ZLIB_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="zlib",
    configuration=ZarrV2ZlibParameters,
    canonical=_zlib_canonical,
)

numcodecs.Zlib.

ZSTD_CODEC_V2 module-attribute

ZSTD_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="zstd",
    configuration=ZarrV2ZstdParameters,
    canonical=_zstd_canonical,
)

numcodecs.Zstd.

ZarrV2BloscCName module-attribute

ZarrV2BloscCName = Literal[
    "blosclz", "lz4", "lz4hc", "snappy", "zlib", "zstd"
]

The compressors inside Blosc.

ZarrV2CompressionLevel module-attribute

ZarrV2CompressionLevel = Annotated[
    int, Interval(ge=-1, le=9)
]

A zlib-style compression level: 0 to 9, or -1 for zlib's default. numcodecs writes the level as given.

__all__ module-attribute

__all__ = [
    "BLOSC_CODEC_V2",
    "BZ2_CODEC_V2",
    "GZIP_CODEC_V2",
    "LZ4_CODEC_V2",
    "LZMA_CODEC_V2",
    "ZLIB_CODEC_V2",
    "ZSTD_CODEC_V2",
    "ZarrV2BloscCName",
    "ZarrV2BloscParameters",
    "ZarrV2Bz2Parameters",
    "ZarrV2CompressionLevel",
    "ZarrV2GzipParameters",
    "ZarrV2Lz4Parameters",
    "ZarrV2LzmaParameters",
    "ZarrV2ZlibParameters",
    "ZarrV2ZstdParameters",
]

ZarrV2BloscParameters

Bases: TypedDict

numcodecs.Blosc(cname='lz4', clevel=5, shuffle=1, blocksize=0, typesize=None).

For shuffle, -1 is automatic, 0 is none, 1 is byte shuffle, and 2 is bit shuffle. numcodecs writes a shuffle given as True or False as it was given, and reads it as 1 or 0. A blocksize of 0 lets Blosc choose the block size. numcodecs reads any blocksize that fits in a C int, negative ones included. Blosc reads any blocksize other than 0 as a size in bytes, and raises one below its minimum of 128 bytes to that minimum, so a negative blocksize does not mean automatic.

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2BloscParameters(TypedDict, closed=True):
    """`numcodecs.Blosc(cname='lz4', clevel=5, shuffle=1, blocksize=0, typesize=None)`.

    For `shuffle`, -1 is automatic, 0 is none, 1 is byte shuffle, and 2 is
    bit shuffle. numcodecs writes a `shuffle` given as `True` or `False`
    as it was given, and reads it as 1 or 0. A `blocksize` of 0 lets Blosc
    choose the block size. numcodecs reads any `blocksize` that fits in a
    C `int`, negative ones included. Blosc reads any `blocksize` other
    than 0 as a size in bytes, and raises one below its minimum of 128
    bytes to that minimum, so a negative `blocksize` does not mean
    automatic.
    """

    cname: NotRequired[ReadOnly[ZarrV2BloscCName]]
    clevel: NotRequired[ReadOnly[Annotated[int, Interval(ge=0, le=9)]]]
    shuffle: NotRequired[ReadOnly[Literal[-1, 0, 1, 2] | bool]]
    blocksize: NotRequired[ReadOnly[_CInt]]
    typesize: NotRequired[ReadOnly[Annotated[int, Interval(ge=1, le=2**31 - 1)] | None]]

blocksize instance-attribute

blocksize: NotRequired[ReadOnly[_CInt]]

clevel instance-attribute

clevel: NotRequired[
    ReadOnly[Annotated[int, Interval(ge=0, le=9)]]
]

cname instance-attribute

cname: NotRequired[ReadOnly[ZarrV2BloscCName]]

shuffle instance-attribute

shuffle: NotRequired[ReadOnly[Literal[-1, 0, 1, 2] | bool]]

typesize instance-attribute

typesize: NotRequired[
    ReadOnly[
        Annotated[int, Interval(ge=1, le=2**31 - 1)]
        | None
    ]
]

ZarrV2Bz2Parameters

Bases: TypedDict

numcodecs.BZ2(level=1): 1 to 9.

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2Bz2Parameters(TypedDict, closed=True):
    """`numcodecs.BZ2(level=1)`: 1 to 9."""

    level: NotRequired[ReadOnly[Annotated[int, Interval(ge=1, le=9)]]]

level instance-attribute

level: NotRequired[
    ReadOnly[Annotated[int, Interval(ge=1, le=9)]]
]

ZarrV2GzipParameters

Bases: TypedDict

numcodecs.GZip(level=1).

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2GzipParameters(TypedDict, closed=True):
    """`numcodecs.GZip(level=1)`."""

    level: NotRequired[ReadOnly[ZarrV2CompressionLevel]]

level instance-attribute

ZarrV2Lz4Parameters

Bases: TypedDict

numcodecs.LZ4(acceleration=1). numcodecs passes acceleration to C as an int, and lz4 reads one below 1 as 1.

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2Lz4Parameters(TypedDict, closed=True):
    """`numcodecs.LZ4(acceleration=1)`. numcodecs passes `acceleration` to C as an `int`, and lz4 reads one below 1 as 1."""

    acceleration: NotRequired[ReadOnly[_CInt]]

acceleration instance-attribute

acceleration: NotRequired[ReadOnly[_CInt]]

ZarrV2LzmaParameters

Bases: TypedDict

numcodecs.LZMA(format=1, check=-1, preset=None, filters=None), with the parameters as the lzma module accepts them.

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2LzmaParameters(TypedDict, closed=True):
    """`numcodecs.LZMA(format=1, check=-1, preset=None, filters=None)`, with the parameters as the `lzma` module accepts them."""

    format: NotRequired[ReadOnly[Annotated[int, Interval(ge=0, le=3)]]]
    check: NotRequired[ReadOnly[int]]
    preset: NotRequired[ReadOnly[Annotated[int, Ge(0)] | None]]
    filters: NotRequired[ReadOnly[tuple[JSONValue, ...] | None]]

check instance-attribute

check: NotRequired[ReadOnly[int]]

filters instance-attribute

filters: NotRequired[ReadOnly[tuple[JSONValue, ...] | None]]

format instance-attribute

format: NotRequired[
    ReadOnly[Annotated[int, Interval(ge=0, le=3)]]
]

preset instance-attribute

preset: NotRequired[ReadOnly[Annotated[int, Ge(0)] | None]]

ZarrV2ZlibParameters

Bases: TypedDict

numcodecs.Zlib(level=1).

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2ZlibParameters(TypedDict, closed=True):
    """`numcodecs.Zlib(level=1)`."""

    level: NotRequired[ReadOnly[ZarrV2CompressionLevel]]

level instance-attribute

ZarrV2ZstdParameters

Bases: TypedDict

numcodecs.Zstd(level=0, checksum=False). Level 0 is zstd's default level, and negative levels give up compression ratio for speed. zstd clamps a level outside its own range, -131072 to 22, to that range, so numcodecs reads any level that fits in a C int.

Source code in src/zarr_metadata/v2/codec/compression.py
class ZarrV2ZstdParameters(TypedDict, closed=True):
    """`numcodecs.Zstd(level=0, checksum=False)`. Level 0 is zstd's default level, and negative levels give up compression ratio for speed. zstd clamps a level outside its own range, -131072 to 22, to that range, so numcodecs reads any level that fits in a C `int`."""

    level: NotRequired[ReadOnly[_CInt]]
    checksum: NotRequired[ReadOnly[bool]]

checksum instance-attribute

checksum: NotRequired[ReadOnly[bool]]

level instance-attribute

level: NotRequired[ReadOnly[_CInt]]

zarr_metadata.v2.codec.filters

The v2 filters that numcodecs 0.16 configures: shuffle, delta, fixedscaleoffset, quantize, bitround, astype and packbits.

A dtype parameter is a NumPy typestr, as numcodecs writes it. A parameter that numcodecs gives a default is optional, and the canonical form of each codec fills it in, as get_config() writes it. The canonical form writes each dtype parameter as NumPy spells it, as an array's dtype compares, so <i1 and |i1 are one parameter.

ASTYPE_CODEC_V2 module-attribute

ASTYPE_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="astype",
    configuration=ZarrV2AsTypeParameters,
    rules=dtype_parameter("encode_dtype", "decode_dtype"),
    canonical=_astype_canonical,
)

numcodecs.AsType.

BITROUND_CODEC_V2 module-attribute

BITROUND_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="bitround", configuration=ZarrV2BitRoundParameters
)

numcodecs.BitRound.

DELTA_CODEC_V2 module-attribute

DELTA_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="delta",
    configuration=ZarrV2DeltaParameters,
    rules=dtype_parameter("dtype", "astype"),
    canonical=_delta_canonical,
)

numcodecs.Delta.

FIXEDSCALEOFFSET_CODEC_V2 module-attribute

FIXEDSCALEOFFSET_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="fixedscaleoffset",
    configuration=ZarrV2FixedScaleOffsetParameters,
    rules=dtype_parameter("dtype", "astype"),
    canonical=_fixedscaleoffset_canonical,
)

numcodecs.FixedScaleOffset.

PACKBITS_CODEC_V2 module-attribute

PACKBITS_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="packbits", configuration=EmptyConfiguration
)

numcodecs.PackBits. It has no configuration.

QUANTIZE_CODEC_V2 module-attribute

QUANTIZE_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="quantize",
    configuration=ZarrV2QuantizeParameters,
    rules=dtype_parameter(
        "dtype", "astype", float_only=True
    ),
    canonical=_quantize_canonical,
)

numcodecs.Quantize.

SHUFFLE_CODEC_V2 module-attribute

SHUFFLE_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="shuffle",
    configuration=ZarrV2ShuffleParameters,
    canonical=_shuffle_canonical,
)

numcodecs.Shuffle.

__all__ module-attribute

__all__ = [
    "ASTYPE_CODEC_V2",
    "BITROUND_CODEC_V2",
    "DELTA_CODEC_V2",
    "FIXEDSCALEOFFSET_CODEC_V2",
    "PACKBITS_CODEC_V2",
    "QUANTIZE_CODEC_V2",
    "SHUFFLE_CODEC_V2",
    "ZarrV2AsTypeParameters",
    "ZarrV2BitRoundParameters",
    "ZarrV2DeltaParameters",
    "ZarrV2FixedScaleOffsetParameters",
    "ZarrV2QuantizeParameters",
    "ZarrV2ShuffleParameters",
]

ZarrV2AsTypeParameters

Bases: TypedDict

numcodecs.AsType(encode_dtype, decode_dtype).

Source code in src/zarr_metadata/v2/codec/filters.py
class ZarrV2AsTypeParameters(TypedDict, closed=True):
    """`numcodecs.AsType(encode_dtype, decode_dtype)`."""

    encode_dtype: ReadOnly[str]
    decode_dtype: ReadOnly[str]

decode_dtype instance-attribute

decode_dtype: ReadOnly[str]

encode_dtype instance-attribute

encode_dtype: ReadOnly[str]

ZarrV2BitRoundParameters

Bases: TypedDict

numcodecs.BitRound(keepbits).

Source code in src/zarr_metadata/v2/codec/filters.py
class ZarrV2BitRoundParameters(TypedDict, closed=True):
    """`numcodecs.BitRound(keepbits)`."""

    keepbits: ReadOnly[Annotated[int, Ge(0)]]

keepbits instance-attribute

keepbits: ReadOnly[Annotated[int, Ge(0)]]

ZarrV2DeltaParameters

Bases: TypedDict

numcodecs.Delta(dtype, astype=None). When astype is omitted or null, it equals dtype.

Source code in src/zarr_metadata/v2/codec/filters.py
class ZarrV2DeltaParameters(TypedDict, closed=True):
    """`numcodecs.Delta(dtype, astype=None)`. When `astype` is omitted or null, it equals `dtype`."""

    dtype: ReadOnly[str]
    astype: NotRequired[ReadOnly[str | None]]

astype instance-attribute

astype: NotRequired[ReadOnly[str | None]]

dtype instance-attribute

dtype: ReadOnly[str]

ZarrV2FixedScaleOffsetParameters

Bases: TypedDict

numcodecs.FixedScaleOffset(offset, scale, dtype, astype=None). When astype is omitted or null, it equals dtype.

Source code in src/zarr_metadata/v2/codec/filters.py
class ZarrV2FixedScaleOffsetParameters(TypedDict, closed=True):
    """`numcodecs.FixedScaleOffset(offset, scale, dtype, astype=None)`. When `astype` is omitted or null, it equals `dtype`."""

    offset: ReadOnly[float | int]
    scale: ReadOnly[float | int]
    dtype: ReadOnly[str]
    astype: NotRequired[ReadOnly[str | None]]

astype instance-attribute

astype: NotRequired[ReadOnly[str | None]]

dtype instance-attribute

dtype: ReadOnly[str]

offset instance-attribute

offset: ReadOnly[float | int]

scale instance-attribute

scale: ReadOnly[float | int]

ZarrV2QuantizeParameters

Bases: TypedDict

numcodecs.Quantize(digits, dtype, astype=None): dtype, and astype when present, name a float. When astype is omitted or null, it equals dtype.

digits is the number of decimal digits to keep, and may be negative. numcodecs computes 10.0 ** -digits and a power of two above it, which overflow a float outside -308 to 307.

Source code in src/zarr_metadata/v2/codec/filters.py
class ZarrV2QuantizeParameters(TypedDict, closed=True):
    """`numcodecs.Quantize(digits, dtype, astype=None)`: `dtype`, and `astype` when present, name a float. When `astype` is omitted or null, it equals `dtype`.

    `digits` is the number of decimal digits to keep, and may be negative.
    numcodecs computes `10.0 ** -digits` and a power of two above it, which
    overflow a float outside -308 to 307.
    """

    digits: ReadOnly[Annotated[int, Interval(ge=-308, le=307)]]
    dtype: ReadOnly[str]
    astype: NotRequired[ReadOnly[str | None]]

astype instance-attribute

astype: NotRequired[ReadOnly[str | None]]

digits instance-attribute

digits: ReadOnly[
    Annotated[int, Interval(ge=-308, le=307)]
]

dtype instance-attribute

dtype: ReadOnly[str]

ZarrV2ShuffleParameters

Bases: TypedDict

numcodecs.Shuffle(elementsize=4). An element size of 1 or less leaves the bytes as they are. numcodecs passes a larger one to C as a Py_ssize_t, so it is at most 2**63 - 1 on a 64-bit platform, and raises OverflowError for any other.

Source code in src/zarr_metadata/v2/codec/filters.py
class ZarrV2ShuffleParameters(TypedDict, closed=True):
    """`numcodecs.Shuffle(elementsize=4)`. An element size of 1 or less leaves the bytes as they are. numcodecs passes a larger one to C as a `Py_ssize_t`, so it is at most 2**63 - 1 on a 64-bit platform, and raises `OverflowError` for any other."""

    elementsize: NotRequired[ReadOnly[Annotated[int, Le(2**63 - 1)]]]

elementsize instance-attribute

elementsize: NotRequired[
    ReadOnly[Annotated[int, Le(2**63 - 1)]]
]

zarr_metadata.v2.codec.vlen

The v2 variable-length filters that numcodecs 0.16 configures: vlen-utf8, vlen-bytes and vlen-array.

VLEN_ARRAY_CODEC_V2 module-attribute

VLEN_ARRAY_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="vlen-array",
    configuration=ZarrV2VLenArrayParameters,
    rules=dtype_parameter("dtype"),
    canonical=_vlen_array_canonical,
)

numcodecs.VLenArray.

VLEN_BYTES_CODEC_V2 module-attribute

VLEN_BYTES_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="vlen-bytes", configuration=EmptyConfiguration
)

numcodecs.VLenBytes. It has no configuration.

VLEN_UTF8_CODEC_V2 module-attribute

VLEN_UTF8_CODEC_V2: Final = ZarrV2CodecDefinition(
    name="vlen-utf8", configuration=EmptyConfiguration
)

numcodecs.VLenUTF8. It has no configuration.

__all__ module-attribute

__all__ = [
    "VLEN_ARRAY_CODEC_V2",
    "VLEN_BYTES_CODEC_V2",
    "VLEN_UTF8_CODEC_V2",
    "ZarrV2VLenArrayParameters",
]

ZarrV2VLenArrayParameters

Bases: TypedDict

numcodecs.VLenArray(dtype): the element type of each array.

Source code in src/zarr_metadata/v2/codec/vlen.py
class ZarrV2VLenArrayParameters(TypedDict, closed=True):
    """`numcodecs.VLenArray(dtype)`: the element type of each array."""

    dtype: ReadOnly[str]

dtype instance-attribute

dtype: ReadOnly[str]

zarr_metadata.v2.consolidated

Zarr v2 consolidated metadata (.zmetadata file).

This module models the de-facto .zmetadata file used by the reference Python implementation of Zarr v2. This is NOT a spec artifact. There is no Zarr v2 specification that defines .zmetadata; it is a canonical-implementation convention.

ZARR_V2_CONSOLIDATED_METADATA_STORE_KEY module-attribute

ZARR_V2_CONSOLIDATED_METADATA_STORE_KEY: Final[
    ZarrV2ConsolidatedMetadataStoreKey
] = ".zmetadata"

The store key a v2 hierarchy's consolidated metadata is persisted under.

Like the document it names, this is a reference-implementation convention rather than a spec artifact; see the module docstring.

ZarrV2ConsolidatedMetadataStoreKey module-attribute

ZarrV2ConsolidatedMetadataStoreKey = Literal['.zmetadata']

Literal type of the store key holding a v2 hierarchy's consolidated metadata.

__all__ module-attribute

__all__ = [
    "ZARR_V2_CONSOLIDATED_METADATA_STORE_KEY",
    "ZarrV2ConsolidatedMetadataJSON",
    "ZarrV2ConsolidatedMetadataStoreKey",
]

ZarrV2ConsolidatedMetadataJSON

Bases: TypedDict

.zmetadata file contents.

The metadata map uses flat path keys ("foo/bar/.zarray", "foo/.zattrs", etc.) pointing to the JSON contents of the file at that path. The keys include the filename suffix, not just the node path; the value's shape is determined by which file the key points at:

  • <path>/.zarray -> ZarrV2ZArrayJSON
  • <path>/.zgroup -> ZarrV2ZGroupJSON
  • <path>/.zattrs -> ZarrV2ZAttrsJSON

The TypedDict cannot discriminate the value shape on the key suffix at the type level; consumers should narrow at runtime by inspecting key.endswith(".zarray") etc.

Source code in src/zarr_metadata/v2/consolidated.py
class ZarrV2ConsolidatedMetadataJSON(TypedDict):
    """
    `.zmetadata` file contents.

    The `metadata` map uses flat path keys (`"foo/bar/.zarray"`,
    `"foo/.zattrs"`, etc.) pointing to the JSON contents of the file at
    that path. The keys include the filename suffix, not just the node
    path; the value's shape is determined by which file the key points at:

    - `<path>/.zarray` -> `ZarrV2ZArrayJSON`
    - `<path>/.zgroup` -> `ZarrV2ZGroupJSON`
    - `<path>/.zattrs` -> `ZarrV2ZAttrsJSON`

    The TypedDict cannot discriminate the value shape on the key suffix
    at the type level; consumers should narrow at runtime by inspecting
    `key.endswith(".zarray")` etc.
    """

    zarr_consolidated_format: Literal[1]
    metadata: Mapping[str, ZarrV2ZArrayJSON | ZarrV2ZGroupJSON | ZarrV2ZAttrsJSON]

metadata instance-attribute

zarr_consolidated_format instance-attribute

zarr_consolidated_format: Literal[1]

zarr_metadata.v2.definition

Read Zarr v2 fields against their definitions. This is the public module for v2 reading.

A v2 array document has two kinds of field: its dtype, and the codecs in compressor and filters. Zarr v2 has no extension registry, but it still has a scope: the data types that zarr-python 2.x writes (one definition per NumPy family), and the codecs that numcodecs 0.16 configures (one per id that this package models). CORE_V2 is that scope. To read one field in it, call zarr_metadata.definition.resolve with the field's kind, as for a v3 field: resolve("<f4", ZarrV2DataTypeDefinition, CORE_V2) returns an AcceptedField, UnclaimedField or RefusedField, and every problem. ZarrV2Context is the class of a v2 scope. It has a slot for each kind of v2 field, data_types and codecs, and shares update, union and claimant with the v3 scope. A v2 reader rejects a v3 scope with TypeError.

A dtype reads as its family, and the byte order, size and unit of the typestr are its configuration. For example, <f4 is float with {"byteorder": "<", "itemsize": 4}, and its simplest spelling is the typestr again. A records array reads as struct, and the type of each record is a nested field. A codec is read by its id, and its other members are its parameters. A typestr with a type code that the spec does not list, or a codec id that the package does not model, reads as an UnclaimedField.

CORE_V2 module-attribute

CORE_V2: Final = ZarrV2Context(
    data_types=DATA_TYPES_V2, codecs=CODECS_V2
)

The data types that zarr-python 2.x writes and the codecs that numcodecs 0.16 configures.

ZarrV2DataTypeField module-attribute

ZarrV2DataTypeField = TypeAliasType(
    "ZarrV2DataTypeField", ZarrV2DataTypeMetadata
)

A member that holds a v2 dtype: a document's dtype, or the type of a struct record. It is read in the same scope as its container.

ZarrV2Kind module-attribute

A definition of a kind of v2 field.

ZarrV2CodecDefinition dataclass

Bases: Definition[C]

A v2 codec: a numcodecs id, and the TypedDict that describes its parameters.

A document writes {"id": name, **parameters}. The configuration of the definition is the parameters, read at the location of the field itself.

Source code in src/zarr_metadata/v2/_definition.py
@dataclass(frozen=True, kw_only=True, slots=True, repr=False)
class ZarrV2CodecDefinition(Definition[C], kind=True, format=2):
    """A v2 codec: a numcodecs id, and the TypedDict that describes its parameters.

    A document writes `{"id": name, **parameters}`. The configuration of
    the definition is the parameters, read at the location of the field
    itself.
    """

    label: ClassVar[str] = "v2 codec"

    @classmethod
    def _name_problem(cls, name: str, at: Loc) -> ValidationProblem | None:
        if len(name) != 0:
            return None
        return ValidationProblem(at, "expected a codec id, got ''", "invalid_value")

    @classmethod
    def _named_configuration(
        cls, value: object
    ) -> tuple[str | None, Mapping[str, object] | None, Problems]:
        if not is_object(value):
            return None, None, ()
        name = value.get("id")
        if not isinstance(name, str):
            return None, None, ()
        return (
            name,
            {key: item for key, item in value.items() if isinstance(key, str) and key != "id"},
            (),
        )

    @classmethod
    def _envelope_problems(cls, value: object) -> Problems:
        if not is_object(value):
            return (
                ValidationProblem(
                    (), "expected a codec configuration with a string 'id'", "invalid_type"
                ),
            )
        entry = value
        if "id" not in entry:
            return (ValidationProblem(("id",), "missing required key", "missing_key"),)
        if not isinstance(entry["id"], str):
            return (
                ValidationProblem(
                    ("id",),
                    f"expected a string codec id, got {shown(entry['id'])}",
                    "invalid_type",
                ),
            )
        bad = cls._name_problem(entry["id"], ("id",))
        return () if bad is None else (bad,)

    @classmethod
    def _envelope_json(cls, name: str, configuration: Mapping[str, JSONValue]) -> JSONValue:
        return {"id": name, **configuration}

    @classmethod
    def _configuration_loc(cls, loc: Loc) -> Loc:
        return loc

    @classmethod
    def _name_loc(cls, loc: Loc) -> Loc:
        return (*loc, "id")

label class-attribute

label: str = 'v2 codec'

The name of the kind in error messages, for example "codec".

ZarrV2Context

A scope that reads Zarr v2 documents. Every v2 reader takes one.

It implements Context, and has one slot for each kind of field a v2 document holds, as ZarrV2ContextSlots declares them: data_types, read from dtype, and codecs, read from compressor and filters. Each slot is a read-only mapping from name to definition. The constructor and update take, for each slot, an iterable of definitions or such a mapping, so one scope's slot can be given to another. A definition of another kind than its slot holds, and a key that is not its definition's name, raise TypeError, and two different definitions under one name in a slot raise ScopeConflictError. To replace a definition, or a whole slot, use update. ZarrV2Context() is the scope that claims nothing. Two scopes are equal when they file the same definitions in each slot, and equal scopes have equal hashes.

Source code in src/zarr_metadata/v2/_context.py
@final
class ZarrV2Context:
    """A scope that reads Zarr v2 documents. Every v2 reader takes one.

    It implements `Context`, and has one slot for each kind of field a v2
    document holds, as `ZarrV2ContextSlots` declares them: `data_types`,
    read from `dtype`, and `codecs`, read from `compressor` and `filters`.
    Each slot is a read-only mapping from name to definition. The
    constructor and `update` take, for each slot, an iterable of
    definitions or such a mapping, so one scope's slot can be given to
    another. A definition of another kind than its slot holds, and a key
    that is not its definition's name, raise `TypeError`, and two
    different definitions under one name in a slot raise
    `ScopeConflictError`. To replace a definition, or a whole slot, use
    `update`.
    `ZarrV2Context()` is the scope that claims nothing. Two scopes are
    equal when they file the same definitions in each slot, and equal
    scopes have equal hashes.
    """

    __slots__ = ("_tables",)

    kinds: ClassVar[Mapping[str, type[ZarrV2Kind]]] = slot_kinds(ZarrV2ContextSlots, is_v2_kind)
    """The kind of definition each slot holds, by slot, as `ZarrV2ContextSlots` declares them."""

    _tables: Tables

    def __init__(self, **slots: Unpack[ZarrV2ContextSlots]) -> None:
        self._tables = filed(self.kinds, slots, 2)

    @classmethod
    def _of(cls, tables: Tables) -> ZarrV2Context:
        """A scope of `tables`, which were filed for this class's slots."""
        context = object.__new__(cls)
        context._tables = tables
        return context

    @classmethod
    def _restored(cls, contents: Mapping[str, Iterable[Definition[Any]]]) -> ZarrV2Context:
        """A scope rebuilt from the definitions in each slot, as `__reduce__` gives them."""
        return cls._of(filed(cls.kinds, contents, 2))

    @property
    def zarr_format(self) -> Literal[2]:
        """The Zarr format of the documents this scope reads: 2."""
        return 2

    @property
    def data_types(self) -> Mapping[str, ZarrV2DataTypeDefinition[Any]]:
        """The data type definitions in scope, by the NumPy family each reads."""
        return self.definitions_of(ZarrV2DataTypeDefinition)

    @property
    def codecs(self) -> Mapping[str, ZarrV2CodecDefinition[Any]]:
        """The codec definitions in scope, by numcodecs id."""
        return self.definitions_of(ZarrV2CodecDefinition)

    def definitions_of(self, kind: type[_K]) -> Mapping[str, _K]:
        """The definitions of `kind` in scope, by the name each is filed under: the slot that holds `kind`. Raises `TypeError` for a kind of the other format."""
        return definitions_in(self._tables, kind)

    def claimant(self, kind: type[D], name: str) -> D | None:
        """The definition of `kind` in scope that reads `name` (a name as a document uses it), or None if there is none. Raises `TypeError` for a kind of the other format.

        This is the definition filed under the name that `filed_under`
        maps `name` to. That is `name` itself, except for raw bits, where
        `r16` is read by the definition of `r*`.
        """
        return claimant_in(self._tables, kind, name)

    def update(self, **slots: Unpack[ZarrV2ContextSlots]) -> ZarrV2Context:
        """This scope, with each slot given here holding only the definitions given for it. The other slots are kept.

        A slot can be given as a mapping from each definition's name to
        it, so a slot of this scope passes back in changed:
        `context.update(codecs={**context.codecs, "gzip": MY_GZIP})`
        replaces the gzip definition and keeps the other codecs, and
        `context.update(codecs=[*context.codecs.values(), MY_CODEC])` adds
        one, raising `ScopeConflictError` if the scope already files
        another definition under its name.
        """
        return self._of(updated(self._tables, self.kinds, slots, 2))

    def union(self, *others: ZarrV2Context) -> ZarrV2Context:
        """The smallest scope that files everything this scope and each of `others` file.

        Raises `ScopeConflictError` when two of them file different
        definitions under one name in a slot. To replace a definition on
        purpose, use `update`. Raises `TypeError` for a scope of another
        format.
        """
        refuse_others(others, ZarrV2Context)
        return self._of(
            joined_tables(self.kinds, [self._tables, *(other._tables for other in others)])
        )

    def __repr__(self) -> str:
        # Keep this short, because it appears in signatures as a default
        # argument. A full repr would list every definition, and `help` on a
        # validator would run to pages.
        count = sum(len(table) for table in self._tables.values())
        return f"ZarrV2Context(<{count} definitions>)"

    def __reduce__(self) -> tuple[object, tuple[dict[str, tuple[Definition[Any], ...]]]]:
        # A scope is defined by the definitions in its slots, so pickle it as
        # them. This lets a scope go to another process along with the
        # documents it will read there.
        return (type(self)._restored, (slot_contents(self._tables, self.kinds),))

    def __copy__(self) -> ZarrV2Context:
        return self

    def __deepcopy__(self, memo: dict[int, object]) -> ZarrV2Context:
        # A scope is immutable, so a copy can be the same object.
        return self

    def __eq__(self, other: object) -> bool:
        if not isinstance(other, ZarrV2Context):
            return NotImplemented
        return self._tables == other._tables

    def __hash__(self) -> int:
        return hash((ZarrV2Context, tables_key(self._tables)))

codecs property

The codec definitions in scope, by numcodecs id.

data_types property

The data type definitions in scope, by the NumPy family each reads.

kinds class-attribute

kinds: Mapping[str, type[ZarrV2Kind]] = slot_kinds(
    ZarrV2ContextSlots, is_v2_kind
)

The kind of definition each slot holds, by slot, as ZarrV2ContextSlots declares them.

zarr_format property

zarr_format: Literal[2]

The Zarr format of the documents this scope reads: 2.

claimant

claimant(kind: type[D], name: str) -> D | None

The definition of kind in scope that reads name (a name as a document uses it), or None if there is none. Raises TypeError for a kind of the other format.

This is the definition filed under the name that filed_under maps name to. That is name itself, except for raw bits, where r16 is read by the definition of r*.

Source code in src/zarr_metadata/v2/_context.py
def claimant(self, kind: type[D], name: str) -> D | None:
    """The definition of `kind` in scope that reads `name` (a name as a document uses it), or None if there is none. Raises `TypeError` for a kind of the other format.

    This is the definition filed under the name that `filed_under`
    maps `name` to. That is `name` itself, except for raw bits, where
    `r16` is read by the definition of `r*`.
    """
    return claimant_in(self._tables, kind, name)

definitions_of

definitions_of(kind: type[_K]) -> Mapping[str, _K]

The definitions of kind in scope, by the name each is filed under: the slot that holds kind. Raises TypeError for a kind of the other format.

Source code in src/zarr_metadata/v2/_context.py
def definitions_of(self, kind: type[_K]) -> Mapping[str, _K]:
    """The definitions of `kind` in scope, by the name each is filed under: the slot that holds `kind`. Raises `TypeError` for a kind of the other format."""
    return definitions_in(self._tables, kind)

union

union(*others: ZarrV2Context) -> ZarrV2Context

The smallest scope that files everything this scope and each of others file.

Raises ScopeConflictError when two of them file different definitions under one name in a slot. To replace a definition on purpose, use update. Raises TypeError for a scope of another format.

Source code in src/zarr_metadata/v2/_context.py
def union(self, *others: ZarrV2Context) -> ZarrV2Context:
    """The smallest scope that files everything this scope and each of `others` file.

    Raises `ScopeConflictError` when two of them file different
    definitions under one name in a slot. To replace a definition on
    purpose, use `update`. Raises `TypeError` for a scope of another
    format.
    """
    refuse_others(others, ZarrV2Context)
    return self._of(
        joined_tables(self.kinds, [self._tables, *(other._tables for other in others)])
    )

update

update(
    **slots: Unpack[ZarrV2ContextSlots],
) -> ZarrV2Context

This scope, with each slot given here holding only the definitions given for it. The other slots are kept.

A slot can be given as a mapping from each definition's name to it, so a slot of this scope passes back in changed: context.update(codecs={**context.codecs, "gzip": MY_GZIP}) replaces the gzip definition and keeps the other codecs, and context.update(codecs=[*context.codecs.values(), MY_CODEC]) adds one, raising ScopeConflictError if the scope already files another definition under its name.

Source code in src/zarr_metadata/v2/_context.py
def update(self, **slots: Unpack[ZarrV2ContextSlots]) -> ZarrV2Context:
    """This scope, with each slot given here holding only the definitions given for it. The other slots are kept.

    A slot can be given as a mapping from each definition's name to
    it, so a slot of this scope passes back in changed:
    `context.update(codecs={**context.codecs, "gzip": MY_GZIP})`
    replaces the gzip definition and keeps the other codecs, and
    `context.update(codecs=[*context.codecs.values(), MY_CODEC])` adds
    one, raising `ScopeConflictError` if the scope already files
    another definition under its name.
    """
    return self._of(updated(self._tables, self.kinds, slots, 2))

ZarrV2ContextSlots

Bases: TypedDict

The definitions in each slot of a v2 scope, as ZarrV2Context and its update take them.

This is where a v2 scope's slots are declared: each key is a slot, and its value the definitions of the kind that slot holds, as an iterable of them or as a mapping from each one's name to it. ZarrV2Context.kinds is read from these annotations, so a type checker checks every slot a caller names, and every definition given in it.

Source code in src/zarr_metadata/v2/_context.py
class ZarrV2ContextSlots(TypedDict, total=False, closed=True):
    """The definitions in each slot of a v2 scope, as `ZarrV2Context` and its `update` take them.

    This is where a v2 scope's slots are declared: each key is a slot,
    and its value the definitions of the kind that slot holds, as an
    iterable of them or as a mapping from each one's name to it.
    `ZarrV2Context.kinds` is read from these annotations, so a type
    checker checks every slot a caller names, and every definition given
    in it.
    """

    data_types: (
        Iterable[ZarrV2DataTypeDefinition[Any]] | Mapping[str, ZarrV2DataTypeDefinition[Any]]
    )
    """Data types, read from `dtype`."""
    codecs: Iterable[ZarrV2CodecDefinition[Any]] | Mapping[str, ZarrV2CodecDefinition[Any]]
    """Codecs, read from `compressor` and `filters`."""

codecs instance-attribute

Codecs, read from compressor and filters.

data_types instance-attribute

Data types, read from dtype.

ZarrV2DataTypeDefinition dataclass

Bases: WithFillValue[C]

A v2 data type: one family of NumPy types, and the fill value an array of that family takes.

The definition is filed under the family, such as float, and is read for every typestr of the family. The byte order, size and unit of the typestr are its configuration. The rules state which of those the family accepts. struct is read for an array of field records, with the configuration {"fields": records}. A problem in a record is therefore located under fields, for example at ("dtype", "fields", 0, 1) for the type of the first record.

Source code in src/zarr_metadata/v2/_definition.py
@dataclass(frozen=True, kw_only=True, slots=True, repr=False)
class ZarrV2DataTypeDefinition(WithFillValue[C], kind=True, format=2):
    """A v2 data type: one family of NumPy types, and the fill value an array of that family takes.

    The definition is filed under the family, such as `float`, and is
    read for every typestr of the family. The byte order, size and unit
    of the typestr are its configuration. The rules state which of those
    the family accepts. `struct` is read for an array of field records,
    with the configuration `{"fields": records}`. A problem in a record
    is therefore located under `fields`, for example at
    `("dtype", "fields", 0, 1)` for the type of the first record.
    """

    label: ClassVar[str] = "v2 data type"
    field_aliases: ClassVar[tuple[TypeAliasType, ...]] = (ZarrV2DataTypeField,)

    def _refusal(self) -> str | None:
        if parse_typestr(self.name) is not None:
            return (
                f"{self.name!r} is how a document writes one type of a family, which reads as "
                "the family; define the family"
            )
        # Use the explicit form, not a bare `super()`, because a dataclass with slots is rebuilt.
        return super(ZarrV2DataTypeDefinition, self)._refusal()

    @classmethod
    def _name_problem(cls, name: str, at: Loc) -> ValidationProblem | None:
        return typestr_problem(name, at)

    @classmethod
    def _filed_under(cls, name: str) -> tuple[str | None, dict[str, JSONValue] | None]:
        if name == STRUCT_NAME:
            return name, None
        if name in FAMILIES.values():
            return None, None
        parsed = parse_typestr(name)
        if parsed is None:
            return name, None
        code, carried = parsed
        family = FAMILIES.get(code)
        if family is None:
            return name, None
        return family, carried

    def _carrying_name(self, configuration: Mapping[str, JSONValue]) -> str | None:
        if self.name == STRUCT_NAME:
            return None
        code = next(code for code, family in FAMILIES.items() if family == self.name)
        name = f"{configuration['byteorder']}{code}{configuration.get('itemsize', '')}"
        if "unit" in configuration:
            factor = configuration.get("scale_factor", 1)
            name += f"[{'' if factor == 1 else factor}{configuration['unit']}]"
        return name

    @classmethod
    def _named_configuration(
        cls, value: object
    ) -> tuple[str | None, Mapping[str, object] | None, Problems]:
        if isinstance(value, str):
            return value, None, ()
        if isinstance(value, (list, tuple)):
            return STRUCT_NAME, {"fields": cast("JSONValue", value)}, ()
        return None, None, ()

    @classmethod
    def _envelope_problems(cls, value: object) -> Problems:
        if isinstance(value, str):
            bad = typestr_problem(value, ())
            return () if bad is None else (bad,)
        if isinstance(value, (list, tuple)):
            return ()
        return (
            ValidationProblem(
                (),
                "expected a v2 dtype -- a NumPy typestr, or an array of field records -- got "
                f"{shown(value)}",
                "invalid_type",
            ),
        )

    @classmethod
    def _envelope_json(cls, name: str, configuration: Mapping[str, JSONValue]) -> JSONValue:
        if name == STRUCT_NAME and "fields" in configuration:
            return configuration["fields"]
        return name

    @classmethod
    def _configuration_loc(cls, loc: Loc) -> Loc:
        return loc

    @classmethod
    def _name_loc(cls, loc: Loc) -> Loc:
        return loc

field_aliases class-attribute

field_aliases: tuple[TypeAliasType, ...] = (
    ZarrV2DataTypeField,
)

The field aliases used to annotate a configuration member that holds a field of this kind. For a codec: ZarrV3CodecField and ZarrV3StaticCodecField.

label class-attribute

label: str = 'v2 data type'

The name of the kind in error messages, for example "codec".

zarr_metadata.v2.data_type

The data types that zarr-python 2.x writes, with one definition per NumPy family.

Each family's definition is in its submodule (fixed_width, object, scalar, struct, time). This module holds the dtype's JSON shape, ZarrV2DataTypeMetadata, and DATA_TYPES_V2, the tuple of every definition.

ZarrV2DataTypeMetadata module-attribute

ZarrV2DataTypeMetadata = TypeAliasType(
    "ZarrV2DataTypeMetadata",
    str
    | tuple[
        tuple[str, "ZarrV2DataTypeMetadata"]
        | tuple[
            str, "ZarrV2DataTypeMetadata", tuple[int, ...]
        ],
        ...,
    ],
)

The v2 dtype representation.

Either a numpy-style dtype string (e.g. "<f8", "|S10") or a tuple of field records describing a structured dtype. Each field record is either a 2-tuple (name, datatype) or a 3-tuple (name, datatype, shape) (the 3-tuple form indicates a subarray field). A field datatype may itself be another structured dtype.

Endianness is encoded in the prefix character of the dtype string; parsing it out is a caller concern, not part of this type.

See https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html#data-type-encoding

__all__ module-attribute

__all__ = ['DATA_TYPES_V2', 'ZarrV2DataTypeMetadata']

zarr_metadata.v2.data_type.fixed_width

The v2 families with a fixed width per item, of any size: bytes (S), str (U) and void (V).

BYTES_DATA_TYPE_V2 module-attribute

BYTES_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="bytes",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized(None, None),
    canonical=orderless_at(None),
    fill_value=ZarrV2Base64FillValue,
    fill_value_rules=_bytes_fill_value_rules,
)

|S<n>: byte strings of n bytes. The fill value is base64 of at most n bytes.

STR_DATA_TYPE_V2 module-attribute

STR_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="str",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized(None, frozenset(), unit=CODE_POINT_BYTES),
    fill_value=str | None,
)

<U<n>: strings of n code points. Each code point takes four bytes, in the written byte order. The fill value is a string.

VOID_DATA_TYPE_V2 module-attribute

VOID_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="void",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized(None, None),
    canonical=orderless_at(None),
    fill_value=ZarrV2Base64FillValue,
    fill_value_rules=_void_fill_value_rules,
)

|V<n>: n untyped bytes. The fill value is base64 of exactly n bytes.

ZarrV2Base64FillValue module-attribute

ZarrV2Base64FillValue = str | None

A fill value that the v2 spec encodes as base64, for a fixed-length byte string, void, or a structured type (https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L191-L193), or null.

__all__ module-attribute

__all__ = [
    "BYTES_DATA_TYPE_V2",
    "STR_DATA_TYPE_V2",
    "VOID_DATA_TYPE_V2",
    "ZarrV2Base64FillValue",
]

zarr_metadata.v2.data_type.object

The v2 object family, |O: Python objects. The fill value may be any JSON value.

OBJECT_DATA_TYPE_V2 module-attribute

OBJECT_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="object",
    configuration=ZarrV2ObjectConfiguration,
    canonical=_canonical,
)

|O: Python objects, each encoded by a filter. The fill value may be any JSON value.

__all__ module-attribute

__all__ = [
    "OBJECT_DATA_TYPE_V2",
    "ZarrV2ObjectConfiguration",
]

ZarrV2ObjectConfiguration

Bases: TypedDict

The configuration that |O carries: a byte order, which the type ignores.

Source code in src/zarr_metadata/v2/data_type/object.py
class ZarrV2ObjectConfiguration(TypedDict, closed=True):
    """The configuration that `|O` carries: a byte order, which the type ignores."""

    byteorder: ReadOnly[ZarrV2ByteOrder]

byteorder instance-attribute

byteorder: ReadOnly[ZarrV2ByteOrder]

zarr_metadata.v2.data_type.scalar

The v2 scalar families: bool, int, uint, float and complex. Each definition is filed under its family and is read for every typestr of the family.

BOOL_DATA_TYPE_V2 module-attribute

BOOL_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="bool",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized((1,), None),
    canonical=orderless_at(None),
    fill_value=bool | None,
)

|b1: one byte, true or false.

COMPLEX_DATA_TYPE_V2 module-attribute

COMPLEX_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="complex",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized((8, 16), frozenset()),
    fill_value=ZarrV2ComplexFillValue,
    fill_value_canonical=_complex_canonical,
)

c8, c16: complex floats. The fill value is [real, imag].

FLOAT_DATA_TYPE_V2 module-attribute

FLOAT_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="float",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized((2, 4, 8), frozenset()),
    fill_value=ZarrV2FloatFillValue,
    fill_value_canonical=_float_canonical,
)

f2, f4, f8: IEEE 754 floats. The fill value is a number or a named non-finite value.

INT_DATA_TYPE_V2 module-attribute

INT_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="int",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized((1, 2, 4, 8), _ONE_BYTE),
    canonical=orderless_at(_ONE_BYTE),
    fill_value=int | None,
    fill_value_rules=_InRange(True),
)

i1 to i8: signed integers. The fill value must be in the type's range.

UINT_DATA_TYPE_V2 module-attribute

UINT_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="uint",
    configuration=ZarrV2ScalarConfiguration,
    rules=sized((1, 2, 4, 8), _ONE_BYTE),
    canonical=orderless_at(_ONE_BYTE),
    fill_value=int | None,
    fill_value_rules=_InRange(False),
)

u1 to u8: unsigned integers. The fill value must be in the type's range.

ZarrV2ByteOrder module-attribute

ZarrV2ByteOrder = Literal['<', '>', '|']

The byte orders that a typestr writes: little-endian, big-endian, and not relevant.

ZarrV2ComplexComponent module-attribute

ZarrV2ComplexComponent = float | int | ZarrV2FloatSpecial

One component of a complex fill value: a float fill value that is not null.

ZarrV2ComplexFillValue module-attribute

ZarrV2ComplexFillValue = (
    tuple[ZarrV2ComplexComponent, ZarrV2ComplexComponent]
    | None
)

A v2 complex fill value: [real, imag], each a float fill value, or null.

ZarrV2FloatFillValue module-attribute

ZarrV2FloatFillValue = (
    float | int | ZarrV2FloatSpecial | None
)

A v2 float fill value: a number, a named non-finite value, or null.

ZarrV2FloatSpecial module-attribute

ZarrV2FloatSpecial = Literal["NaN", "Infinity", "-Infinity"]

The non-finite values that the v2 spec spells by name (https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L178-L190).

__all__ module-attribute

__all__ = [
    "BOOL_DATA_TYPE_V2",
    "COMPLEX_DATA_TYPE_V2",
    "FLOAT_DATA_TYPE_V2",
    "INT_DATA_TYPE_V2",
    "UINT_DATA_TYPE_V2",
    "ZarrV2ByteOrder",
    "ZarrV2ComplexComponent",
    "ZarrV2ComplexFillValue",
    "ZarrV2FloatFillValue",
    "ZarrV2FloatSpecial",
    "ZarrV2ScalarConfiguration",
]

ZarrV2ScalarConfiguration

Bases: TypedDict

The configuration that a scalar typestr carries: its byte order and its size in bytes, such as {"byteorder": "<", "itemsize": 4} for <f4.

Source code in src/zarr_metadata/v2/data_type/scalar.py
class ZarrV2ScalarConfiguration(TypedDict, closed=True):
    """The configuration that a scalar typestr carries: its byte order and its size in bytes, such as `{"byteorder": "<", "itemsize": 4}` for `<f4`."""

    byteorder: ReadOnly[ZarrV2ByteOrder]
    itemsize: ReadOnly[Annotated[int, Ge(0)]]

byteorder instance-attribute

byteorder: ReadOnly[ZarrV2ByteOrder]

itemsize instance-attribute

itemsize: ReadOnly[Annotated[int, Ge(0)]]

zarr_metadata.v2.data_type.struct

The v2 struct type: an array of field records. The type of each record is a field of its own.

STRUCT_DATA_TYPE_V2 module-attribute

STRUCT_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name=STRUCT_NAME,
    configuration=ZarrV2StructConfiguration,
    rules=_rules,
    fill_value=ZarrV2Base64FillValue,
    fill_value_rules=_fill_value_rules,
)

A structured type: an array of field records. The fill value is base64 of one record (https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L191-L193).

ZarrV2StructRecord module-attribute

ZarrV2StructRecord = (
    tuple[
        str,
        ZarrV2DataTypeField,
        tuple[Annotated[int, Ge(0)], ...],
    ]
    | tuple[str, ZarrV2DataTypeField]
)

A field record: [name, dtype] or [name, dtype, shape]. The dtype is a nested field (https://github.com/zarr-developers/zarr-specs/blob/fc7dd9c9beb5a50b87f9b08b00bf50fc0048482f/docs/v2/v2.0.rst#L152-L174).

__all__ module-attribute

__all__ = [
    "STRUCT_DATA_TYPE_V2",
    "ZarrV2StructConfiguration",
    "ZarrV2StructRecord",
]

ZarrV2StructConfiguration

Bases: TypedDict

The records of a structured dtype. The document writes the records as the dtype itself.

Source code in src/zarr_metadata/v2/data_type/struct.py
class ZarrV2StructConfiguration(TypedDict, closed=True):
    """The records of a structured dtype. The document writes the records as the dtype itself."""

    fields: ReadOnly[tuple[ZarrV2StructRecord, ...]]

fields instance-attribute

fields: ReadOnly[tuple[ZarrV2StructRecord, ...]]

zarr_metadata.v2.data_type.time

The v2 time families, datetime64 (M) and timedelta64 (m): eight bytes, in a unit that the typestr gives in brackets.

DATETIME64_DATA_TYPE_V2 module-attribute

DATETIME64_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="datetime64",
    configuration=ZarrV2TimeConfiguration,
    rules=time_rules("M"),
    canonical=_canonical,
    fill_value=ZarrV2TimeFillValue,
    fill_value_canonical=_fill_value_canonical,
)

<M8[unit]: a point in time, as ticks of the unit since the epoch.

TIMEDELTA64_DATA_TYPE_V2 module-attribute

TIMEDELTA64_DATA_TYPE_V2: Final = ZarrV2DataTypeDefinition(
    name="timedelta64",
    configuration=ZarrV2TimeConfiguration,
    rules=time_rules("m"),
    canonical=_canonical,
    fill_value=ZarrV2TimeFillValue,
    fill_value_canonical=_fill_value_canonical,
)

<m8[unit]: a duration, as ticks of the unit.

ZarrV2TimeFillValue module-attribute

ZarrV2TimeFillValue = NumpyTimeTicks | Literal["NaT"] | None

A v2 time fill value: a count of ticks, "NaT", or null.

__all__ module-attribute

__all__ = [
    "DATETIME64_DATA_TYPE_V2",
    "TIMEDELTA64_DATA_TYPE_V2",
    "ZarrV2TimeConfiguration",
    "ZarrV2TimeFillValue",
]

ZarrV2TimeConfiguration

Bases: TypedDict

The configuration that a time typestr carries. For example, <M8[10ns] is {"byteorder": "<", "itemsize": 8, "unit": "ns", "scale_factor": 10}.

Source code in src/zarr_metadata/v2/data_type/time.py
class ZarrV2TimeConfiguration(TypedDict, closed=True):
    """The configuration that a time typestr carries. For example, `<M8[10ns]` is `{"byteorder": "<", "itemsize": 8, "unit": "ns", "scale_factor": 10}`."""

    byteorder: ReadOnly[ZarrV2ByteOrder]
    itemsize: ReadOnly[Annotated[int, Ge(0)]]
    unit: NotRequired[ReadOnly[str]]
    scale_factor: NotRequired[ReadOnly[NumpyTimeScaleFactor]]

byteorder instance-attribute

byteorder: ReadOnly[ZarrV2ByteOrder]

itemsize instance-attribute

itemsize: ReadOnly[Annotated[int, Ge(0)]]

scale_factor instance-attribute

scale_factor: NotRequired[ReadOnly[NumpyTimeScaleFactor]]

unit instance-attribute

unit: NotRequired[ReadOnly[str]]