Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions packages/zarr-metadata/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,96 @@

<!-- towncrier release notes start -->

## 0.5.0 (2026-08-14)

### Bugfixes

- `JSONValue`'s array arm is now the covariant `Sequence["JSONValue"]` rather
than the invariant `list["JSONValue"] | tuple["JSONValue", ...]`. Values typed
with a narrower element type — a `list[str]` field on a TypedDict, a
`Sequence[float]` — now count as JSON values, and TypedDicts whose fields
carry precise types are now assignable to `Mapping[str, JSONValue]`.
Type-level cost, accepted deliberately: `Sequence` says nothing about the
concrete container and admits `str`/`bytes`, so runtime code narrowing a JSON
array must exclude `str`/`bytes`/`bytearray` — as it already had to, since
`str` was always a union arm. ([#4264](https://github.com/zarr-developers/zarr-python/pull/4264))

### Deprecations and Removals

- Unified the naming grammar for SCREAMING_SNAKE constants with the one used for
type names. A constant's name is now a purely syntactic transformation of the
name of the `Literal` type it manifests, so the format version is spelled
`ZARR_V2`/`ZARR_V3` and comes first, matching the `ZarrV2`/`ZarrV3` prefix on
the corresponding type:

- `ARRAY_METADATA_STORE_KEY_V2` → `ZARR_V2_ARRAY_METADATA_STORE_KEY`
- `ARRAY_METADATA_STORE_KEY_V3` → `ZARR_V3_ARRAY_METADATA_STORE_KEY`
- `ATTRIBUTES_STORE_KEY_V2` → `ZARR_V2_ATTRIBUTES_STORE_KEY`
- `GROUP_METADATA_STORE_KEY_V2` → `ZARR_V2_GROUP_METADATA_STORE_KEY`
- `GROUP_METADATA_STORE_KEY_V3` → `ZARR_V3_GROUP_METADATA_STORE_KEY`
- `CONSOLIDATED_METADATA_STORE_KEY_V2` → `ZARR_V2_CONSOLIDATED_METADATA_STORE_KEY`
- `ARRAY_ORDER_V2` → `ZARR_V2_ARRAY_ORDER`
- `ARRAY_DIMENSION_SEPARATOR_V2` → `ZARR_V2_ARRAY_DIMENSION_SEPARATOR`
- `CONSOLIDATED_METADATA_KEY_V3` → `ZARR_V3_CONSOLIDATED_METADATA_KEY`

The old names are removed, not aliased. This supersedes the 0.4.0 convention
under which type names put the format version first while constants put it
last: every constant that manifests a `Literal` type now follows the same rule
as that type.

The last of those is the one rename the syntactic rule does not force:
`ZARR_V3_CONSOLIDATED_METADATA_KEY` manifests no `Literal` type, so it is
outside the rule and was renamed for consistency with its siblings.

Digit runs stay glued to the token they follow, so spec vocabulary is
preserved: `Uint8DataTypeName` pairs with `UINT8_DATA_TYPE_NAME` (not
`UINT_8_...`) and `Crc32cCodecName` with `CRC32C_CODEC_NAME`. No dtype, codec,
chunk-grid, or chunk-key-encoding constant changed name.

Constants that do not manifest a `Literal` type are outside the rule and are
unchanged: the `*_METADATA_*_KEYS_V2`/`_V3` key sets, the
`CANONICAL_*_HEX_FLOAT*` bit patterns, and `UNSET`. The key sets keep the
version-last spelling, so `zarr_metadata.model` exports both
`ARRAY_METADATA_REQUIRED_KEYS_V2` and `ZARR_V2_ARRAY_METADATA_STORE_KEY`. They
name validation policy rather than a spec document, have no paired type to
derive from, and renaming them would be a second breaking change buying only
cosmetic consistency — so it is deliberately deferred.

`tests/test_public_api.py::test_constant_names_derive_from_their_type_names`
derives every constant name from the type it manifests and asserts they match,
so the two grammars cannot diverge again.

Store keys also moved to the modules that describe the documents they name,
matching the package's layering (the `v2`/`v3` modules describe the specs; the
`model` layer is built on top of them). `ZARR_V2_ATTRIBUTES_STORE_KEY` now
lives in `zarr_metadata.v2.attributes` beside the `.zattrs` type it names,
rather than in the array model; the other five moved likewise, and
`ZarrV2AttributesStoreKey` is no longer an array-specific concept.
`zarr_metadata.model` re-exports all six, so
`from zarr_metadata.model import ZARR_V2_ARRAY_METADATA_STORE_KEY` is
unaffected.

`CONSOLIDATED_METADATA_KEY_V3` moved to `zarr_metadata.v3.consolidated` and was
renamed to `ZARR_V3_CONSOLIDATED_METADATA_KEY` for consistency. It is not a
store key: unlike v2's `.zmetadata` file, v3 consolidated metadata is embedded
as an extension field inside the group's own `zarr.json`.

All seven keys and the six store-key `Literal` aliases are now also exported
from the top-level `zarr_metadata` namespace, alongside the document types and
the rest of the spec vocabulary, so `from zarr_metadata import
ZARR_V2_ARRAY_METADATA_STORE_KEY` works. The model layer's validators, parsers,
type guards, and metadata key sets remain `zarr_metadata.model` imports.

([#4232](https://github.com/zarr-developers/zarr-python/pull/4232))

### Misc

- The source distribution now ships an explicit allowlist (`/src`, `/tests`,
`/docs`, `/mkdocs.yml`, `/justfile`, `/CHANGELOG.md`) rather than whatever
happens to sit in the package directory, so an sdist both tests and documents
itself and cannot pick up scratch files from the tree it was built in. ([#4248](https://github.com/zarr-developers/zarr-python/pull/4248))


## 0.4.0 (2026-07-29)

### Features
Expand Down
63 changes: 0 additions & 63 deletions packages/zarr-metadata/changes/4232.removal.md

This file was deleted.

9 changes: 0 additions & 9 deletions packages/zarr-metadata/changes/4264.bugfix.md

This file was deleted.

30 changes: 30 additions & 0 deletions packages/zarr-metadata/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,33 @@ underlines = ["", "", ""]
title_format = "## {version} ({project_date})"
issue_format = "[#{issue}](https://github.com/zarr-developers/zarr-python/pull/{issue})"
start_string = "<!-- towncrier release notes start -->\n"

# Declaring any type replaces towncrier's built-in set, so all five the
# `changes/README.md` menu offers are restated here. They are the defaults
# verbatim except for `misc`, whose `showcontent` towncrier defaults to false:
# a `misc` entry would render as a bare PR link, which tells a reader nothing.
# A change worth a release note is worth a sentence, whatever its category.
[[tool.towncrier.type]]
directory = "feature"
name = "Features"
showcontent = true

[[tool.towncrier.type]]
directory = "bugfix"
name = "Bugfixes"
showcontent = true

[[tool.towncrier.type]]
directory = "doc"
name = "Improved Documentation"
showcontent = true

[[tool.towncrier.type]]
directory = "removal"
name = "Deprecations and Removals"
showcontent = true

[[tool.towncrier.type]]
directory = "misc"
name = "Misc"
showcontent = true
Loading