Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove deprecated BaseModel method __fields__, parse_obj and _get_value #43

Merged
merged 4 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,6 @@ dmypy.json

# Pyre type checker
.pyre/

# uv
uv.lock
2 changes: 1 addition & 1 deletion asdf_pydantic/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def to_yaml_tree(self, obj: AsdfPydanticModel, tag, ctx):
return obj.asdf_yaml_tree()

def from_yaml_tree(self, node, tag, ctx):
return self._tag_to_class[tag].parse_obj(node)
return self._tag_to_class[tag].model_validate(node)
47 changes: 28 additions & 19 deletions asdf_pydantic/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,42 @@ class AsdfPydanticModel(BaseModel):
ASDF Serialization and Deserialization:
Serialize to ASDF yaml tree is done with the
py:classmethod`AsdfPydanticModel.asdf_yaml_tree()` and deserialize to an
AsdfPydanticModel object with py:meth`AsdfPydanticModel.parse_obj()`.
AsdfPydanticModel object with py:meth`AsdfPydanticModel.model_validate()`.
"""

_tag: ClassVar[str | TagDefinition]
model_config = ConfigDict(arbitrary_types_allowed=True)

def asdf_yaml_tree(self) -> dict:
d = {}
for field_key, v in self.__dict__.items():
if field_key not in self.__fields__:
continue

"""Converts the model to an ASDF-compatible YAML tree (dict).

.. note::
Any fields that are normal Pydantic `BaseModel` will be converted to
dict. See conversion table.

Conversion Table:

+-------------------------+-----------------------------+
| Value type in field | Value type in dict |
+=========================+=============================+
| AsdfPydanticModel | No conversion |
+-------------------------+-----------------------------+
| BaseModel | Converted to dict using |
| | BaseModel.model_dump() |
+-------------------------+-----------------------------+
| Other types | No conversion |
+-------------------------+-----------------------------+
"""
tree = {}
for k, v in dict(self).items():
if isinstance(v, AsdfPydanticModel):
d[field_key] = v
tree[k] = v
elif isinstance(v, BaseModel):
tree[k] = v.model_dump()
else:
d[field_key] = self._get_value(
v,
to_dict=True,
by_alias=False,
include=None,
exclude=None,
exclude_unset=False,
exclude_defaults=False,
exclude_none=False,
)

return d
tree[k] = v

return tree

@model_validator(mode="before")
@classmethod
Expand Down
42 changes: 42 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,52 @@
import pytest
import yaml
from asdf.extension import TagDefinition
from pydantic import BaseModel

from asdf_pydantic import AsdfPydanticModel


########################################################################################
# ASDF Tree
########################################################################################
def test_asdf_yaml_tree_sanity():
class TestModel(AsdfPydanticModel):
foo: str

model = TestModel(foo="bar")
assert model.asdf_yaml_tree() == {"foo": "bar"}


def test_asdf_yaml_tree_nested_dict():
class NestedTestModel(AsdfPydanticModel):
nested: dict

model = NestedTestModel(nested={"foo": "bar"})
assert model.asdf_yaml_tree() == {"nested": {"foo": "bar"}}


def test_asdf_yaml_tree_nested_basemodel():
class TestModel(BaseModel):
foo: str

class NestedTestModel(AsdfPydanticModel):
nested: TestModel

model = NestedTestModel(nested=TestModel(foo="bar"))
assert model.asdf_yaml_tree() == {"nested": {"foo": "bar"}}


def test_asdf_yaml_tree_nested_asdf_pydantic_model():
class TestModel(AsdfPydanticModel):
foo: str

class NestedTestModel(AsdfPydanticModel):
nested: TestModel

model = NestedTestModel(nested=TestModel(foo="bar"))
assert model.asdf_yaml_tree() == {"nested": TestModel(foo="bar")}


########################################################################################
# TAGS
########################################################################################
Expand Down