-
Notifications
You must be signed in to change notification settings - Fork 54
Description
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 selfIt 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.)