Skip to content

Commit 97d781b

Browse files
d-v-bdependabot[bot]Copilot
authored
fix![zarr-metadata]: define JSONValue type, and narrow object annotations to use JSONValue (zarr-developers#4037)
* chore(deps): bump the actions group across 1 directory with 8 updates (zarr-developers#176) Bumps the actions group with 8 updates in the / directory: | Package | From | To | | --- | --- | --- | | [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) | `0.9.5` | `0.9.6` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6.0.0` | `6.0.1` | | [github/issue-metrics](https://github.com/github/issue-metrics) | `4.2.2` | `4.2.7` | | [j178/prek-action](https://github.com/j178/prek-action) | `2.0.3` | `2.0.4` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `7.0.0` | `8.0.1` | | [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.13.0` | `1.14.0` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.3` | `0.5.6` | Updates `prefix-dev/setup-pixi` from 0.9.5 to 0.9.6 - [Release notes](https://github.com/prefix-dev/setup-pixi/releases) - [Commits](prefix-dev/setup-pixi@1b2de7f...5185adf) Updates `codecov/codecov-action` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](codecov/codecov-action@57e3a13...e79a696) Updates `github/issue-metrics` from 4.2.2 to 4.2.7 - [Release notes](https://github.com/github/issue-metrics/releases) - [Commits](github-community-projects/issue-metrics@c9e9838...1e38d5e) Updates `j178/prek-action` from 2.0.3 to 2.0.4 - [Release notes](https://github.com/j178/prek-action/releases) - [Commits](j178/prek-action@6ad8027...bdca6f1) Updates `actions/upload-artifact` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v7...043fb46) Updates `actions/download-artifact` from 7.0.0 to 8.0.1 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](actions/download-artifact@v7...3e5f45b) Updates `pypa/gh-action-pypi-publish` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](pypa/gh-action-pypi-publish@v1.13.0...cef2210) Updates `zizmorcore/zizmor-action` from 0.5.3 to 0.5.6 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](zizmorcore/zizmor-action@b1d7e1f...5f14fd0) --- updated-dependencies: - dependency-name: prefix-dev/setup-pixi dependency-version: 0.9.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: codecov/codecov-action dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: github/issue-metrics dependency-version: 4.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: j178/prek-action dependency-version: 2.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore: define JSONValue type, and narrow object annotations to use JSONValue * fix: apply JSONValue more extensively, and correct dtype data types * Delete packages/zarr-metadata/.claude/hooks/.logs/hook-log.jsonl * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: export JSONValue * docs: add changelog entry --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 205f5f8 commit 97d781b

12 files changed

Lines changed: 54 additions & 26 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Introduces a new `JSONValue` type that models python objects that serialize directly to JSON. This type is used to annotate the contents of `attributes` and `fill_value` fields, replacing the use of the overly wide `object` type. This is technically a breaking change.

packages/zarr-metadata/src/zarr_metadata/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from importlib.metadata import version
22

3-
from zarr_metadata._common import NamedConfig
3+
from zarr_metadata._common import JSONValue, NamedConfig
44
from zarr_metadata.v2.array import (
55
ArrayDimensionSeparatorV2,
66
ArrayMetadataV2,
@@ -37,6 +37,7 @@
3737
"GroupMetadataV2Partial",
3838
"GroupMetadataV3",
3939
"GroupMetadataV3Partial",
40+
"JSONValue",
4041
"MetadataFieldV3",
4142
"NamedConfig",
4243
"ZArrayMetadata",

packages/zarr-metadata/src/zarr_metadata/_common.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,28 @@
99
from collections.abc import Mapping
1010
from typing import NotRequired
1111

12-
from typing_extensions import TypedDict
12+
from typing_extensions import TypeAliasType, TypedDict
13+
14+
JSONValue = TypeAliasType(
15+
"JSONValue",
16+
"int | float | bool | None | str | list[JSONValue] | tuple[JSONValue, ...] | Mapping[str, JSONValue]", # type: ignore[reportInvalidTypeForm]
17+
)
18+
"""A recursive type alias for JSON-encodable values.
19+
20+
Defined via `TypeAliasType` (rather than a plain `TypeAlias`) so the
21+
self-reference is a named recursion point that pydantic can resolve when
22+
building a `TypeAdapter`; a bare recursive `TypeAlias` raises
23+
`PydanticUserError`/`RecursionError` at validation time.
24+
"""
1325

1426

1527
class NamedConfig(TypedDict):
1628
"""
1729
Externally-tagged union member for a metadata field.
1830
1931
The `configuration` mapping holds arbitrary JSON-encodable values;
20-
it is typed as `Mapping[str, object]` because the type system cannot
21-
express or verify JSON-encodability.
32+
it is typed as `Mapping[str, JSONValue]`.
2233
"""
2334

2435
name: str
25-
configuration: NotRequired[Mapping[str, object]]
36+
configuration: NotRequired[Mapping[str, JSONValue]]

packages/zarr-metadata/src/zarr_metadata/v2/array.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from typing_extensions import TypedDict
77

8+
from zarr_metadata._common import JSONValue
89
from zarr_metadata.v2.codec import CodecMetadataV2
910

1011
DataTypeMetadataV2 = str | tuple[tuple[str, str] | tuple[str, str, tuple[int, ...]], ...]
@@ -61,7 +62,7 @@ class ZArrayMetadata(TypedDict):
6162
chunks: tuple[int, ...]
6263
dtype: DataTypeMetadataV2
6364
compressor: CodecMetadataV2 | None
64-
fill_value: object
65+
fill_value: JSONValue
6566
order: ArrayOrderV2
6667
filters: tuple[CodecMetadataV2, ...] | None
6768
dimension_separator: NotRequired[ArrayDimensionSeparatorV2]
@@ -87,11 +88,11 @@ class ArrayMetadataV2(TypedDict):
8788
chunks: tuple[int, ...]
8889
dtype: DataTypeMetadataV2
8990
compressor: CodecMetadataV2 | None
90-
fill_value: object
91+
fill_value: JSONValue
9192
order: ArrayOrderV2
9293
filters: tuple[CodecMetadataV2, ...] | None
9394
dimension_separator: NotRequired[ArrayDimensionSeparatorV2]
94-
attributes: NotRequired[Mapping[str, object]]
95+
attributes: NotRequired[Mapping[str, JSONValue]]
9596
"""User attributes from the sibling `.zattrs` file (not part of `.zarray`).
9697
9798
See the class docstring for the rationale behind the merged representation.
@@ -128,11 +129,11 @@ class ArrayMetadataV2Partial(TypedDict, total=False):
128129
chunks: tuple[int, ...]
129130
dtype: DataTypeMetadataV2
130131
compressor: CodecMetadataV2 | None
131-
fill_value: object
132+
fill_value: JSONValue
132133
order: ArrayOrderV2
133134
filters: tuple[CodecMetadataV2, ...] | None
134135
dimension_separator: NotRequired[ArrayDimensionSeparatorV2]
135-
attributes: NotRequired[Mapping[str, object]]
136+
attributes: NotRequired[Mapping[str, JSONValue]]
136137
"""User attributes from the sibling `.zattrs` file (not part of `.zarray`).
137138
138139
See the class docstring for the rationale behind the merged representation.

packages/zarr-metadata/src/zarr_metadata/v2/attributes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
from collections.abc import Mapping
77

8-
ZAttrsMetadata = Mapping[str, object]
8+
from zarr_metadata._common import JSONValue
9+
10+
ZAttrsMetadata = Mapping[str, JSONValue]
911
"""On-disk `.zattrs` file content.
1012
1113
A JSON object holding user-defined attributes for a v2 array or group.

packages/zarr-metadata/src/zarr_metadata/v2/codec.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
from typing_extensions import TypedDict
99

10+
from zarr_metadata._common import JSONValue
1011

11-
class CodecMetadataV2(TypedDict, extra_items=object): # type: ignore[call-arg]
12+
13+
class CodecMetadataV2(TypedDict, extra_items=JSONValue): # type: ignore[call-arg]
1214
"""
1315
A numcodecs configuration dict, used as a v2 compressor or filter.
1416

packages/zarr-metadata/src/zarr_metadata/v2/group.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from typing_extensions import TypedDict
1010

11+
from zarr_metadata._common import JSONValue
12+
1113

1214
class ZGroupMetadata(TypedDict):
1315
"""
@@ -39,7 +41,7 @@ class GroupMetadataV2(TypedDict):
3941
"""
4042

4143
zarr_format: Literal[2]
42-
attributes: NotRequired[Mapping[str, object]]
44+
attributes: NotRequired[Mapping[str, JSONValue]]
4345

4446

4547
class GroupMetadataV2Partial(TypedDict, total=False):
@@ -69,7 +71,7 @@ class GroupMetadataV2Partial(TypedDict, total=False):
6971
"""
7072

7173
zarr_format: Literal[2]
72-
attributes: NotRequired[Mapping[str, object]]
74+
attributes: NotRequired[Mapping[str, JSONValue]]
7375

7476

7577
__all__ = [

packages/zarr-metadata/src/zarr_metadata/v3/array.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
from typing_extensions import TypedDict
77

8+
from zarr_metadata._common import JSONValue
89
from zarr_metadata.v3._common import MetadataFieldV3
910

1011

11-
class ExtensionFieldV3(TypedDict, extra_items=object): # type: ignore[call-arg]
12+
class ExtensionFieldV3(TypedDict, extra_items=JSONValue): # type: ignore[call-arg]
1213
"""
1314
Required shape of any extension field on a v3 metadata document.
1415
@@ -55,9 +56,9 @@ class ArrayMetadataV3(TypedDict, extra_items=ExtensionFieldV3): # type: ignore[
5556
shape: tuple[int, ...]
5657
chunk_grid: MetadataFieldV3
5758
chunk_key_encoding: MetadataFieldV3
58-
fill_value: object
59+
fill_value: JSONValue
5960
codecs: tuple[MetadataFieldV3, ...]
60-
attributes: NotRequired[Mapping[str, object]]
61+
attributes: NotRequired[Mapping[str, JSONValue]]
6162
storage_transformers: NotRequired[tuple[MetadataFieldV3, ...]]
6263
dimension_names: NotRequired[tuple[str | None, ...]]
6364

@@ -91,9 +92,9 @@ class ArrayMetadataV3Partial(TypedDict, total=False, extra_items=ExtensionFieldV
9192
shape: tuple[int, ...]
9293
chunk_grid: MetadataFieldV3
9394
chunk_key_encoding: MetadataFieldV3
94-
fill_value: object
95+
fill_value: JSONValue
9596
codecs: tuple[MetadataFieldV3, ...]
96-
attributes: NotRequired[Mapping[str, object]]
97+
attributes: NotRequired[Mapping[str, JSONValue]]
9798
storage_transformers: NotRequired[tuple[MetadataFieldV3, ...]]
9899
dimension_names: NotRequired[tuple[str | None, ...]]
99100

packages/zarr-metadata/src/zarr_metadata/v3/codec/cast_value.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from typing_extensions import TypedDict
1010

11+
from zarr_metadata._common import JSONValue
1112
from zarr_metadata.v3._common import MetadataFieldV3
1213

1314
CAST_VALUE_CODEC_NAME: Final = "cast_value"
@@ -46,7 +47,7 @@
4647
OUT_OF_RANGE_MODE: Final = ("clamp", "wrap")
4748
"""Tuple of permitted values for the `out_of_range` field of the `cast_value` codec."""
4849

49-
ScalarMapEntry = tuple[object, object]
50+
ScalarMapEntry = tuple[JSONValue, JSONValue]
5051
"""A single `[input, output]` mapping in a `scalar_map` direction.
5152
5253
Each scalar is JSON-encoded per its data type's fill-value rules (so

packages/zarr-metadata/src/zarr_metadata/v3/codec/scale_offset.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
from typing_extensions import TypedDict
1010

11+
from zarr_metadata._common import JSONValue
12+
1113
SCALE_OFFSET_CODEC_NAME: Final = "scale_offset"
1214
"""The `name` field value of the `scale_offset` codec."""
1315

@@ -26,8 +28,8 @@ class ScaleOffsetCodecConfiguration(TypedDict):
2628
permitted in addition to numbers.
2729
"""
2830

29-
offset: NotRequired[object]
30-
scale: NotRequired[object]
31+
offset: NotRequired[JSONValue]
32+
scale: NotRequired[JSONValue]
3133

3234

3335
class ScaleOffsetCodecObject(TypedDict):

0 commit comments

Comments
 (0)