Skip to content

Commit 583ddea

Browse files
authored
Add supports for sets (#7)
1 parent af2fb6e commit 583ddea

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

src/py_avro_schema/_schemas.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,33 @@ def make_default(self, py_default: collections.abc.Sequence) -> JSONArray:
671671
return [self.items_schema.make_default(item) for item in py_default]
672672

673673

674+
@register_schema
675+
class SetSchema(SequenceSchema):
676+
"""An Avro array schema for a given Python set"""
677+
678+
@classmethod
679+
def handles_type(cls, py_type: type) -> bool:
680+
"""Whether this schema class can represent a given Python class"""
681+
py_type = _type_from_annotated(py_type)
682+
origin = get_origin(py_type)
683+
return _is_class(origin, collections.abc.MutableSet)
684+
685+
def __init__(
686+
self,
687+
py_type: type[collections.abc.MutableSet],
688+
namespace: str | None = None,
689+
options: Option = Option(0),
690+
):
691+
"""
692+
An Avro array schema for a given Python sequence
693+
694+
:param py_type: The Python class to generate a schema for.
695+
:param namespace: The Avro namespace to add to schemas.
696+
:param options: Schema generation options.
697+
"""
698+
super().__init__(py_type, namespace=namespace, options=options) # type: ignore
699+
700+
674701
@register_schema
675702
class DictSchema(Schema):
676703
"""An Avro map schema for a given Python mapping"""
@@ -1148,7 +1175,7 @@ def _record_field(self, py_field: tuple[str, Type]) -> RecordField:
11481175
if field := self.signature_fields.get(name):
11491176
_annotation, _default = field
11501177
if actual_type is _annotation:
1151-
default = _default
1178+
default = _default or dataclasses.MISSING
11521179
field_obj = RecordField(
11531180
py_type=actual_type,
11541181
name=name,

tests/test_primitives.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ def test_string_list():
174174
assert_schema(py_type, expected)
175175

176176

177+
def test_string_set():
178+
py_type = set[str]
179+
expected = {"type": "array", "items": "string"}
180+
assert_schema(py_type, expected)
181+
182+
177183
def test_string_list_annotated():
178184
py_type = Annotated[List[str], ...]
179185
expected = {"type": "array", "items": "string"}
@@ -192,6 +198,12 @@ def test_int_list():
192198
assert_schema(py_type, expected)
193199

194200

201+
def test_int_set():
202+
py_type = set[int]
203+
expected = {"type": "array", "items": "long"}
204+
assert_schema(py_type, expected)
205+
206+
195207
def test_string_tuple():
196208
py_type = Tuple[str]
197209
expected = {"type": "array", "items": "string"}
@@ -214,6 +226,18 @@ def test_string_mutable_sequence():
214226
assert_schema(py_type, expected)
215227

216228

229+
def test_string_set_of_set():
230+
py_type = set[set[str]]
231+
expected = {
232+
"type": "array",
233+
"items": {
234+
"type": "array",
235+
"items": "string",
236+
},
237+
}
238+
assert_schema(py_type, expected)
239+
240+
217241
def test_string_list_of_lists():
218242
py_type = List[List[str]]
219243
expected = {

0 commit comments

Comments
 (0)