Repository navigation
Conversation
When functools.partial() received a **mapping, every positional-or-keyword parameter that the mapping could fill was made keyword-only in the partially applied signature. A plain dict may not contain those keys, so calling the result positionally is fine at runtime and mypy already accepts the equivalent direct call f(1, "x", **kwargs). This led to false "Too many positional arguments" errors. Keep such parameters as optional positional-or-keyword parameters. A TypedDict is still treated as providing its keys, matching how mypy checks direct calls, and an explicit keyword argument still makes the parameter keyword-only. Fixes python#18644 Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>
Contributor
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18644
When
functools.partial()receives a**mappingargument, the plugin turned every positional parameter the mapping could fill into a keyword-only one. A plain dict may not contain those keys, so passing them positionally afterwards is fine at runtime, and mypy already accepts the equivalent direct call:Now a positional parameter that is matched only by non-TypedDict
**arguments stays positional (and optional) in the partial's signature. Parameters given by explicit keyword (partial(f, b="x")) and parameters filled from a TypedDict**(whose keys mypy treats as present, as in direct calls) remain keyword-only, unchanged.The
Argument 1 has incompatible type "**dict[str, int]"error from the issue's first example is unchanged: the direct call reports the same thing.Test:
testFunctoolsPartialDictUnpackKeepsPositionalincheck-functools.testcovers positional/partial/keyword calls afterpartial(fn, **d), a function with/and*args, mixing a positional argument with**d, errors that must still be reported, and the explicit-keyword case. It fails on master and passes with the change;check-functools.testand the fulltestcheck.pysuite pass locally.I used AI assistance while preparing this change; I reviewed the diff and ran the tests above.