Pydantic: different post_init behavior for dataclass across pydantic versions

Created on 22 Jan 2020  路  4Comments  路  Source: samuelcolvin/pydantic

Bug

The behavior of the __post_init__ routine for pydantic dataclasses is inconsistent across pydantic versions.

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.3
            pydantic compiled: True
                 install path: /home/ubuntu/moo/lib/python3.6/site-packages/pydantic
               python version: 3.6.7 (default, Oct 22 2018, 11:32:17)  [GCC 8.2.0]
                     platform: Linux-4.15.0-1057-aws-x86_64-with-Ubuntu-18.04-bionic
     optional deps. installed: []

Related issues

Issue #739 is related but it talks specifically about descendant classes.

Code snippet

from pydantic.dataclasses import dataclass
@dataclass
class A:
    a = 10
    def __post_init__(self):
        print("custom initializer called")
        self.x = {}

a = A()
print(a.x)

Output

The post init method is called but the extra attribute x is not added to the class instance.

custom initializer called

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    print(a.x)
AttributeError: 'A' object has no attribute 'x'

Downgrading pydantic version to 0.26, it does work. So does using the dataclass object from dataclasses module for python 3.6.

custom initializer called
{}

Is this an intentional change in behavior? Apologies if I've missed something

bug

All 4 comments

The solution is to use __post_init_post_parse__ instead of __post_init__.

This was changed back in v0.28 see #567 and associated issues/PRs for dicussion

Thank you. Would it be useful to specifically point out in the documentation that pydantic dataclass initialize hooks are split into two - before and after validation, and extra attributes can only be added after? Happy to submit a PR.
It tripped me up a bit since it worked okay before in older pydantic versions and dataclasses package.

okay, I'd accept a PR. But I would guess very few people are still using pydantic pre v0.28, so I'm not sure how helpful that specific pointer would be?

right. I was thinking more about the difference between pydantic dataclass and python standard library dataclass in that the __post_init__ method doesn't work _exactly_ the same. I added a note here - #1188.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ashears picture ashears  路  3Comments

krzysieqq picture krzysieqq  路  3Comments

gangefors picture gangefors  路  3Comments

drpoggi picture drpoggi  路  3Comments

ashpreetbedi picture ashpreetbedi  路  3Comments