-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Closed
Labels
testsTests in the Lib/test dirTests in the Lib/test dirtopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
After merging #102808 I realized that I've missed several important cases.
Right now substitution algorithm has these lines:
Lines 1477 to 1488 in 2cdc518
if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): | |
# Consider the following `Callable`. | |
# C = Callable[[int], str] | |
# Here, `C.__args__` should be (int, str) - NOT ([int], str). | |
# That means that if we had something like... | |
# P = ParamSpec('P') | |
# T = TypeVar('T') | |
# C = Callable[P, T] | |
# D = C[[int, str], float] | |
# ...we need to be careful; `new_args` should end up as | |
# `(int, str, float)` rather than `([int, str], float)`. | |
new_args.extend(new_arg) |
It is tested. But, it is never tested for the nested arguments:
Lines 1500 to 1511 in 2cdc518
elif isinstance(old_arg, tuple): | |
# Corner case: | |
# P = ParamSpec('P') | |
# T = TypeVar('T') | |
# class Base(Generic[P]): ... | |
# Can be substituted like this: | |
# X = Base[[int, T]] | |
# In this case, `old_arg` will be a tuple: | |
new_args.append( | |
tuple(self._make_substitution(old_arg, new_arg_by_param)), | |
) | |
else: |
I think that Callable
is complex and important enought to be covered with as many cases as possible. Furthermore, Callable
can be nested deeply in real types and we need to be sure that this use-case works as intended.
I will send a PR with more tests :)
Related #88965
Linked PRs
Metadata
Metadata
Assignees
Labels
testsTests in the Lib/test dirTests in the Lib/test dirtopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error