Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion src/zarr/core/metadata/v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ def parse_storage_transformers(data: object) -> tuple[dict[str, JSON], ...]:

class V3JsonEncoder(json.JSONEncoder):
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.indent = kwargs.pop("indent", config.get("json_indent"))
super().__init__(*args, **kwargs)
self.indent = config.get("json_indent")

def default(self, o: object) -> Any:
if isinstance(o, np.dtype):
Expand Down
15 changes: 14 additions & 1 deletion tests/test_metadata/test_v3.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from zarr.codecs.bytes import BytesCodec
from zarr.core.buffer import default_buffer_prototype
from zarr.core.chunk_key_encodings import DefaultChunkKeyEncoding, V2ChunkKeyEncoding
from zarr.core.group import parse_node_type
from zarr.core.group import parse_node_type, GroupMetadata
from zarr.core.metadata.v3 import (
ArrayV3Metadata,
DataType,
Expand Down Expand Up @@ -304,6 +304,19 @@ def test_metadata_to_dict(
assert observed == expected


def test_json_indent():
m = GroupMetadata()
d = m.to_buffer_dict(default_buffer_prototype())["zarr.json"].to_bytes()
class TestIndentEncoder(json.JSONEncoder):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs)
self.indent = 2

# expected has extra ' ' on each line compared with json.dumps( indent=2)
expected = json.dumps(json.loads(d), cls=TestIndentEncoder).encode()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

json.dumps takes an indent keyword argument, so I don't think we need the custom encoder class for this test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I tried that first!
But json.dumps(data, indent=2) gives a different output than a class derived from json.JSONEncoder. The json.JSONEncoder has an extra whitespace at the end of each line (see my comment on line 315 above).
I don't know why this is (I guess it would be nice to know)?!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird, i would also like to know why this is the case. is the extra whitespace more or less correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just confirmed this doing a test writing of some zarr data. All the zarr.json have whitespace at the end of rows that end with a comma.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weird, i would also like to know why this is the case. is the extra whitespace more or less correct?

I would say it's not really correct to have the extra whitespace at the end of lines.
Here, there shouldn't be whitespace after "foo",

>>> json.dumps({"test": "foo", "bar": 2}, cls=TestIndentEncoder)
'{\n  "test": "foo", \n  "bar": 2\n}'

assert d == expected


# @pytest.mark.parametrize("fill_value", [-1, 0, 1, 2932897])
# @pytest.mark.parametrize("precision", ["ns", "D"])
# async def test_datetime_metadata(fill_value: int, precision: str) -> None:
Expand Down
Loading