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

defaultdict converted to dict after __post_init__ #1536

Closed
rshin opened this issue May 19, 2020 · 2 comments · Fixed by #2325
Closed

defaultdict converted to dict after __post_init__ #1536

rshin opened this issue May 19, 2020 · 2 comments · Fixed by #2325

Comments

@rshin
Copy link

rshin commented May 19, 2020

Bug

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

             pydantic version: 1.5.1
            pydantic compiled: True
                 install path: <redacted>/lib/python3.7/site-packages/pydantic
               python version: 3.7.3 | packaged by conda-forge | (default, Dec  6 2019, 08:36:57)  [Clang 9.0.0 (tags/RELEASE_900/final)]
                     platform: Darwin-19.4.0-x86_64-i386-64bit
     optional deps. installed: ['typing-extensions']

If I run the following snippet:

import collections
import dataclasses
from typing import DefaultDict

from pydantic.dataclasses import dataclass


@dataclass
class X:
    f: DefaultDict[int, int] = dataclasses.field(init=False)

    def __post_init__(self):
        self.f = collections.defaultdict(int)
        self.f[2] += 1
        print(f"__post_init__: {self.f}")


x = X()
print(type(x.f))
print(x.f)

It prints the following:

__post_init__: defaultdict(<class 'int'>, {2: 1})
<class 'dict'>
{2: 1}

In other words, the defaultdict field is converted into a dict (while preserving the keys), even though the field is annotated as DefaultDict, which is surprising. Is this intended behavior?

@rshin rshin added the bug V1 Bug related to Pydantic V1.X label May 19, 2020
@PrettyWood
Copy link
Member

Hello @rshin,
You are right it comes from the default mapping validator, which always returns a dict.
@samuelcolvin A potential fix could be something like this. maybe with a try...except
Are you willing to consider it in which case I open a PR?

@samuelcolvin
Copy link
Member

Surely better to implement a validator for DefaultDict, thus avoiding any performance impact on normal dictionaries?

@samuelcolvin samuelcolvin added feature request and removed bug V1 Bug related to Pydantic V1.X labels May 31, 2020
alex-paru added a commit to alex-paru/pydantic that referenced this issue Oct 27, 2020
alex-paru added a commit to alex-paru/pydantic that referenced this issue Oct 28, 2020
alex-paru added a commit to alex-paru/pydantic that referenced this issue Oct 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants