errors with non string types should give a better message
MODIFY
fastavro/_write.pyx
fastavro/_write.pyx
@@ -125,7 +125,10 @@ cdef inline write_bytes(bytearray fo, const unsigned char[:] datum):
cdef inline write_utf8(bytearray fo, datum):
"""A string is encoded as a long followed by that many bytes of UTF-8
encoded character data."""
+ try:
b_datum = datum.encode()
+ except AttributeError:
+ raise TypeError("must be string")
write_long(fo, len(b_datum))
fo += b_datum

MODIFY
fastavro/io/binary_encoder.py
fastavro/io/binary_encoder.py
@@ -47,7 +47,11 @@ class BinaryEncoder:
self._fo.write(datum)
def write_utf8(self, datum):
- self.write_bytes(datum.encode())
+ try:
+ encoded = datum.encode()
+ except AttributeError:
+ raise TypeError("must be string")
+ self.write_bytes(encoded)
def write_crc32(self, datum):
data = crc32(datum) & 0xFFFFFFFF

MODIFY
tests/test_fastavro.py
tests/test_fastavro.py
@@ -2834,3 +2834,19 @@ def test_union_path_picked_with_record_type_hint(input_records, expected_roundtr
fastavro.parse_schema(schema), input_records, return_record_name=True
)
assert expected_roundtrip == rt_records
+
+
+def test_non_string_types_raise_type_error():
+ """https://github.com/fastavro/fastavro/issues/556"""
+
+ schema = {
+ "type": "record",
+ "fields": [{"name": "field", "type": "string"}],
+ "name": "test_non_string_types_raise_type_error",
+ }
+
+ record = {"field": None}
+
+ new_file = BytesIO()
+ with pytest.raises(TypeError, match="must be string"):
+ fastavro.schemaless_writer(new_file, schema, record)

errors with non string types should give a better message