Fixed bug that resulted in false positive when evaluating a function call involving a TypeVarTuple under certain circumstances. This addresses #7820. (#7917)

This commit is contained in:
Eric Traut 2024-05-14 14:30:31 -07:00 committed by GitHub
parent 6c7470d51e
commit 3ae32dc927
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 14 deletions

View File

@ -24874,6 +24874,13 @@ export function createTypeEvaluator(
srcLastToPackIndex = srcDetails.params.length;
}
// If both the source and dest have an *args parameter but the dest's is
// in a later position, then we can't assign the source's *args to the dest.
// Don't make any adjustment in this case.
if (srcDetails.argsIndex !== undefined && destDetails.argsIndex > srcDetails.argsIndex) {
return;
}
const destFirstNonPositional = destDetails.firstKeywordOnlyIndex ?? destDetails.params.length;
const suffixLength = destFirstNonPositional - destDetails.argsIndex - 1;
const srcPositionalsToPack = srcDetails.params.slice(destDetails.argsIndex, srcLastToPackIndex - suffixLength);
@ -25055,7 +25062,9 @@ export function createTypeEvaluator(
continue;
}
if (
if (isUnpacked(srcParamType)) {
canAssign = false;
} else if (
!assignFunctionParameter(
destParamType,
srcParamType,

View File

@ -2,7 +2,16 @@
# as an argument to another generic function multiple times.
from dataclasses import dataclass
from typing import Any, Generic, Literal, ParamSpec, TypeVar, Callable, overload
from typing import (
Any,
Generic,
Literal,
ParamSpec,
TypeVar,
Callable,
TypeVarTuple,
overload,
)
T = TypeVar("T")
A = TypeVar("A")
@ -13,6 +22,7 @@ X = TypeVar("X")
Y = TypeVar("Y")
Z = TypeVar("Z")
P = ParamSpec("P")
Ts = TypeVarTuple("Ts")
def identity(x: T) -> T:
@ -90,8 +100,7 @@ class Pair(Generic[A, B]):
right: B
def func1(f: Callable[[A], B]) -> Callable[[Pair[A, X]], Pair[B, X]]:
...
def func1(f: Callable[[A], B]) -> Callable[[Pair[A, X]], Pair[B, X]]: ...
def test_3(pair: Pair[Pair[A, B], C]) -> Pair[Pair[A, B], C]:
@ -118,22 +127,18 @@ def test_4(pair: Pair[Pair[Pair[A, B], C], D]) -> Pair[Pair[Pair[A, B], C], D]:
@overload
def test_5(
a: Callable[P, type[T]], *, b: Literal[False, None] = ...
) -> type[list[type[T]]]:
...
) -> type[list[type[T]]]: ...
@overload
def test_5(a: T, *args: int, b: Literal[False, None] = ...) -> type[list[T]]:
...
def test_5(a: T, *args: int, b: Literal[False, None] = ...) -> type[list[T]]: ...
@overload
def test_5(a: T, *args: int, b: Literal[True] = ...) -> type[list[T]]:
...
def test_5(a: T, *args: int, b: Literal[True] = ...) -> type[list[T]]: ...
def test_5(a: Any, *args: int, b: Any = ...) -> Any:
...
def test_5(a: Any, *args: int, b: Any = ...) -> Any: ...
val3 = test_5(test_5, **{})
@ -149,8 +154,7 @@ reveal_type(
)
def test_6(g: Callable[[B], C]) -> Callable[[Callable[[A], B]], Callable[[A], C]]:
...
def test_6(g: Callable[[B], C]) -> Callable[[Callable[[A], B]], Callable[[A], C]]: ...
val5 = test_6(test_6)
@ -169,3 +173,10 @@ def test_7(
expected_text="((A(1)@test_6) -> ((A(2)@test_6) -> C@test_7)) -> ((A(1)@test_6) -> ((A(2)@test_6) -> D@test_7))",
)
return val6
def test_8(fn: Callable[[*Ts], Callable[[A], B]]) -> Callable[[A, *Ts], B]: ...
def test_9(x: Callable[[bool], Callable[[int], Callable[[str], None]]]):
test_8(test_8(x))