From 0bbe458d8d5c1a24078d9e0ff8664cab1ae35416 Mon Sep 17 00:00:00 2001 From: faph Date: Mon, 18 Mar 2024 10:31:21 +0000 Subject: [PATCH] Naive support for Pydantic defaults --- src/py_avro_schema/_schemas.py | 6 ++++++ tests/test_pydantic.py | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/py_avro_schema/_schemas.py b/src/py_avro_schema/_schemas.py index 1d8f487..70ece28 100644 --- a/src/py_avro_schema/_schemas.py +++ b/src/py_avro_schema/_schemas.py @@ -913,6 +913,12 @@ def _annotation(self, field_name: str) -> Type: return class_.__annotations__[field_name] raise ValueError(f"{field_name} is not a field of {self.py_type}") # Should never happen + def make_default(self, py_default: pydantic.BaseModel) -> Any: + """Naive implementation""" + # A more correct implementation would recursively serialize all Pydantic fields as per Avro schema + # specification. Probably should be implemented using the `make_default` methods. + return dict(py_default) + class PlainClassSchema(RecordSchema): """An Avro record schema for a plain Python class with typed constructor method arguments""" diff --git a/tests/test_pydantic.py b/tests/test_pydantic.py index d1d06a9..3647a40 100644 --- a/tests/test_pydantic.py +++ b/tests/test_pydantic.py @@ -523,3 +523,28 @@ class PyType(Base): ], } assert_schema(PyType, expected) + + +def test_base_model_defaults(): + class Default(pydantic.BaseModel): + field_a: str = "default_a" + + class PyType(pydantic.BaseModel): + default: Default = pydantic.Field(..., default_factory=Default) + + expected = { + "fields": [ + { + "default": {"field_a": "default_a"}, + "name": "default", + "type": { + "fields": [{"default": "default_a", "name": "field_a", "type": "string"}], + "name": "Default", + "type": "record", + }, + } + ], + "name": "PyType", + "type": "record", + } + assert_schema(PyType, expected)