Skip to content

Commit

Permalink
Merge pull request #584 from yukinarit/fix-init-var-field-attribute
Browse files Browse the repository at this point in the history
Fix InitVar with field attribute
  • Loading branch information
yukinarit authored Aug 18, 2024
2 parents 129e030 + c40573a commit 569a2fb
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
12 changes: 11 additions & 1 deletion serde/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,15 +890,25 @@ def should_impl_dataclass(cls: type[Any]) -> bool:
if not dataclasses.is_dataclass(cls):
return True

# Checking is_dataclass is not enough in such a case that the class is inherited
# from another dataclass. To do it correctly, check if all fields in __annotations__
# are present as dataclass fields.
annotations = getattr(cls, "__annotations__", {})
if not annotations:
return False

field_names = [field.name for field in dataclass_fields(cls)]
for field_name in annotations:
for field_name, annotation in annotations.items():
# Omit InitVar field because it doesn't appear in dataclass fields.
if is_instance(annotation, dataclasses.InitVar):
continue
# This field in __annotations__ is not a part of dataclass fields.
# This means this class does not implement dataclass directly.
if field_name not in field_names:
return True

# If all of the fields in __annotation__ are present as dataclass fields,
# the class already implemented dataclass, thus returns False.
return False


Expand Down
9 changes: 9 additions & 0 deletions tests/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,3 +1126,12 @@ class Bar(Foo):

bar = Bar(a=10, b=20)
assert bar == serde.from_dict(Bar, serde.to_dict(bar))


def test_init_var_with_field_attribute() -> None:
@serde.serde
@dataclasses.dataclass
class Foo:
a: int = serde.field(skip=True)

assert serde.to_dict(Foo(10)) == {}

0 comments on commit 569a2fb

Please sign in to comment.