@@ -309,6 +309,9 @@ def encode(self, variable: Variable, name: T_Name = None):
309309 dtype = np .dtype (encoding .get ("dtype" , data .dtype ))
310310 fv = encoding .get ("_FillValue" )
311311 mv = encoding .get ("missing_value" )
312+ # to properly handle _FillValue/missing_value below [a], [b]
313+ # we need to check if unsigned data is written as signed data
314+ unsigned = encoding .get ("_Unsigned" ) is not None
312315
313316 fv_exists = fv is not None
314317 mv_exists = mv is not None
@@ -323,13 +326,19 @@ def encode(self, variable: Variable, name: T_Name = None):
323326
324327 if fv_exists :
325328 # Ensure _FillValue is cast to same dtype as data's
326- encoding ["_FillValue" ] = dtype .type (fv )
329+ # [a] need to skip this if _Unsigned is available
330+ if not unsigned :
331+ encoding ["_FillValue" ] = dtype .type (fv )
327332 fill_value = pop_to (encoding , attrs , "_FillValue" , name = name )
328333
329334 if mv_exists :
330335 # try to use _FillValue, if it exists to align both values
331336 # or use missing_value and ensure it's cast to same dtype as data's
332- encoding ["missing_value" ] = attrs .get ("_FillValue" , dtype .type (mv ))
337+ # [b] need to provide mv verbatim if _Unsigned is available
338+ encoding ["missing_value" ] = attrs .get (
339+ "_FillValue" ,
340+ (dtype .type (mv ) if not unsigned else mv ),
341+ )
333342 fill_value = pop_to (encoding , attrs , "missing_value" , name = name )
334343
335344 # apply fillna
@@ -522,7 +531,6 @@ def encode(self, variable: Variable, name: T_Name = None) -> Variable:
522531 def decode (self , variable : Variable , name : T_Name = None ) -> Variable :
523532 if "_Unsigned" in variable .attrs :
524533 dims , data , attrs , encoding = unpack_for_decoding (variable )
525-
526534 unsigned = pop_to (attrs , encoding , "_Unsigned" )
527535
528536 if data .dtype .kind == "i" :
0 commit comments