be able to specify enum and fixed names in tuple writer
MODIFY
fastavro/_read.pyx
fastavro/_read.pyx
@@ -24,7 +24,6 @@ from ._read_common import (
SYNC_SIZE,
HEADER_SCHEMA,
missing_codec_lib,
- NAMED_TYPES,
)
from .const import (
MCS_PER_HOUR,
@@ -34,6 +33,7 @@ from .const import (
MLS_PER_MINUTE,
MLS_PER_SECOND,
DAYS_SHIFT,
+ NAMED_TYPES,
)
CYTHON_MODULE = 1 # Tests check this to confirm whether using the Cython code.

MODIFY
fastavro/_read_common.py
fastavro/_read_common.py
@@ -13,7 +13,6 @@ HEADER_SCHEMA = {
{"name": "sync", "type": {"type": "fixed", "name": "sync", "size": SYNC_SIZE}},
],
}
-NAMED_TYPES = {"record", "enum", "fixed", "error"}
class SchemaResolutionError(Exception):

MODIFY
fastavro/_read_py.py
fastavro/_read_py.py
@@ -26,7 +26,6 @@ from ._read_common import (
SYNC_SIZE,
HEADER_SCHEMA,
missing_codec_lib,
- NAMED_TYPES,
)
from .const import (
MCS_PER_HOUR,
@@ -36,6 +35,7 @@ from .const import (
MLS_PER_MINUTE,
MLS_PER_SECOND,
DAYS_SHIFT,
+ NAMED_TYPES,
)
MASK = 0xFF

MODIFY
fastavro/_write.pyx
fastavro/_write.pyx
@@ -253,7 +253,7 @@ cdef write_union(bytearray fo, datum, schema, dict named_schemas, fname):
(name, datum) = datum
for index, candidate in enumerate(schema):
extracted_type = extract_record_type(candidate)
- if extracted_type == "record":
+ if extracted_type in const.NAMED_TYPES:
schema_name = candidate["name"]
else:
schema_name = extracted_type

MODIFY
fastavro/_write_py.py
fastavro/_write_py.py
@@ -13,6 +13,7 @@ import bz2
import lzma
import zlib
+from .const import NAMED_TYPES
from .io.binary_encoder import BinaryEncoder
from .io.json_encoder import AvroJSONEncoder
from .validation import _validate
@@ -140,7 +141,7 @@ def write_union(encoder, datum, schema, named_schemas, fname):
(name, datum) = datum
for index, candidate in enumerate(schema):
extracted_type = extract_record_type(candidate)
- if extracted_type == "record":
+ if extracted_type in NAMED_TYPES:
schema_name = candidate["name"]
else:
schema_name = extracted_type

MODIFY
fastavro/const.py
fastavro/const.py
@@ -17,3 +17,5 @@ INT_MIN_VALUE = -(1 << 31)
INT_MAX_VALUE = (1 << 31) - 1
LONG_MIN_VALUE = -(1 << 63)
LONG_MAX_VALUE = (1 << 63) - 1
+
+NAMED_TYPES = {"record", "enum", "fixed", "error"}

MODIFY
tests/test_fastavro.py
tests/test_fastavro.py
@@ -2678,3 +2678,67 @@ def test_error_if_trying_to_write_the_wrong_number_of_bytes():
records = [b"22", b"333", b"22"]
with pytest.raises(ValueError):
roundtrip(parsed_schema, records)
+
+
+def test_tuple_writer_picks_correct_union_path_enum():
+ """https://github.com/fastavro/fastavro/issues/536"""
+ schema = {
+ "type": "record",
+ "name": "test_tuple_writer_picks_correct_union_path_enum",
+ "fields": [
+ {
+ "name": "Field",
+ "type": [
+ {"type": "string"},
+ {"type": "enum", "name": "Enum", "symbols": ["FOO", "BAR"]},
+ ],
+ },
+ ],
+ }
+
+ expected_roundtrip_value = [{"Field": "FOO"}]
+
+ records = [{"Field": ("Enum", "FOO")}]
+ parsed_schema = fastavro.parse_schema(schema)
+ assert expected_roundtrip_value == roundtrip(
+ parsed_schema, records, return_record_name=True
+ )
+
+ records = [{"Field": ("string", "FOO")}]
+ expected_roundtrip_value = [{"Field": "FOO"}]
+ parsed_schema = fastavro.parse_schema(schema)
+ assert expected_roundtrip_value == roundtrip(
+ parsed_schema, records, return_record_name=True
+ )
+
+
+def test_tuple_writer_picks_correct_union_path_fixed():
+ """https://github.com/fastavro/fastavro/issues/536"""
+ schema = {
+ "type": "record",
+ "name": "test_tuple_writer_picks_correct_union_path_fixed",
+ "fields": [
+ {
+ "name": "Field",
+ "type": [
+ {"type": "bytes"},
+ {"type": "fixed", "name": "Fixed", "size": 4},
+ ],
+ },
+ ],
+ }
+
+ expected_roundtrip_value = [{"Field": b"1234"}]
+
+ records = [{"Field": ("Fixed", b"1234")}]
+ parsed_schema = fastavro.parse_schema(schema)
+ assert expected_roundtrip_value == roundtrip(
+ parsed_schema, records, return_record_name=True
+ )
+
+ records = [{"Field": ("bytes", b"1234")}]
+ expected_roundtrip_value = [{"Field": b"1234"}]
+ parsed_schema = fastavro.parse_schema(schema)
+ assert expected_roundtrip_value == roundtrip(
+ parsed_schema, records, return_record_name=True
+ )

be able to specify enum and fixed names in tuple writer