Skip to content

Commit

Permalink
Add feature to validate map types (#848)
Browse files Browse the repository at this point in the history
* Add feature to validate map types

* Bump to 8.7 on account of new validation behavior for MapSchema.
  • Loading branch information
tetron authored Jul 18, 2024
1 parent 98e2751 commit 680d922
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ DEVPKGS=-rdev-requirements.txt -rtest-requirements.txt -rmypy-requirements.txt
COVBASE=coverage run --append
PYTEST_EXTRA ?= -rs

VERSION=8.6.$(shell date +%Y%m%d%H%M%S --utc --date=`git log --first-parent \
VERSION=8.7.$(shell date +%Y%m%d%H%M%S --utc --date=`git log --first-parent \
--max-count=1 --format=format:%cI`)

## all : default task (install schema-salad in dev mode)
Expand Down
48 changes: 46 additions & 2 deletions schema_salad/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def friendly(v: Any) -> Any:
return avro_shortname(v.name)
if isinstance(v, avro.schema.ArraySchema):
return f"array of <{friendly(v.items)}>"
if isinstance(v, (avro.schema.MapSchema, avro.schema.NamedMapSchema)):
return f"map of <{friendly(v.values)}>"
if isinstance(v, avro.schema.PrimitiveSchema):
return v.type
if isinstance(v, (avro.schema.UnionSchema, avro.schema.NamedUnionSchema)):
Expand Down Expand Up @@ -258,10 +260,18 @@ def validate_ex(
for s in expected_schema.schemas:
if isinstance(datum, MutableSequence) and not isinstance(s, avro.schema.ArraySchema):
continue
if isinstance(datum, MutableMapping) and not isinstance(s, avro.schema.RecordSchema):
if isinstance(datum, MutableMapping) and not isinstance(
s, (avro.schema.RecordSchema, avro.schema.MapSchema, avro.schema.NamedMapSchema)
):
continue
if isinstance(datum, (bool, int, float, str)) and isinstance(
s, (avro.schema.ArraySchema, avro.schema.RecordSchema)
s,
(
avro.schema.ArraySchema,
avro.schema.RecordSchema,
avro.schema.MapSchema,
avro.schema.NamedMapSchema,
),
):
continue
if datum is not None and s.type == "null":
Expand Down Expand Up @@ -437,6 +447,40 @@ def validate_ex(
raise ValidationException("", None, errors, "*")
return False
return True

if isinstance(expected_schema, (avro.schema.MapSchema, avro.schema.NamedMapSchema)):
if isinstance(datum, MutableMapping):
for key, val in datum.items():
if not isinstance(key, str):
pass
try:
sl = SourceLine(datum, key, ValidationException)
if not validate_ex(
expected_schema.values,
val,
identifiers,
strict=strict,
foreign_properties=foreign_properties,
raise_ex=raise_ex,
strict_foreign_properties=strict_foreign_properties,
logger=logger,
skip_foreign_properties=skip_foreign_properties,
vocab=vocab,
):
return False
except ValidationException as v:
if raise_ex:
source = v if debug else None
raise ValidationException("item is invalid because", sl, [v]) from source
return False
return True
if raise_ex:
raise ValidationException(
f"the value {vpformat(datum)} is not an object, "
f"expected object of {friendly(expected_schema.values)}"
)
return False

if raise_ex:
raise ValidationException(f"Unrecognized schema_type {schema_type}")
return False

0 comments on commit 680d922

Please sign in to comment.