Fixed recent regression that resulted in false positives when checking the type of a "self" parameter within a metaclass when the type annotation was of the form Type[T].

This commit is contained in:
Eric Traut 2021-03-29 19:50:53 -07:00
parent 75e43b3fc5
commit b1ed52b662
2 changed files with 49 additions and 3 deletions

View File

@ -3123,8 +3123,15 @@ export function createTypeEvaluator(
return combineConstrainedTypes(constrainedTypes);
}
const objType = objectType || AnyType.create();
return TypeBase.isInstantiable(subtype) ? convertToInstantiable(objType) : objType;
// Convert to an "object" or "type" instance depending on whether
// it's instantiable.
if (TypeBase.isInstantiable(subtype)) {
return typeClassType && isClass(typeClassType)
? ObjectType.create(typeClassType)
: AnyType.create();
}
return objectType || AnyType.create();
}
return subtype;
@ -16251,6 +16258,40 @@ export function createTypeEvaluator(
filteredTypes.push(filterType);
}
}
} else if (isTypeVar(filterType) && TypeBase.isInstantiable(filterType)) {
// Handle the case where the filter type is Type[T] and the unexpanded
// subtype is some instance type, possibly T.
if (isInstanceCheck && TypeBase.isInstance(unexpandedType)) {
if (isTypeVar(unexpandedType) && isTypeSame(convertToInstance(filterType), unexpandedType)) {
// If the unexpanded subtype is T, we can definitively filter
// in both the positive and negative cases.
if (isPositiveTest) {
filteredTypes.push(unexpandedType);
}
} else {
if (isPositiveTest) {
filteredTypes.push(convertToInstance(filterType));
} else {
// If the unexpanded subtype is some other instance, we can't
// filter anything because it might be an instance.
filteredTypes.push(unexpandedType);
isClassRelationshipIndeterminate = true;
}
}
} else if (!isInstanceCheck && TypeBase.isInstantiable(unexpandedType)) {
if (isTypeVar(unexpandedType) && isTypeSame(filterType, unexpandedType)) {
if (isPositiveTest) {
filteredTypes.push(unexpandedType);
}
} else {
if (isPositiveTest) {
filteredTypes.push(filterType);
} else {
filteredTypes.push(unexpandedType);
isClassRelationshipIndeterminate = true;
}
}
}
}
}

View File

@ -1,7 +1,7 @@
# This sample validates that parameter types specified for "self"
# and "cls" parameters are compatible with the containing class.
from typing import Type, TypeVar
from typing import Iterator, Type, TypeVar
class Parent:
@ -64,3 +64,8 @@ class Child1:
@classmethod
def cm6(cls: Type[_T]) -> _T:
...
class MyMeta(type):
def m1(self: Type[_T]) -> Iterator[_T]:
...