@@ -470,7 +470,7 @@ def from_json_scalar(self, data: JSON, *, zarr_format: ZarrFormat) -> np.void:
470470 return cast ("np.void" , np .array ([as_bytes ]).view (dtype )[0 ])
471471 raise TypeError (f"Invalid type: { data } . Expected a string." )
472472
473- def to_json_scalar (self , data : object , * , zarr_format : ZarrFormat ) -> str :
473+ def to_json_scalar (self , data : object , * , zarr_format : ZarrFormat ) -> str | dict [ str , JSON ] :
474474 """
475475 Convert a scalar to a JSON-serializable string representation.
476476
@@ -483,9 +483,10 @@ def to_json_scalar(self, data: object, *, zarr_format: ZarrFormat) -> str:
483483
484484 Returns
485485 -------
486- str
486+ str | dict[str, JSON]
487487 A string representation of the scalar, which is a base64-encoded
488- string of the bytes that make up the scalar.
488+ string of the bytes that make up the scalar. Subclasses may return
489+ a dict for V3 format.
489490 """
490491 return bytes_to_json (self .cast_scalar (data ).tobytes (), zarr_format )
491492
@@ -501,6 +502,20 @@ def item_size(self) -> int:
501502 """
502503 return self .to_native_dtype ().itemsize
503504
505+ def has_multi_byte_fields (self ) -> bool :
506+ """
507+ Check if this structured dtype has any fields with item_size > 1.
508+
509+ Returns
510+ -------
511+ bool
512+ True if any field has item_size > 1, False otherwise.
513+ """
514+ return any (
515+ isinstance (field_dtype , HasItemSize ) and field_dtype .item_size > 1
516+ for _ , field_dtype in self .fields
517+ )
518+
504519
505520@dataclass (frozen = True , kw_only = True )
506521class Struct (Structured ):
@@ -552,7 +567,8 @@ def _from_json_v3(cls, data: DTypeJSON) -> Self:
552567 f_name = field ["name" ]
553568 f_dtype = field ["data_type" ]
554569 else :
555- f_name , f_dtype = field
570+ # Legacy tuple-style field format from "structured" dtype
571+ f_name , f_dtype = field # type: ignore[unreachable]
556572 parsed_fields .append ((f_name , get_data_type_from_json (f_dtype , zarr_format = 3 ))) # type: ignore[arg-type]
557573 return cls (fields = tuple (parsed_fields ))
558574 msg = f"Invalid JSON representation of { cls .__name__ } . Got { data !r} , expected a JSON object with the key { cls ._zarr_v3_name !r} "
@@ -648,17 +664,3 @@ def to_json_scalar(self, data: object, *, zarr_format: ZarrFormat) -> str | dict
648664 scalar [field_name ], zarr_format = zarr_format
649665 )
650666 return result
651-
652- def has_multi_byte_fields (self ) -> bool :
653- """
654- Check if this structured dtype has any fields with item_size > 1.
655-
656- Returns
657- -------
658- bool
659- True if any field has item_size > 1, False otherwise.
660- """
661- return any (
662- isinstance (field_dtype , HasItemSize ) and field_dtype .item_size > 1
663- for _ , field_dtype in self .fields
664- )
0 commit comments