8000 fix: avoid multiple calls of `__post_init__` when dataclasses are inh… · pydantic/pydantic@a825106 · GitHub
[go: up one dir, main page]

Skip to content

Commit a825106

Browse files
authored
fix: avoid multiple calls of __post_init__ when dataclasses are inherited (#4493)
1 parent c04923c commit a825106

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

changes/4487-PrettyWood.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fix: avoid multiple calls of `__post_init__` when dataclasses are inherited

pydantic/dataclasses.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,10 @@ def handle_extra_init(self: 'Dataclass', *args: Any, **kwargs: Any) -> None:
288288
init(self, *args, **kwargs)
289289

290290
if hasattr(dc_cls, '__post_init__'):
291-
post_init = dc_cls.__post_init__
291+
try:
292+
post_init = dc_cls.__post_init__.__wrapped__ # type: ignore[attr-defined]
293+
except AttributeError:
294+
post_init = dc_cls.__post_init__
292295

293296
@wraps(post_init)
294297
def new_post_init(self: 'Dataclass', *args: Any, **kwargs: Any) -> None:

tests/test_dataclasses.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,31 @@ def __post_init__(self):
14741474
assert C().a == 6 # 1 * 3 + 3
14751475

14761476

1477+
def test_inheritance_post_init_2():
1478+
post_init_calls = 0
1479+
post_init_post_parse_calls = 0
1480+
1481+
@pydantic.dataclasses.dataclass
1482+
class BaseClass:
1483+
def __post_init__(self):
1484+
nonlocal post_init_calls
1485+
post_init_calls += 1
1486+
1487+
@pydantic.dataclasses.dataclass
1488+
class AbstractClass(BaseClass):
1489+
pass
1490+
1491+
@pydantic.dataclasses.dataclass
1492+
class ConcreteClass(AbstractClass):
1493+
def __post_init_post_parse__(self):
1494+
nonlocal post_init_post_parse_calls
1495+
post_init_post_parse_calls += 1
1496+
1497+
ConcreteClass()
1498+
assert post_init_calls == 1
1499+
assert post_init_post_parse_calls == 1
1500+
1501+
14771502
def test_dataclass_setattr():
14781503
class Foo:
14791504
bar: str = 'cat'

0 commit comments

Comments
 (0)
0