11from  __future__ import  annotations 
22
3+ import  base64 
34import  warnings 
45from  typing  import  TYPE_CHECKING , TypedDict , overload 
56
4445
4546DEFAULT_DTYPE  =  "float64" 
4647
47- # Keep in sync with _replace_special_floats  
48+ # Keep in sync with _replace_special_floats_and_serialize_void  
4849SPECIAL_FLOATS_ENCODED  =  {
4950    "Infinity" : np .inf ,
5051    "-Infinity" : - np .inf ,
@@ -187,7 +188,9 @@ def default(self, o: object) -> Any:
187188                if  isinstance (out , complex ):
188189                    # python complex types are not JSON serializable, so we use the 
189190                    # serialization defined in the zarr v3 spec 
190-                     return  _replace_special_floats ([out .real , out .imag ])
191+                     return  _replace_special_floats_and_serialize_void (
192+                         [out .real , out .imag ], is_v3 = True 
193+                     )
191194                elif  np .isnan (out ):
192195                    return  "NaN" 
193196                elif  np .isinf (out ):
@@ -204,7 +207,7 @@ def default(self, o: object) -> Any:
204207            return  super ().default (o )
205208
206209
207- def  _replace_special_floats (obj : object ) ->  Any :
210+ def  _replace_special_floats_and_serialize_void (obj : object ,  is_v3 :  bool ) ->  Any :
208211    """Helper function to replace NaN/Inf/-Inf values with special strings 
209212
210213    Note: this cannot be done in the V3JsonEncoder because Python's `json.dumps` optimistically 
@@ -215,12 +218,18 @@ def _replace_special_floats(obj: object) -> Any:
215218            return  "NaN" 
216219        elif  np .isinf (obj ):
217220            return  "Infinity"  if  obj  >  0  else  "-Infinity" 
221+     if  isinstance (obj , np .void ):
222+         if  is_v3 :
223+             raise  ValueError ("Cannot convert void with v3 zarr" )
224+         return  base64 .standard_b64encode (cast (bytes , obj )).decode ("ascii" )
218225    elif  isinstance (obj , dict ):
219226        # Recursively replace in dictionaries 
220-         return  {k : _replace_special_floats (v ) for  k , v  in  obj .items ()}
227+         return  {
228+             k : _replace_special_floats_and_serialize_void (v , is_v3 = is_v3 ) for  k , v  in  obj .items ()
229+         }
221230    elif  isinstance (obj , list ):
222231        # Recursively replace in lists 
223-         return  [_replace_special_floats (item ) for  item  in  obj ]
232+         return  [_replace_special_floats_and_serialize_void (item ,  is_v3 = is_v3 ) for  item  in  obj ]
224233    return  obj 
225234
226235
@@ -388,7 +397,7 @@ def encode_chunk_key(self, chunk_coords: ChunkCoords) -> str:
388397        return  self .chunk_key_encoding .encode_chunk_key (chunk_coords )
389398
390399    def  to_buffer_dict (self , prototype : BufferPrototype ) ->  dict [str , Buffer ]:
391-         d  =  _replace_special_floats (self .to_dict ())
400+         d  =  _replace_special_floats_and_serialize_void (self .to_dict (),  is_v3 = True )
392401        return  {ZARR_JSON : prototype .buffer .from_bytes (json .dumps (d , cls = V3JsonEncoder ).encode ())}
393402
394403    @classmethod  
0 commit comments