Skip to content

Commit

Permalink
♻️ Add extra checks in header valdiation.
Browse files Browse the repository at this point in the history
  • Loading branch information
dalonsoa committed Dec 18, 2024
1 parent fb12669 commit 7c28b94
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
22 changes: 15 additions & 7 deletions csvy/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ def validate_header(header: dict[str, Any]) -> dict[str, Any]:
This function runs the validators on the header. It uses the keys of the header to
find the validators in the registry and runs them on the corresponding values. As
a result, some values in the header may be replaced by the validated values in the
form of Pydantic models. If the header is an already validated header, the
validators are not run in the values that are already Pydantic models.
form of Pydantic models.
If the header is an already validated header, the Pydantic models within, if any,
are dumped to dictionaries and re-validated, again. This accounts for the case where
attributes of the Pydantic models are changed to invalid values.
Args:
header: The header of the CSVY file.
Expand All @@ -55,13 +58,18 @@ def validate_header(header: dict[str, Any]) -> dict[str, Any]:
The validated header.
"""
validated_header = {}
validated_header: dict[str, Any] = {}
for key, value in header.items():
if isinstance(value, BaseModel) or key not in VALIDATORS_REGISTRY:
validated_header[key] = value
else:
value_ = value.model_dump() if isinstance(value, BaseModel) else value
if key in VALIDATORS_REGISTRY:
if not isinstance(value_, dict):
raise ValueError(
f"Value for '{key}' must be a dictionary, not a '{type(value_)}'."
)
validator = VALIDATORS_REGISTRY[key]
validated_header[key] = validator(**value)
validated_header[key] = validator(**value_)
else:
validated_header[key] = value_
return validated_header


Expand Down
7 changes: 6 additions & 1 deletion tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,14 @@ class MyValidator(BaseModel):
assert validated_header["my_validator"].value == 42
assert validated_header["author"] == header["author"]

# If the header is already validated, the validators should not run.
# If the header is already validated, it should pass
assert validate_header(validated_header) == validated_header

# But if the validated header is changed to an invalid value, it should fail
validated_header["my_validator"].value = -1
with pytest.raises(ValueError):
validate_header(validated_header)


def test_validate_read_missing(validators_registry):
"""Test that we can run validators on the header."""
Expand Down

0 comments on commit 7c28b94

Please sign in to comment.