Skip to content

Commit 680d922

Browse files
authored
Add feature to validate map types (#848)
* Add feature to validate map types * Bump to 8.7 on account of new validation behavior for MapSchema.
1 parent 98e2751 commit 680d922

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ DEVPKGS=-rdev-requirements.txt -rtest-requirements.txt -rmypy-requirements.txt
3131
COVBASE=coverage run --append
3232
PYTEST_EXTRA ?= -rs
3333

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

3737
## all : default task (install schema-salad in dev mode)

schema_salad/validate.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ def friendly(v: Any) -> Any:
9494
return avro_shortname(v.name)
9595
if isinstance(v, avro.schema.ArraySchema):
9696
return f"array of <{friendly(v.items)}>"
97+
if isinstance(v, (avro.schema.MapSchema, avro.schema.NamedMapSchema)):
98+
return f"map of <{friendly(v.values)}>"
9799
if isinstance(v, avro.schema.PrimitiveSchema):
98100
return v.type
99101
if isinstance(v, (avro.schema.UnionSchema, avro.schema.NamedUnionSchema)):
@@ -258,10 +260,18 @@ def validate_ex(
258260
for s in expected_schema.schemas:
259261
if isinstance(datum, MutableSequence) and not isinstance(s, avro.schema.ArraySchema):
260262
continue
261-
if isinstance(datum, MutableMapping) and not isinstance(s, avro.schema.RecordSchema):
263+
if isinstance(datum, MutableMapping) and not isinstance(
264+
s, (avro.schema.RecordSchema, avro.schema.MapSchema, avro.schema.NamedMapSchema)
265+
):
262266
continue
263267
if isinstance(datum, (bool, int, float, str)) and isinstance(
264-
s, (avro.schema.ArraySchema, avro.schema.RecordSchema)
268+
s,
269+
(
270+
avro.schema.ArraySchema,
271+
avro.schema.RecordSchema,
272+
avro.schema.MapSchema,
273+
avro.schema.NamedMapSchema,
274+
),
265275
):
266276
continue
267277
if datum is not None and s.type == "null":
@@ -437,6 +447,40 @@ def validate_ex(
437447
raise ValidationException("", None, errors, "*")
438448
return False
439449
return True
450+
451+
if isinstance(expected_schema, (avro.schema.MapSchema, avro.schema.NamedMapSchema)):
452+
if isinstance(datum, MutableMapping):
453+
for key, val in datum.items():
454+
if not isinstance(key, str):
455+
pass
456+
try:
457+
sl = SourceLine(datum, key, ValidationException)
458+
if not validate_ex(
459+
expected_schema.values,
460+
val,
461+
identifiers,
462+
strict=strict,
463+
foreign_properties=foreign_properties,
464+
raise_ex=raise_ex,
465+
strict_foreign_properties=strict_foreign_properties,
466+
logger=logger,
467+
skip_foreign_properties=skip_foreign_properties,
468+
vocab=vocab,
469+
):
470+
return False
471+
except ValidationException as v:
472+
if raise_ex:
473+
source = v if debug else None
474+
raise ValidationException("item is invalid because", sl, [v]) from source
475+
return False
476+
return True
477+
if raise_ex:
478+
raise ValidationException(
479+
f"the value {vpformat(datum)} is not an object, "
480+
f"expected object of {friendly(expected_schema.values)}"
481+
)
482+
return False
483+
440484
if raise_ex:
441485
raise ValidationException(f"Unrecognized schema_type {schema_type}")
442486
return False

0 commit comments

Comments
 (0)