add hint to top level union schemas
MODIFY
fastavro/_schema.pyx
fastavro/_schema.pyx
@@ -63,6 +63,10 @@ def parse_schema(schema, expand=False, _write_hint=True, _force=False):
return _parse_schema(schema, "", expand, _write_hint, set())
elif isinstance(schema, dict) and "__fastavro_parsed" in schema:
return schema
+ elif isinstance(schema, list):
+ # If we are given a list we should make sure that the immediate sub
+ # schemas have the hint in them
+ return [parse_schema(s, expand, _write_hint, _force) for s in schema]
else:
return _parse_schema(schema, "", expand, _write_hint, set())

MODIFY
fastavro/_schema_py.py
fastavro/_schema_py.py
@@ -190,6 +190,10 @@ def parse_schema(schema, expand=False, _write_hint=True, _force=False):
return _parse_schema(schema, "", expand, _write_hint, set())
elif isinstance(schema, dict) and "__fastavro_parsed" in schema:
return schema
+ elif isinstance(schema, list):
+ # If we are given a list we should make sure that the immediate sub
+ # schemas have the hint in them
+ return [parse_schema(s, expand, _write_hint, _force) for s in schema]
else:
return _parse_schema(schema, "", expand, _write_hint, set())

MODIFY
fastavro/_write.pyx
fastavro/_write.pyx
@@ -557,6 +557,20 @@ cdef class Writer(object):
for key, value in iteritems(schema)
if key != "__fastavro_parsed"
}
+ elif isinstance(schema, list):
+ schemas = []
+ for s in schema:
+ if isinstance(s, dict):
+ schemas.append(
+ {
+ key: value
+ for key, value in iteritems(s)
+ if key != "__fastavro_parsed"
+ }
+ )
+ else:
+ schemas.append(s)
+ schema = schemas
self.metadata['avro.schema'] = json.dumps(schema)

MODIFY
fastavro/_write_py.py
fastavro/_write_py.py
@@ -369,6 +369,20 @@ class GenericWriter(object):
for key, value in iteritems(schema)
if key != "__fastavro_parsed"
}
+ elif isinstance(schema, list):
+ schemas = []
+ for s in schema:
+ if isinstance(s, dict):
+ schemas.append(
+ {
+ key: value
+ for key, value in iteritems(s)
+ if key != "__fastavro_parsed"
+ }
+ )
+ else:
+ schemas.append(s)
+ schema = schemas
self.metadata['avro.schema'] = json.dumps(schema)

MODIFY
tests/test_fastavro.py
tests/test_fastavro.py
@@ -1856,6 +1856,35 @@ def test_hint_is_not_written_to_the_file():
assert "__fastavro_parsed" not in reader._schema
+def test_hint_is_not_written_to_the_file_list_schema():
+ """The __fastavro_parsed hint should not be written to the avrofile"""
+ schema = [
+ {
+ "type": "record",
+ "name": "test_hint_is_not_written_to_the_file_list_schema_1",
+ "fields": []
+ },
+ {
+ "type": "record",
+ "name": "test_hint_is_not_written_to_the_file_list_schema_2",
+ "fields": []
+ }
+ ]
+
+ parsed_schema = fastavro.parse_schema(schema)
+
+ # It should get added when parsing
+ assert all(("__fastavro_parsed" in s for s in parsed_schema))
+
+ stream = MemoryIO()
+ fastavro.writer(stream, parsed_schema, [{}])
+ stream.seek(0)
+
+ reader = fastavro.reader(stream)
+ # By the time it is in the file, it should not
+ assert all(("__fastavro_parsed" not in s for s in reader._schema))
+
+
def test_more_null_union_issues():
"""https://github.com/fastavro/fastavro/issues/336"""
schema = {

MODIFY
tests/test_schema.py
tests/test_schema.py
@@ -367,3 +367,36 @@ def test_expanding_recursive_schemas_should_stop():
parsed = expand_schema(sub_schema)
assert sub_schema == parsed
+
+
+def test_parse_schema_includes_hint_with_list():
+ """https://github.com/fastavro/fastavro/issues/444"""
+ schema = [
+ {
+ "type": "record",
+ "name": "test_parse_schema_includes_hint_with_list_1",
+ "doc": "blah",
+ "fields": [
+ {
+ "name": "field1",
+ "type": "string",
+ "default": ""
+ }
+ ]
+ },
+ {
+ "type": "record",
+ "name": "test_parse_schema_includes_hint_with_list_2",
+ "doc": "blah",
+ "fields": [
+ {
+ "name": "field2",
+ "type": "string",
+ "default": ""
+ }
+ ]
+ }
+ ]
+ parsed_schema = parse_schema(schema)
+ for s in parsed_schema:
+ assert "__fastavro_parsed" in s

add hint to top level union schemas