Skip to content

core

tuplify_json #

tuplify_json(obj: Mapping) -> Mapping
tuplify_json(obj: list) -> tuple
tuplify_json(obj)

Recursively converts lists within a Python object to tuples.

Source code in pydantic_zarr/experimental/core.py
def tuplify_json(obj: object) -> object:
    """
    Recursively converts lists within a Python object to tuples.
    """
    if isinstance(obj, list):
        return tuple(tuplify_json(elem) for elem in obj)
    elif isinstance(obj, dict):
        return {k: tuplify_json(v) for k, v in obj.items()}
    else:
        return obj

parse_dtype_v2 #

parse_dtype_v2(value)

Convert the input to a NumPy dtype and either return the str attribute of that object or, if the dtype is a structured dtype, return the fields of that dtype as a list of tuples.

Parameters:

Name Type Description Default
value DTypeLike

A value that can be converted to a NumPy dtype.

required

Returns:

Type Description
A Zarr V2-compatible encoding of the dtype.
References

See the Zarr V2 specification for more details on this encoding of data types.

Source code in pydantic_zarr/experimental/core.py
def parse_dtype_v2(value: npt.DTypeLike) -> str | list[tuple[Any, ...]]:
    """
    Convert the input to a NumPy dtype and either return the ``str`` attribute of that
    object or, if the dtype is a structured dtype, return the fields of that dtype as a list
    of tuples.

    Parameters
    ----------
    value : npt.DTypeLike
        A value that can be converted to a NumPy dtype.

    Returns
    -------

    A Zarr V2-compatible encoding of the dtype.

    References
    ----------
    See the [Zarr V2 specification](https://zarr-specs.readthedocs.io/en/latest/v2/v2.0.html#data-type-encoding)
    for more details on this encoding of data types.
    """
    # Assume that a non-string sequence represents a the Zarr V2 JSON form of a structured dtype.
    if isinstance(value, Sequence) and not isinstance(value, str):
        return [tuple(v) for v in value]
    else:
        np_dtype = np.dtype(value)
        if np_dtype.fields is not None:
            # This is a structured dtype, which must be converted to a list of tuples. Note that
            # this function recurses, because a structured dtype is parametrized by other dtypes.
            return [(k, parse_dtype_v2(v[0])) for k, v in np_dtype.fields.items()]
        else:
            return np_dtype.str

ensure_member_name #

ensure_member_name(data)

If the input is a string, then ensure that it is a valid name for a subnode in a zarr group

Source code in pydantic_zarr/experimental/core.py
def ensure_member_name(data: Any) -> str:
    """
    If the input is a string, then ensure that it is a valid
    name for a subnode in a zarr group
    """
    if isinstance(data, str):
        if "/" in data:
            raise ValueError(
                f'Strings containing "/" are invalid. Got {data}, which violates this rule.'
            )
        if data in ("", ".", ".."):
            raise ValueError(f"The string {data} is not a valid member name.")
        return data
    raise TypeError(f"Expected a str, got {type(data)}.")

model_like #

model_like(a, b, exclude=None, include=None)

A similarity check for a pair pydantic.BaseModel, parametrized over included or excluded fields.

Source code in pydantic_zarr/experimental/core.py
def model_like(a: BaseModel, b: BaseModel, exclude: IncEx = None, include: IncEx = None) -> bool:
    """
    A similarity check for a pair pydantic.BaseModel, parametrized over included or excluded fields.


    """

    a_dict = a.model_dump(exclude=exclude, include=include)
    b_dict = b.model_dump(exclude=exclude, include=include)
    return json_eq(a_dict, b_dict)

maybe_node #

maybe_node(store, path, *, zarr_format)

Return the array or group found at the store / path, if an array or group exists there. Otherwise return None.

Source code in pydantic_zarr/experimental/core.py
def maybe_node(
    store: StoreLike, path: str, *, zarr_format: Literal[2, 3]
) -> zarr.Array | zarr.Group | None:
    """
    Return the array or group found at the store / path, if an array or group exists there.
    Otherwise return None.
    """
    from zarr.core.sync import sync
    from zarr.core.sync_group import get_node
    from zarr.storage._common import make_store_path

    # convert the storelike store argument to a Zarr store
    spath = sync(make_store_path(store, path=path))
    try:
        return get_node(spath.store, spath.path, zarr_format=zarr_format)
    except FileNotFoundError:
        return None

ensure_multiple #

ensure_multiple(data)

Ensure that there is at least one element in the sequence

Source code in pydantic_zarr/experimental/core.py
def ensure_multiple(data: Sequence[T]) -> Sequence[T]:
    """
    Ensure that there is at least one element in the sequence
    """
    if len(data) < 1:
        raise ValueError("Invalid length. Expected 1 or more, got 0.")
    return data

json_eq #

json_eq(a, b)

An equality check between python objects that recurses into dicts and sequences and ignores the difference between tuples and lists. Otherwise, it's just regular equality. Useful for comparing dicts that would become identical JSON, but where one has lists and the other has tuples.

Source code in pydantic_zarr/experimental/core.py
def json_eq(a: object, b: object) -> bool:
    """
    An equality check between python objects that recurses into dicts and sequences and ignores
    the difference between tuples and lists. Otherwise, it's just regular equality. Useful
    for comparing dicts that would become identical JSON, but where one has lists and the other
    has tuples.
    """
    # treat lists & tuples as the same "sequence" type
    seq_types = (list, tuple)

    # both are sequences → compare element-wise
    if isinstance(a, seq_types) and isinstance(b, seq_types):
        return len(a) == len(b) and all(json_eq(x, y) for x, y in zip(a, b, strict=False))

    # recurse into mappings
    if isinstance(a, Mapping) and isinstance(b, Mapping):
        return a.keys() == b.keys() and all(json_eq(a[k], b[k]) for k in a)

    # otherwise → regular equality
    return a == b