@@ -3104,3 +3104,114 @@ foo(t2)
31043104foo(t3) # E: Argument 1 to "foo" has incompatible type "C[Unpack[tuple[Any, ...]], str]"; expected "C[int, Unpack[tuple[int, ...]], int]"
31053105foo(t4)
31063106[builtins fixtures/tuple.pyi]
3107+
3108+ [case testInferAgainstVariadicAnySplit]
3109+ from typing import Generic, TypeVar, Optional, Any
3110+ from typing_extensions import TypeVarTuple, Unpack
3111+
3112+ T = TypeVar("T", bound=Any)
3113+ Ts = TypeVarTuple("Ts")
3114+
3115+ class Result(Generic[Unpack[Ts]]):
3116+ def foo(self: Result[T, Unpack[tuple[Any, ...]]]) -> Optional[T]: ...
3117+ def bar(self: Result[Unpack[tuple[Any, ...]], T]) -> Optional[T]: ...
3118+
3119+ result: Result[Unpack[tuple[Any, ...]]]
3120+ reveal_type(result.foo) # N: Revealed type is "def () -> Any | None"
3121+ reveal_type(result.bar) # N: Revealed type is "def () -> Any | None"
3122+ [builtins fixtures/tuple.pyi]
3123+
3124+ [case testInferAgainstVariadicPrefixProtocol]
3125+ from typing import Any, Protocol, TypeVar
3126+ from typing_extensions import TypeVarTuple, Unpack
3127+
3128+ T = TypeVar("T")
3129+ Ts = TypeVarTuple("Ts")
3130+
3131+ class WithTuple(Protocol[Unpack[Ts]]):
3132+ tup: tuple[Unpack[Ts]]
3133+
3134+ def get_tuple(e: WithTuple[Unpack[Ts]]) -> tuple[Unpack[Ts]]:
3135+ return e.tup
3136+
3137+ def get_first(e: WithTuple[T, Unpack[tuple[Any, ...]]]) -> T:
3138+ return e.tup[0]
3139+
3140+ class X:
3141+ tup: tuple[int, str]
3142+
3143+ reveal_type(get_tuple(X())) # N: Revealed type is "tuple[builtins.int, builtins.str]"
3144+ reveal_type(get_first(X())) # N: Revealed type is "builtins.int"
3145+ [builtins fixtures/tuple.pyi]
3146+
3147+ [case testInferAgainstVariadicPrefixSuffix]
3148+ from typing import Any, Protocol, TypeVar
3149+ from typing_extensions import TypeVarTuple, Unpack
3150+
3151+ T = TypeVar("T")
3152+ T1 = TypeVar("T1")
3153+ T2 = TypeVar("T2")
3154+ T3 = TypeVar("T3")
3155+ T4 = TypeVar("T4")
3156+ Ts = TypeVarTuple("Ts")
3157+
3158+ def first_last(t: tuple[T1, Unpack[tuple[Any, ...]], T2]) -> tuple[T1, T2]: ...
3159+ def first_last_2(t: tuple[T1, T2, Unpack[Ts], T3, T4]) -> tuple[tuple[T1, T2, T3, T4], tuple[Unpack[Ts]]]: ...
3160+ def first_last_middle(t: tuple[T1, Unpack[Ts], T2]) -> tuple[tuple[T1, T2], tuple[Unpack[Ts]]]: ...
3161+
3162+ t1: tuple[Any, ...]
3163+ t2i: tuple[str, Unpack[tuple[int, ...]], bytes]
3164+ t2a: tuple[str, Unpack[tuple[Any, ...]], bytes]
3165+ t3: tuple[str, bytes, Unpack[tuple[int, ...]], float, bool]
3166+
3167+ reveal_type(first_last(t1)) # N: Revealed type is "tuple[Any, Any]"
3168+ reveal_type(first_last(t2i)) # N: Revealed type is "tuple[builtins.str, builtins.bytes]"
3169+ reveal_type(first_last(t3)) # N: Revealed type is "tuple[builtins.str, builtins.bool]"
3170+
3171+ reveal_type(first_last_2(t1)) # N: Revealed type is "tuple[tuple[Any, Any, Any, Any], builtins.tuple[Any, ...]]"
3172+ reveal_type(first_last_2(t2a)) # N: Revealed type is "tuple[tuple[builtins.str, Any, Any, builtins.bytes], builtins.tuple[Any, ...]]"
3173+ reveal_type(first_last_2(t3)) # N: Revealed type is "tuple[tuple[builtins.str, builtins.bytes, builtins.float, builtins.bool], builtins.tuple[builtins.int, ...]]"
3174+
3175+ reveal_type(first_last_middle(t3)) # N: Revealed type is "tuple[tuple[builtins.str, builtins.bool], tuple[builtins.bytes, Unpack[builtins.tuple[builtins.int, ...]], builtins.float]]"
3176+ [builtins fixtures/tuple.pyi]
3177+
3178+ [case testInferAgainstVariadicPrefixSuffix2]
3179+ from typing import Any, TypeVar, Generic
3180+ from typing_extensions import TypeVarTuple, Unpack
3181+
3182+ T = TypeVar("T")
3183+ T1 = TypeVar("T1")
3184+ T2 = TypeVar("T2")
3185+ Ts = TypeVarTuple("Ts")
3186+
3187+ def mix(x: tuple[T1, T2, Unpack[Ts]]) -> tuple[T1, T2, tuple[Unpack[Ts]]]: ...
3188+ a: tuple[str, Unpack[tuple[Any, ...]], bytes, float]
3189+
3190+ reveal_type(mix(a)) # N: Revealed type is "tuple[builtins.str, Any, tuple[Unpack[builtins.tuple[Any, ...]], builtins.bytes, builtins.float]]"
3191+
3192+ class C(Generic[T1, Unpack[Ts], T2]):
3193+ start: T1
3194+ end: T2
3195+ middle: tuple[Unpack[Ts]]
3196+
3197+ c: C[str, bool, Unpack[tuple[int, ...]]]
3198+ reveal_type(c) # N: Revealed type is "__main__.C[builtins.str, builtins.bool, Unpack[builtins.tuple[builtins.int, ...]]]"
3199+ reveal_type(c.start) # N: Revealed type is "builtins.str"
3200+ reveal_type(c.middle) # N: Revealed type is "tuple[builtins.bool, Unpack[builtins.tuple[builtins.int, ...]]]"
3201+ reveal_type(c.end) # N: Revealed type is "builtins.int"
3202+
3203+ cs: C[Unpack[tuple[int, ...]], str, bool]
3204+ reveal_type(cs) # N: Revealed type is "__main__.C[Unpack[builtins.tuple[builtins.int, ...]], builtins.str, builtins.bool]"
3205+ reveal_type(cs.start) # N: Revealed type is "builtins.int"
3206+ reveal_type(cs.middle) # N: Revealed type is "tuple[Unpack[builtins.tuple[builtins.int, ...]], builtins.str]"
3207+ reveal_type(cs.end) # N: Revealed type is "builtins.bool"
3208+
3209+ def mix2(x: tuple[T1, T, T2]) -> tuple[T, tuple[T1, T2]]: ...
3210+ b1: tuple[int, str, Unpack[tuple[Any, ...]]]
3211+ b2: tuple[int, Unpack[tuple[Any, ...]], str]
3212+ b3: tuple[Unpack[tuple[Any, ...]], int, str]
3213+
3214+ reveal_type(mix2(b1)) # N: Revealed type is "tuple[builtins.str, tuple[builtins.int, Any]]"
3215+ reveal_type(mix2(b2)) # N: Revealed type is "tuple[Any, tuple[builtins.int, builtins.str]]"
3216+ reveal_type(mix2(b3)) # N: Revealed type is "tuple[builtins.int, tuple[Any, builtins.str]]"
3217+ [builtins fixtures/tuple.pyi]
0 commit comments