From 34c4c2430f9f0e3559b47f52d6077c536cb2386a Mon Sep 17 00:00:00 2001 From: Ryan Abernathey Date: Wed, 9 Oct 2024 10:54:46 -0400 Subject: [PATCH] add custom Zarr _FillValue encoding / decoding --- xarray/backends/zarr.py | 59 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/xarray/backends/zarr.py b/xarray/backends/zarr.py index 58572f4998c..f3d122ad394 100644 --- a/xarray/backends/zarr.py +++ b/xarray/backends/zarr.py @@ -1,8 +1,10 @@ from __future__ import annotations +import base64 import functools import json import os +import struct import warnings from collections.abc import Callable, Iterable from typing import TYPE_CHECKING, Any, Literal @@ -58,6 +60,49 @@ def _zarr_v3() -> bool: ZarrFormat = Literal[2, 3] +class FillValueCoder: + """Handle custom logic to safely encode and decode fill values in Zarr. + Possibly redundant with logic in xarray/coding/variables.py but needs to be + isolated from NetCDF-specific logic. + """ + + @classmethod + def encode(cls, value: int | float | str | bytes, dtype: np.dtype[Any]) -> Any: + if dtype.kind in "S": + # byte string + return base64.standard_b64encode(value).decode() + elif dtype.kind in "b": + # boolean + return bool(value) + elif dtype.kind in "iu": + # todo: do we want to check for decimals? + return int(value) + elif dtype.kind in "f": + return base64.standard_b64encode(struct.pack("