-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 with **kwargs
with multiple arguments
#18759
Comments
Maybe too late to change now, but this can work well and be much safer if the inferred type for all dict literals with literal str keys is changed to the appropriate TypedDict. |
I swear there was an earlier issue about the same thing but I can't find anything... This is an issue with the error message IMO. mypy is correct and shouldn't let this typecheck. If you want gradual typing then annotate |
Of course I can work-around any issue by throwing Any at things, but this is still a false positive for a completely valid code. False positives are very bad, because they teach people to silence errors without thinking. The correct thing to do, which is not hard, is to check that the value type in the dict is a subset of the union of the types of all arguments not passed explicitly. |
So is something like Mostly rhetorical question: where do you draw the line and why? Is there a principled argument for line-drawing? # case 1
def f(x: int, y: str) -> None:
...
f(**{"x": 5, "y": "a"})
# case 2
def f(x: int, y: str) -> None:
...
a = {"x": 5, "y": "a"}
f(**a)
# case 3a
a = {"x": 5, "y": "a"}
x: int = a["x"]
# case 4a
a = {"x": 5, 1: "a"} # typed dicts cannot have int keys
x: int = a["x"]
# case 3b
def f(x: int, y: str) -> None:
...
a = [5, "a"]
f(*a)
# case 4b
a = [5, "a"]
x: int = a[0] Personally I draw it before case 1, though I see the pragmatic case for inferring TypedDict (which would lead until but not including 4a and 3b). I don't envy anyone trying to teach the "pragmatic" inference rules though. |
class _Kwargs(TypedDict):
x: int
y: str
def foo(x: int, y: str) -> None:
return
def bar() -> None:
args: _Kwargs = {"x": 123, "y": "abc"}
foo(**args) I recently highlighted this pattern in a video of mine |
To Reproduce
https://mypy-play.net/?mypy=latest&python=3.12&gist=97467e43c0e316f2f9fd1d6f0c2bd432
Expected Behavior
This should type check without errors. It's fairly common and while not 100% safe, checking the type of
args
is not enough anyway -- you have to check the values of the keys. This information is not present in types.Actual Behavior
This generates these errors:
Note that two contradictory errors are generated on the same line.
Your Environment
The text was updated successfully, but these errors were encountered: