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

Passing kwargs to partial functions via dict extraction is not properly recognized with v1.11.0 #17569

Closed
glatterf42 opened this issue Jul 23, 2024 · 1 comment
Labels
bug mypy got something wrong

Comments

@glatterf42
Copy link

glatterf42 commented Jul 23, 2024

Apologies if this is intentional behaviour instead of a bug. If it is, I couldn't find it in the changelog related to the type-checking of partial() that came with 1.11. So this issue might serve as a documentation of workarounds, too.

Bug Report

Prior to version 1.11 of mypy, the arguments passed to functools.partial() were not checked. With the newly introduced checks, passing in optional arguments by unpacking a dictionary does no longer work. **dict[str, str] (for example) is instead thought to refer to the first positional argument, which might have an entirely different type.
For a recent example from GitHub Actions in our repository, please see here.
For future reference: the second workaround in the above example was inspired by stackoverflow.

To Reproduce

Please see https://mypy-play.net/?mypy=1.11.0&python=3.12&gist=927391e497547426684526ac48c5f908 for a reproducible playground example of what I'm talking about.

Expected Behavior

Not sure if there is any way mypy could distinguish between a **dict[str, str] being the correct type for the first positional argument or this argument not being specified for this partial object. That would be great, though.

Actual Behavior

From the playground example: main.py:15: error: Argument 1 to "foo" has incompatible type "**dict[str, str]"; expected "int" [arg-type].

Your Environment

Not sure if this is necessary with the playground example provided above. Please let me know if it is. For the playground example, I used mypy 1.11.0 with Python 3.12 and none of the options.

@glatterf42 glatterf42 added the bug mypy got something wrong label Jul 23, 2024
@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Oct 8, 2024

Thanks for the thorough issue and discussing the workarounds. This is is basically preexisting mypy behaviour that is exposed now that we actually check functools.partial at all:

kwargs: dict[str, str] = {"key": "lorem", "name": "ipsum"}
def foo2(key: str | None = None, name: str | None = None, value: int | None = None): ...
foo2(**kwargs)  # mypy complains because it doesn't know what keys kwargs are, and if there is a "value" in kwargs then there will be a TypeError

There are several duplicate issues about the choice to be sound here, see e.g. #17642

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 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