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

Dataclass post_init_post_parse called multiple times. #4487

Closed
7 of 16 tasks
Danosaurus-rex opened this issue Sep 6, 2022 · 3 comments · Fixed by #4493
Closed
7 of 16 tasks

Dataclass post_init_post_parse called multiple times. #4487

Danosaurus-rex opened this issue Sep 6, 2022 · 3 comments · Fixed by #4493
Assignees
Labels
bug V1 Bug related to Pydantic V1.X

Comments

@Danosaurus-rex
Copy link

Danosaurus-rex commented Sep 6, 2022

Initial Checks

  • I have searched GitHub for a duplicate issue and I'm sure this is something new
  • I have searched Google & StackOverflow for a solution and couldn't find anything
  • I have read and followed the docs and still think this is a bug
  • I am confident that the issue is with pydantic (not my code, or another library in the ecosystem like FastAPI or mypy)

Description

When using inheritance with pydantic.dataclasses.dataclass based objects with pydantic>=1.10 I seem to have encountered a bug that calls __post_init_post_parse__ methods multiple times if a __post_init__ method is called further down an inheritance chain.

Running the below code snippet outputs the print statement three times, whereas if __post_init__ is placed in AbstractClass the "post init post parse called" statement is called twice.

The exact same code snippet on pydantic<1.10 works as expected with the print statement only printed the once.

Including an overridden __post_init__ method in ConcreteClass only prints the statement once - but of course if there is more useful logic contained in BaseClass.__post_init__ (as would be the case for this pattern) then this is ignored.

Removing the @dataclass decorators from the base classes works fine however, except if we didn't have access to the code for those underlying base classes.

EDIT: It appears its due to these lines:
https://github.com/pydantic/pydantic/blob/v1.10.2/pydantic/dataclasses.py#L290-L304

Example Code

from pydantic.dataclasses import dataclass

@dataclass
class BaseClass:
    def __post_init__(self):
        pass

@dataclass
class AbstractClass(BaseClass):
    pass

@dataclass
class ConcreteClass(AbstractClass):
    def __post_init_post_parse__(self):
        print("post init post parse called")

ConcreteClass()

# prints:
# post init post parse called
# post init post parse called
# post init post parse called


# Example of nested dataclasses from docs: https://pydantic-docs.helpmanual.io/usage/dataclasses/#convert-stdlib-dataclasses-into-pydantic-dataclasses

from datetime import datetime
from typing import Optional

@dataclass
class Meta:
    modified_date: Optional[datetime]
    seen_count: int
    def __post_init__(self):
        print("POST INIT")

@dataclass
class File(Meta):
    filename: str
    def __post_init_post_parse__(self):
        print("POST INIT POST PARSE")

File(filename="file.txt", modified_date=datetime.now(), seen_count=1)

# prints:
# POST INIT
# POST INIT POST PARSE
# POST INIT POST PARSE

Python, Pydantic & OS Version

pydantic version: 1.10.2
            pydantic compiled: True
                 install path: *****
               python version: 3.8.13 (default, Mar 28 2022, 06:16:26)  [Clang 12.0.0 ]
                     platform: macOS-10.16-x86_64-i386-64bit
     optional deps. installed: ['dotenv', 'typing-extensions']

Affected Components

@Danosaurus-rex Danosaurus-rex added bug V1 Bug related to Pydantic V1.X unconfirmed Bug not yet confirmed as valid/applicable labels Sep 6, 2022
@samuelcolvin
Copy link
Member

See #4484.

@PrettyWood, any ideas?

@PrettyWood
Copy link
Member

I'll check

@Kludex
Copy link
Member

Kludex commented Apr 30, 2023

@Kludex Kludex closed this as completed Apr 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V1 Bug related to Pydantic V1.X
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants