Skip to content

Commit

Permalink
Support required model property
Browse files Browse the repository at this point in the history
  • Loading branch information
christiansandberg committed Sep 23, 2024
1 parent cfefcc1 commit ec90ab3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 31 deletions.
17 changes: 8 additions & 9 deletions onedm/sdf/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ class IntegerData(DataQualities):
exclusive_minimum: int | None = None
exclusive_maximum: int | None = None
multiple_of: int | None = None
enum: list[int] | None = None
choices: Annotated[dict[str, IntegerData] | None, Field(alias="sdfChoice")] = (
None # type: ignore[assignment]
)
Expand Down Expand Up @@ -266,14 +265,14 @@ def always_include_type(self, type: str, _):
def _get_base_schema(self) -> core_schema.CoreSchema:
if self.properties is None:
return core_schema.dict_schema()
required = self.required or []
fields = {
name: core_schema.typed_dict_field(
property.get_pydantic_schema(), required=name in required
)
for name, property in self.properties.items()
}
return core_schema.typed_dict_schema(fields)
return core_schema.typed_dict_schema(
{
name: core_schema.typed_dict_field(
property.get_pydantic_schema(), required=name in self.required
)
for name, property in self.properties.items()
}
)


class AnyData(DataQualities):
Expand Down
38 changes: 17 additions & 21 deletions onedm/sdf/from_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ def data_from_type(type_: Type) -> data.Data | None:
def data_from_schema(schema: core_schema.CoreSchema) -> data.Data:
schema_type = schema["type"]
data_type: data.Data
if schema_type == "int":
if schema_type == "nullable":
data_type = data_from_nullable_schema(schema) # type: ignore
elif schema_type == "default":
data_type = data_from_default_schema(schema) # type: ignore
elif schema_type == "any":
data_type = data_from_any_schema(schema) # type: ignore
elif schema_type == "int":
data_type = data_from_int_schema(schema) # type: ignore
elif schema_type == "float":
data_type = data_from_float_schema(schema) # type: ignore
Expand Down Expand Up @@ -50,12 +56,6 @@ def data_from_schema(schema: core_schema.CoreSchema) -> data.Data:
data_type = data_from_enum_schema(schema) # type: ignore
elif schema_type == "literal":
data_type = data_from_literal_schema(schema) # type: ignore
elif schema_type == "any":
data_type = data_from_any_schema(schema) # type: ignore
elif schema_type == "nullable":
data_type = data_from_nullable_schema(schema) # type: ignore
elif schema_type == "default":
data_type = data_from_default_schema(schema) # type: ignore
elif schema_type == "datetime":
data_type = data_from_datetime_schema(schema) # type: ignore
else:
Expand All @@ -82,19 +82,21 @@ def data_from_default_schema(schema: core_schema.WithDefaultSchema):


def data_from_model_schema(schema: core_schema.ModelSchema):
data_type = data_from_schema(schema["schema"])
return data_type
return data_from_schema(schema["schema"])


def data_from_model_fields_schema(schema: core_schema.ModelFieldsSchema):
return data.ObjectData(
label=schema.get("model_name"),
properties={
prop_schema.get("serialization_alias", name): data_from_schema(
prop_schema["schema"]
)
for name, prop_schema in schema["fields"].items()
field.get("serialization_alias", name): data_from_schema(field["schema"])
for name, field in schema["fields"].items()
},
required=[
field.get("serialization_alias", name)
for name, field in schema["fields"].items()
if field["schema"]["type"] != "default"
],
nullable=False,
)

Expand Down Expand Up @@ -209,15 +211,9 @@ def data_from_bytes_schema(schema: core_schema.BytesSchema):
def data_from_literal_schema(schema: core_schema.LiteralSchema):
choices = schema["expected"]
if len(choices) == 1:
return data.AnyData(
const=choices[0],
nullable=False,
)
return data.AnyData(const=choices[0], nullable=False)
if all(isinstance(choice, str) for choice in choices):
return data.StringData(
enum=choices,
nullable=False,
)
return data.StringData(enum=choices, nullable=False)
raise NotImplementedError(f"Literal with {choices} not supported")


Expand Down
8 changes: 7 additions & 1 deletion tests/sdf/test_from_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,26 @@ def test_set():
def test_model():
class TestModel(BaseModel):
with_default: int = 2
with_alias: Annotated[int, Field(alias="withAlias")]
with_alias: Annotated[int, Field(alias="withAlias")] = 0
optional: float | None = None
required: bool | None

data = data_from_type(TestModel)

assert isinstance(data, sdf.ObjectData)
assert data.label == "TestModel"
assert not data.nullable
assert data.required == ["required"]

assert isinstance(data.properties["with_default"], sdf.IntegerData)
assert data.properties["with_default"].default == 2
assert not data.properties["with_default"].nullable

assert "withAlias" in data.properties

assert data.properties["required"].nullable
assert data.properties["optional"].nullable


def test_dataclass():
@dataclass
Expand Down

0 comments on commit ec90ab3

Please sign in to comment.