Skip to content

Nit: __post_init__ vs pydantic @model_validator(mode="after") #204

@TomNicholas

Description

@TomNicholas

In the ZArray class then after #193 we now have multiple types of validation checks, which together look like this:

from pydantic import (
    BaseModel,
    field_validator,
    model_validator,
)

class ZArray(BaseModel):
    ...

    @field_validator("dtype")
    @classmethod
    def validate_dtype(cls, dtype) -> np.dtype:
        # Your custom validation logic here
        # Convert numpy.dtype to a format suitable for Pydantic
        return np.dtype(dtype)

    def __post_init__(self) -> None:
        if len(self.shape) != len(self.chunks):
            raise ValueError(
                "Dimension mismatch between array shape and chunk shape. "
                f"Array shape {self.shape} has ndim={self.shape} but chunk shape {self.chunks} has ndim={len(self.chunks)}"
            )

    @model_validator(mode="after")
    def _check_fill_value(self) -> Self:
        if self.fill_value is None:
            self.fill_value = ZARR_DEFAULT_FILL_VALUE.get(self.dtype, 0.0)
        return self

It seems to me like having both __post_init__ and @model_validator(mode="after") is unnecessarily complicated. I think _check_fill_value should just be rewritten using @field_validator like validate_dtype is.

The check inside __post_init__ can't be done using field_validator as it involves comparing two correctly-instatiated fields against one another. It is not clear to me whether best practice with pydantic is to use __post_init__ or @model_validator(mode="after") - both seem supported, and to do similar things.

@ghidalgo3 is there some subtlety I've missed here or can I clean this up a bit? (I know eventually this should all be replaced by ZarrV3Metadata in #175.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions