Fixed a bug that results in incorrect type narrowing for a type guard function that uses TypeIs[type[T]]. This addresses #7946. (#7947)

This commit is contained in:
Eric Traut 2024-05-18 00:11:08 -07:00 committed by GitHub
parent 7d146aad07
commit 017f7c2767
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 13 deletions

View File

@ -23549,6 +23549,10 @@ export function createTypeEvaluator(
}
}
if (ClassType.isBuiltIn(destType, 'type') && (srcType.instantiableNestingLevel ?? 0) > 0) {
return true;
}
if (
!isSpecialFormClass(expandedSrcType, flags) &&
assignClass(

View File

@ -1343,19 +1343,6 @@ function narrowTypeForIsInstanceInternal(
let concreteFilterType = evaluator.makeTopLevelTypeVarsConcrete(filterType);
if (isInstantiableClass(concreteFilterType)) {
// If the class was implicitly specialized (e.g. because its type
// parameters have default values), replace the default type arguments
// with Unknown.
if (concreteFilterType.typeArguments && !concreteFilterType.isTypeArgumentExplicit) {
concreteFilterType = specializeWithUnknownTypeArgs(
ClassType.cloneForSpecialization(
concreteFilterType,
/* typeArguments */ undefined,
/* isTypeArgumentExplicit */ false
)
);
}
let filterIsSuperclass: boolean;
let filterIsSubclass: boolean;
@ -1363,6 +1350,19 @@ function narrowTypeForIsInstanceInternal(
filterIsSuperclass = evaluator.assignType(filterType, concreteVarType);
filterIsSubclass = evaluator.assignType(concreteVarType, filterType);
} else {
// If the class was implicitly specialized (e.g. because its type
// parameters have default values), replace the default type arguments
// with Unknown.
if (concreteFilterType.typeArguments && !concreteFilterType.isTypeArgumentExplicit) {
concreteFilterType = specializeWithUnknownTypeArgs(
ClassType.cloneForSpecialization(
concreteFilterType,
/* typeArguments */ undefined,
/* isTypeArgumentExplicit */ false
)
);
}
filterIsSuperclass = isIsinstanceFilterSuperclass(
evaluator,
varType,

View File

@ -119,3 +119,11 @@ def func7(names: tuple[str, ...]):
reveal_type(names, expected_text="tuple[str, str]")
else:
reveal_type(names, expected_text="tuple[str, ...]")
def is_int(obj: type) -> TypeIs[type[int]]: ...
def func8(x: type) -> None:
if is_int(x):
reveal_type(x, expected_text="type[int]")