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

False positive 'Invalid value for "Config.extra" [pydantic-config]' #9021

Closed
1 task done
Apakottur opened this issue Mar 15, 2024 · 5 comments · Fixed by #9039
Closed
1 task done

False positive 'Invalid value for "Config.extra" [pydantic-config]' #9021

Apakottur opened this issue Mar 15, 2024 · 5 comments · Fixed by #9039
Labels
bug V2 Bug related to Pydantic V2 mypy related to mypy

Comments

@Apakottur
Copy link

Apakottur commented Mar 15, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Consider this code:

# test.py
from pydantic import BaseModel, ConfigDict

def condition() -> bool:
    return True

class MyModel(BaseModel):
    model_config = ConfigDict(extra="ignore" if condition() else "forbid")
# mypy.toml
[tool.mypy]
plugins = ["pydantic.mypy"]

Running mypy --config mypy.toml test.py gives

test.py:10: error: Invalid value for "Config.extra"  [pydantic-config]
Found 1 error in 1 file (checked 1 source file)

The error is incorrect, since the value is a valid literal in both cases, whicever branch of the condition is executed.

Might be related to #3481.

Example Code

No response

Python, Pydantic & OS Version

pydantic version: 2.6.4
        pydantic-core version: 2.16.3
          pydantic-core build: profile=release pgo=true
                 install path: .venv/lib/python3.12/site-packages/pydantic
               python version: 3.12.2 (main, Feb 25 2024, 16:35:05) [GCC 11.4.0]
                     platform: Linux-6.1.79-060179-generic-x86_64-with-glibc2.35
             related packages: pydantic-settings-2.2.1 mypy-1.9.0 pyright-1.1.353 typing_extensions-4.10.0 pydantic-extra-types-2.6.0
                       commit: unknown
@Apakottur Apakottur added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Mar 15, 2024
@sydney-runkle
Copy link
Member

@Apakottur,

Hmm, thanks for reporting this. Seems like a bug, but a pretty minor one. Maybe @dmontagu has an idea for an easy fix...

@sydney-runkle sydney-runkle added mypy related to mypy and removed pending Awaiting a response / confirmation labels Mar 15, 2024
@Viicos
Copy link
Contributor

Viicos commented Mar 15, 2024

This has to do with how mypy handles union of types (see playground). I don't think Pydantic can do much here.

For reference, pyright will handle this correctly as "ignore" if condition() else "forbid" is inferred as Literal["ignore", "forbid"].

@dmontagu
Copy link
Contributor

dmontagu commented Mar 15, 2024

@Viicos is right; suggested approach compatible with mypy:

# test.py
from pydantic import BaseModel, ConfigDict
from typing_extensions import Literal

def condition() -> bool:
    return True

_my_model_extra: Literal['ignore', 'forbid'] = "ignore" if condition() else "forbid"

class MyModel(BaseModel):
    model_config = ConfigDict(extra=_my_model_extra)

I haven't confirmed this works but I think it should. If it doesn't, I am more confident the following would work:

from pydantic import BaseModel, ConfigDict
from typing_extensions import Literal

def condition() -> bool:
    return True

def _get_my_model_extra() -> Literal['ignore', 'forbid']:
    if condition():
        return 'ignore'
    else:
        return 'forbid'

class MyModel(BaseModel):
    model_config = ConfigDict(extra=_get_my_model_extra())

I'm going to close this issue because I think this is the best we can do, but let us know if none of these approaches work for you and we can reopen it.

@Apakottur
Copy link
Author

Thanks for the respone @dmontagu , I've tried both your suggestions and they both still give the same error.
Does one of them pass without errors for you?

@dmontagu dmontagu reopened this Mar 18, 2024
@dmontagu
Copy link
Contributor

@Apakottur thanks for the info, I see the problem — the issue is that we have additional checks in the plugin itself. I think I'm going to make this check more lax so it only errors if you use a string or member and it isn't the right value. If you use a conditional expression etc. it just won't type check the value (I think that's hard to do in a plugin, but if anyone knows a good way I will be happy to incorporate it), but note that if you use ConfigDict like you have' you'll get proper type checking from the usual non-plugin type checks, so this seems like a good solution.

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 mypy related to mypy
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants