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

Mypy handling initializing Pydantic models with dict values incorrectly #17244

Closed
dpitch40 opened this issue May 14, 2024 · 2 comments
Closed
Labels
bug mypy got something wrong

Comments

@dpitch40
Copy link

dpitch40 commented May 14, 2024

Bug Report

Mypy is flagging code pasted directly from the Pydantic docs (involving initializing models with dictionary values for nested classes) as incorrectly typed.

To Reproduce

Save the following code (directly from the current Pydantic docs to a Python file.

from typing import Literal, Union

from pydantic import BaseModel, Field, ValidationError


class Cat(BaseModel):
    pet_type: Literal['cat']
    meows: int


class Dog(BaseModel):
    pet_type: Literal['dog']
    barks: float


class Lizard(BaseModel):
    pet_type: Literal['reptile', 'lizard']
    scales: bool


class Model(BaseModel):
    pet: Union[Cat, Dog, Lizard] = Field(..., discriminator='pet_type')
    n: int


print(Model(pet={'pet_type': 'dog', 'barks': 3.14}, n=1))

Then run mypy on it.

Expected Behavior

Mypy should validate the above code without errors, as it is example code directly from Pydantic's docs.

Actual Behavior

test.py:26: error: Argument "pet" to "Model" has incompatible type "dict[str, object]"; expected "Cat | Dog | Lizard"  [arg-type]
Found 1 error in 1 file (checked 1 source file

Your Environment

  • Mypy version used: 1.10.0
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): mypy.ini
  • Python version used: 3.10.11
  • Pydantic version used: 2.7.1
@dpitch40 dpitch40 added the bug mypy got something wrong label May 14, 2024
@dpitch40 dpitch40 changed the title Mypy handling Pydantic discriminated unions incorrectly Mypy handling initializing Pydantic models with dict values incorrectly May 14, 2024
@dpitch40
Copy link
Author

I can also reproduce it with this code from the Pydantic docs.

from typing import List, Optional

from pydantic import BaseModel


class Foo(BaseModel):
    count: int
    size: Optional[float] = None


class Bar(BaseModel):
    apple: str = 'x'
    banana: str = 'y'


class Spam(BaseModel):
    foo: Foo
    bars: List[Bar]


m = Spam(foo={'count': 4}, bars=[{'apple': 'x1'}, {'apple': 'x2'}])

The Pydantic docs appear to treat code initializing nested classes using dictionaries containing the fields and values as correct (and the code does work for me if I run it), but Mypy is flagging such code as incorrect.

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented May 20, 2024

mypy isn't going to support this. I think pydantic has a mypy plugin that might help with this, you could ask on their repo.

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

2 participants