mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-07 05:17:10 +03:00
Improved isinstance
type narrowing logic to retain type arguments in cases where the corresponding type parameter is bound or constrained.
This commit is contained in:
parent
78f2a94943
commit
01ae3bf97c
@ -2926,6 +2926,10 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
return combineTypes(typesToCombine);
|
||||
}
|
||||
|
||||
if (subtype.details.isExemptFromBoundCheck) {
|
||||
return AnyType.create();
|
||||
}
|
||||
|
||||
// Convert to an "object" or "type" instance depending on whether
|
||||
// it's instantiable.
|
||||
if (TypeBase.isInstantiable(subtype)) {
|
||||
@ -7351,6 +7355,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
const typeVar = TypeVarType.createInstance(`__source${index}`);
|
||||
typeVar.details.isSynthesized = true;
|
||||
typeVar.details.synthesizedIndex = index;
|
||||
typeVar.details.isExemptFromBoundCheck = true;
|
||||
return typeVar;
|
||||
});
|
||||
|
||||
|
@ -1714,6 +1714,7 @@ export interface TypeVarDetails {
|
||||
isSynthesized: boolean;
|
||||
isSynthesizedSelf?: boolean | undefined;
|
||||
synthesizedIndex?: number | undefined;
|
||||
isExemptFromBoundCheck?: boolean;
|
||||
|
||||
// Used for recursive type aliases.
|
||||
recursiveTypeAliasName?: string | undefined;
|
||||
|
@ -2,16 +2,16 @@
|
||||
# narrow the type of a specialized class to a subclass where the type
|
||||
# arguments are implied by the type arguments of the wider class.
|
||||
|
||||
from typing import Generic, Iterable, Literal, Sequence, Type, TypeVar, Union
|
||||
from typing import Any, Generic, Iterable, Literal, Sequence, Type, TypeVar, Union
|
||||
|
||||
T = TypeVar("T")
|
||||
_T1 = TypeVar("_T1")
|
||||
|
||||
|
||||
class SomeClass(Generic[T]):
|
||||
class SomeClass(Generic[_T1]):
|
||||
...
|
||||
|
||||
|
||||
class OtherClass(SomeClass[T]):
|
||||
class OtherClass(SomeClass[_T1]):
|
||||
...
|
||||
|
||||
|
||||
@ -35,6 +35,43 @@ def func2(
|
||||
)
|
||||
|
||||
|
||||
def func3(value: Iterable[T]) -> Sequence[T] | None:
|
||||
def func3(value: Iterable[_T1]) -> Sequence[_T1] | None:
|
||||
if isinstance(value, Sequence):
|
||||
return value
|
||||
|
||||
|
||||
_T2 = TypeVar("_T2", bound=float, covariant=True)
|
||||
|
||||
|
||||
class Parent1(Generic[_T2]):
|
||||
pass
|
||||
|
||||
|
||||
class Child1(Parent1[_T2]):
|
||||
pass
|
||||
|
||||
|
||||
def func4(var: Parent1[int]):
|
||||
if isinstance(var, Child1):
|
||||
t1: Literal["Child1[int]"] = reveal_type(var)
|
||||
|
||||
|
||||
def func5(var: Parent1[Any]):
|
||||
if isinstance(var, Child1):
|
||||
t1: Literal["Child1[Any]"] = reveal_type(var)
|
||||
|
||||
|
||||
_T3 = TypeVar("_T3", float, str)
|
||||
|
||||
|
||||
class Parent2(Generic[_T3]):
|
||||
pass
|
||||
|
||||
|
||||
class Child2(Parent2[_T3]):
|
||||
pass
|
||||
|
||||
|
||||
def func6(var: Parent2[int]):
|
||||
if isinstance(var, Child2):
|
||||
t1: Literal["Child2[int]"] = reveal_type(var)
|
||||
|
Loading…
Reference in New Issue
Block a user