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

Nested model with Dict __root__ init behaviour #1773

Closed
okonos opened this issue Jul 28, 2020 · 4 comments
Closed

Nested model with Dict __root__ init behaviour #1773

okonos opened this issue Jul 28, 2020 · 4 comments
Labels

Comments

@okonos
Copy link

okonos commented Jul 28, 2020

Question

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

             pydantic version: 1.6.1
            pydantic compiled: True
                 install path: /home/pawecich/.virtualenvs/foundation/lib/python3.8/site-packages/pydantic
               python version: 3.8.2 (default, Jul 16 2020, 14:00:26)  [GCC 9.3.0]
                     platform: Linux-5.4.0-42-generic-x86_64-with-glibc2.29
     optional deps. installed: ['typing-extensions']

Hello,

I'm trying to nest a model with custom Union[str, Dict] root type in another model and seem to be getting some inconsistent behavior during model init. Consider following code snippet:

from typing import Dict, Union

from pydantic import BaseModel, ValidationError


class StrDict(BaseModel):
    __root__: Union[str, Dict[str, str]]

    def __init__(self, *args, **kwargs):
        print(f"{kwargs=}")
        super().__init__(*args, **kwargs)


class StrDictModel(BaseModel):
    d: StrDict


print(StrDictModel(d='asdf').dict())
print()
try:
    print(StrDictModel(d={'k': 'v'}).dict())
except ValidationError as e:
    print(e)
print()
print(StrDictModel(d={'__root__': {'k': 'v'}}).dict())

This outputs:

kwargs={'__root__': 'asdf'}
{'d': 'asdf'}

kwargs={'k': 'v'}
1 validation error for Model
d -> __root__
  field required (type=value_error.missing)

kwargs={'__root__': {'k': 'v'}}
{'d': {'k': 'v'}}

In case of passing a string, it gets nested under the __root__ key automatically, which is not the case with the dict, which seems to require explicit nesting.
Is this expected?

@PrettyWood
Copy link
Member

Hi @okonos
It is intended yes as described in #1607:

This does not make that change at the outermost level, so .dict() still always returns a dict (as discussed in #1193).

@okonos
Copy link
Author

okonos commented Jul 29, 2020

Thanks, @PrettyWood
I admit I find it somewhat confusing. From the discussions linked I gather that this custom root functionality is to be changed in the next major version. Do you happen to know what the scope of the changes is going to be and if this particular behavior is to be addressed somehow?

@PrettyWood
Copy link
Member

I'm afraid it won't be available anytime soon (see https://github.com/samuelcolvin/pydantic/milestone/2)
@samuelcolvin is quite busy at the moment and the whole covid situation didn't help. Yet I agree we may need to put more effort on v2 (or at least give more visibility)

@okonos
Copy link
Author

okonos commented Jul 29, 2020

No problem, I believe it should be rather simple to work around.
Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants