Support expand_type with ParamSpec.{args,kwargs}
#20119
Open
+150
−9
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 #19839.
Looks like it was relatively easy to do the right way, let me try! When splitting a callable/parameters into args and kwargs, we have the following options:
*args, required unless has a default. If we encounter such required arg, all previously collected optional args become required (this only happens due to faulty TVT expansion somewhere; probably I should look into that too)**kwargs, required unless has a default*argsas anUnpack(possibly normalized by tuple constructor)**kwargsand is only used if there are no kwargs with known names, because PEP 728 is not yet implemented, so we have to choose betweendictandTypedDict. (thoughts? Maybe it is better to preferdictwithunion(kwarg, *kwargs.values())as value type? Either way I do not consider this question important as PEP728 will be eventually implemented, and we'll haveextra_itemsfor ourTypedDicts)Applying these steps to every argument in order, we collect required and optional args and kwargs candidates. Now, the type of
**kwargsis aTypedDictif we know any keys,dict[str, KwargType]if we only have something like**kw: str, anddict[str, Never]if no kwargs were found.The type of
*argsis union of all prefixes ofoptional_argsconcatenated withrequired_args: all required args must be there, and optional args can only be passed in order. Since it is uncommon to have a function with more than 10-20 args, I think this union is a reasonable solution.