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

Pyright/Pylance typing error when overriding __pydantic_extra__ type #9187

Open
1 task done
zEdS15B3GCwq opened this issue Apr 8, 2024 · 8 comments · May be fixed by #9659
Open
1 task done

Pyright/Pylance typing error when overriding __pydantic_extra__ type #9187

zEdS15B3GCwq opened this issue Apr 8, 2024 · 8 comments · May be fixed by #9659
Labels
bug V2 Bug related to Pydantic V2 good first issue help wanted Pull Request welcome

Comments

@zEdS15B3GCwq
Copy link

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Similar to #9147 and #7094, but those seem to be focused on TypeAdapter and I'm unsure how closely those are related. Sorry if this is a duplicate.

See code below. Pylance warns that __pydantic_extra__ should also be specified when instantiating the class. I believe this warning should not appear.

Example Code

from pydantic import BaseModel, ConfigDict


class Model(BaseModel):
    __pydantic_extra__: dict[str, int]

    a: int

    model_config = ConfigDict(extra="allow")


m = Model(a=1) # Argument missing for parameter "__pydantic_extra__" Pylance (reportCallIssue)

Python, Pydantic & OS Version

pydantic version: 2.6.4
        pydantic-core version: 2.16.3
          pydantic-core build: profile=release pgo=true
                 install path: C:\Test\.venv\Lib\site-packages\pydantic
               python version: 3.12.2 (tags/v3.12.2:6abddd9, Feb  6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]
                     platform: Windows-11-10.0.22631-SP0
             related packages: typing_extensions-4.11.0
                       commit: unknown
@zEdS15B3GCwq zEdS15B3GCwq added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Apr 8, 2024
@sydney-runkle
Copy link
Member

@zEdS15B3GCwq,

Thanks for reporting this! Yep, looks like a bug. Great first issue, for anyone interested!

@sydney-runkle sydney-runkle added good first issue bug V2 Bug related to Pydantic V2 help wanted Pull Request welcome and removed bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Apr 9, 2024
@Viicos
Copy link
Contributor

Viicos commented Apr 10, 2024

This is unfortunate, as dataclass_transform (which is used to make type checkers aware of BaseModel acting like a dataclass) does not provide any way to "ignore" fields from the synthesized __init__ method.

A workaround is to define your model as:

from pydantic import ConfigDict, Field


class MyModel(BaseModel):
    __pydantic_extra__: dict[str, int] = Field(init=False)

    a: int

    model_config = ConfigDict(extra="allow")

Ideally, this feature could have been implemented as a config value, e.g. ConfigDict(extra_type=int) or similar, but the current implementation (having to annotate __pydantic_extra__) makes it nice as you get type checking support as well.

@blueTurtz
Copy link
Contributor

@sydney-runkle I can pick this up.

@sydney-runkle
Copy link
Member

@Viicos,

What do you think about this approach here (we might need some docs changes):

from pydantic import BaseModel, ConfigDict
from pydantic.fields import PrivateAttr as _PrivateAttr


class Model(BaseModel):
    __pydantic_extra__: dict[str, int] = _PrivateAttr()

    a: int

    model_config = ConfigDict(extra="allow")


m = Model(a=1)

Thinking about this approach on the heels of #9293

@sydney-runkle
Copy link
Member

Also, here's the relevant docs for reference: https://docs.pydantic.dev/latest/concepts/models/#extra-fields

@Viicos
Copy link
Contributor

Viicos commented May 21, 2024

Looks good as a workaround, so the docs can probably be updated with the added PrivateAttr. #9293 already applied the change on the BaseModel.__pydantic_extra__ annotation :)

@blueTurtz
Copy link
Contributor

#9187 (comment)
Using mypy I found that the following issue is raised when using the Example Code from the link above

(pydantic-env) ➜  tmp mypy 9187.py
9187.py:12: error: Missing named argument "__pydantic_extra__" for "Model"  [call-arg]
Found 1 error in 1 file (checked 1 source file)

@dmontagu
Copy link
Contributor

dmontagu commented Jun 14, 2024

When #9659 gets merged, I think the solution to this will be to do:

from pydantic import BaseModel, Field


class MyModel(BaseModel, extra='allow'):
    __pydantic_extra__: dict[str, int] = Field(init=False)

(or similar, with whatever type hint you want on the pydantic extra)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2 good first issue help wanted Pull Request welcome
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants