fix validator picking wrong union schema
MODIFY
fastavro/_validation.pyx
fastavro/_validation.pyx
@@ -117,6 +117,10 @@ cdef inline bint validate_record(object datum, dict schema, str parent_ns='',
field='{}.{}'.format(namespace, f['name']),
raise_errors=raise_errors):
return False
+ field_names = [field['name'] for field in schema['fields']]
+ for datum_field in iterkeys(datum):
+ if datum_field not in field_names:
+ return False
return True

MODIFY
fastavro/_validation_py.py
fastavro/_validation_py.py
@@ -245,6 +245,7 @@ def validate_record(datum, schema, parent_ns=None, raise_errors=True):
If true, raises ValidationError on invalid data
"""
_, namespace = schema_name(schema, parent_ns)
+ field_names = [field['name'] for field in schema['fields']]
return (
isinstance(datum, Mapping) and
all(validate(datum=datum.get(f['name'], f.get('default')),
@@ -252,7 +253,8 @@ def validate_record(datum, schema, parent_ns=None, raise_errors=True):
field='{}.{}'.format(namespace, f['name']),
raise_errors=raise_errors)
for f in schema['fields']
- )
+ ) and
+ all(datum_field in field_names for datum_field in iterkeys(datum))
)

MODIFY
tests/test_fastavro.py
tests/test_fastavro.py
@@ -1568,3 +1568,24 @@ def test_embedded_records_get_namespaced_correctly():
}]
assert records == roundtrip(schema, records)
+
+
+def test_union_schema_checks_field_names():
+ """https://github.com/fastavro/fastavro/issues/272"""
+ schema = [{
+ "type": "record",
+ "name": "A",
+ "fields": [{"name": "foo", "type": ["string", "null"]}]
+ }, {
+ "type": "record",
+ "name": "B",
+ "fields": [{"name": "bar", "type": ["string", "null"]}]
+ }, {
+ "type": "record",
+ "name": "AOrB",
+ "fields": [{"name": "entity", "type": ["A", "B"]}]
+ }]
+
+ datum_to_read = {'entity': {'foo': 'this is an instance of schema A'}}
+
+ assert [datum_to_read] == roundtrip(schema, [datum_to_read])

fix validator picking wrong union schema