From 79ed78fda03eaab649912dc630b44e941debf553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Augusto=20da=20Silva=20Vasconcellos?= Date: Wed, 29 May 2019 14:14:36 -0300 Subject: [PATCH] Run dataclass' original __post_init__ before validation (#560) * Run dataclass' original __post_init__ before validation * Add unit test * Update HISTORY.rst --- HISTORY.rst | 2 ++ pydantic/dataclasses.py | 4 ++-- tests/test_dataclasses.py | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 69fa838..3d3dcd0 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,8 @@ History v0.xx (xxxx-xx-xx) .................. * fix JSON Schema for ``list``, ``tuple``, and ``set``, #540 by @tiangolo +* Change `_pydantic_post_init` to execute dataclass' original `__post_init__` before + validation, #560 by @HeavenVolkoff v0.26 (2019-05-22) .................. diff --git a/pydantic/dataclasses.py b/pydantic/dataclasses.py index 0207489..83e3a98 100644 --- a/pydantic/dataclasses.py +++ b/pydantic/dataclasses.py @@ -25,11 +25,11 @@ if TYPE_CHECKING: # pragma: no cover def _pydantic_post_init(self: 'DataclassType') -> None: + if self.__post_init_original__: + self.__post_init_original__() d = validate_model(self.__pydantic_model__, self.__dict__, cls=self.__class__)[0] object.__setattr__(self, '__dict__', d) object.__setattr__(self, '__initialised__', True) - if self.__post_init_original__: - self.__post_init_original__() def _validate_dataclass(cls: Type['DataclassType'], v: Any) -> 'DataclassType': diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py index 7cdd4b1..250c9eb 100644 --- a/tests/test_dataclasses.py +++ b/tests/test_dataclasses.py @@ -107,6 +107,25 @@ def test_post_init(): assert post_init_called +def test_post_init_assignment(): + from dataclasses import field + + # Based on: https://docs.python.org/3/library/dataclasses.html#post-init-processing + @pydantic.dataclasses.dataclass + class C: + a: float + b: float + c: float = field(init=False) + + def __post_init__(self): + self.c = self.a + self.b + + c = C(0.1, 0.2) + assert c.a == 0.1 + assert c.b == 0.2 + assert c.c == 0.30000000000000004 + + def test_inheritance(): @pydantic.dataclasses.dataclass class A: