Skip to content

Commit

Permalink
feat: implement make_default for PydanticSchema (jpmorganchase#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
dada-engineer committed Mar 18, 2024
1 parent 57df5ff commit 28a2133
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
11 changes: 7 additions & 4 deletions src/py_avro_schema/_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,9 @@ def data(self, names: NamesType) -> JSONObj:
"items": self.items_schema.data(names=names),
}

def make_default(self, py_default: Any) -> Any:

This comment has been minimized.

Copy link
@faph

faph Mar 18, 2024

Could I propose we do this in a separate PR?

This comment has been minimized.

Copy link
@dada-engineer

dada-engineer Mar 18, 2024

Author Owner

This is also just wrong, as str is also a sequence so I am not sure if this schema would handle this type as well... needs more thought.

This comment has been minimized.

Copy link
@faph

faph Mar 18, 2024

But I think that is already controlled by SequenceSchema.handles_types

return [_schema_obj(default.__class__).make_default(default) for default in py_default]


class DictSchema(Schema):
"""An Avro map schema for a given Python mapping"""
Expand Down Expand Up @@ -807,10 +810,6 @@ def __init__(
if isinstance(self.schema, UnionSchema):
self.schema.sort_item_schemas(self.default)
typeguard.check_type(self.default, self.py_type)

# allow to use pydantic models as default values
if PydanticSchema.handles_type(default.__class__):
self.default = default.model_dump(mode="json") # type: ignore
else:
if Option.DEFAULTS_MANDATORY in self.options:
raise TypeError(f"Default value for field {self} is missing")
Expand Down Expand Up @@ -906,6 +905,10 @@ def _record_field(self, name: str, py_field: pydantic.fields.FieldInfo) -> Recor
)
return field_obj

def make_default(self, py_default: Any) -> Any:
"""Return an Avro schema compliant default value for a given Python value"""
return {key: _schema_obj(value.__class__).make_default(value) for key, value in py_default}

def _annotation(self, field_name: str) -> Type:
"""
Fetch the raw annotation for a given field name
Expand Down
4 changes: 3 additions & 1 deletion tests/test_pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ class Default(pydantic.BaseModel):

class PyType(pydantic.BaseModel):
default: Default = pydantic.Field(..., default_factory=Default)
defaults: list[Default] = pydantic.Field(..., default_factory=lambda: [Default()])

This comment has been minimized.

Copy link
@faph

faph Mar 18, 2024

This should be a separate test case (and separate PR) please


expected = {
"fields": [
Expand All @@ -542,7 +543,8 @@ class PyType(pydantic.BaseModel):
"name": "Default",
"type": "record",
},
}
},
{"default": [{"field_a": "default_a"}], "name": "defaults", "type": {"items": "Default", "type": "array"}},
],
"name": "PyType",
"type": "record",
Expand Down

0 comments on commit 28a2133

Please sign in to comment.