Fixed false positive errors relating to unions created from a Type[T] type.

This commit is contained in:
Eric Traut 2021-06-14 17:10:11 -07:00
parent b5849e9985
commit a8e7c27abe
4 changed files with 40 additions and 4 deletions

View File

@ -5913,6 +5913,9 @@ export function createTypeEvaluator(
} else {
typeResult = getTypeArg(expr, adjFlags);
}
typeResult.type = transformTypeObjectToClass(typeResult.type);
return typeResult;
};
@ -10023,7 +10026,7 @@ export function createTypeEvaluator(
}
return {
type: combineTypes([leftType, adjustedRightType]),
type: combineTypes([transformTypeObjectToClass(leftType), transformTypeObjectToClass(adjustedRightType)]),
node,
};
}

View File

@ -1830,7 +1830,7 @@ export function _transformTypeVars(
if (replacementType && isObject(replacementType)) {
classType = ClassType.cloneForSpecialization(
type.classType,
[ObjectType.create(replacementType.classType)],
[replacementType],
/* usTypeArgumentExplicit */ true
);
}

View File

@ -11,6 +11,7 @@ import { assert } from '../common/debug';
import { ExpressionNode, ParameterCategory } from '../parser/parseNodes';
import { FunctionDeclaration } from './declaration';
import { Symbol, SymbolTable } from './symbol';
import { transformTypeObjectToClass } from './typeUtils';
export const enum TypeCategory {
// Name is not bound to a value of any type.
@ -2159,7 +2160,8 @@ export function findSubtype(type: Type, filter: (type: UnionableType | NeverType
export function isUnionableType(subtypes: Type[]): boolean {
let typeFlags = TypeFlags.Instance | TypeFlags.Instantiable;
for (const subtype of subtypes) {
for (let subtype of subtypes) {
subtype = transformTypeObjectToClass(subtype);
typeFlags &= subtype.flags;
}

View File

@ -1,7 +1,7 @@
# This sample tests the alternative syntax for unions as
# documented in PEP 604.
from typing import Callable, Generic, Literal, TypeVar
from typing import Callable, Generic, Literal, TypeVar, Union
def foo1(a: int):
@ -43,3 +43,34 @@ def foo5(a: str):
t1: Literal["str | None"] = reveal_type(helper(a))
t2: Literal["str | None"] = reveal_type(Baz[str].qux)
T = TypeVar("T")
TT = TypeVar("TT", bound=type)
def decorator1(value: type[T]) -> type[T]:
...
def decorator2(value: TT) -> TT:
...
class ClassA:
class ClassA_A:
pass
@decorator1
class ClassA_B:
pass
@decorator2
class ClassA_C:
pass
a_or_str: "ClassA.ClassA_A | str"
b_or_str: "ClassA.ClassA_B | str"
b_or_str_Union: Union[ClassA.ClassA_B, str]
c_or_str: "ClassA.ClassA_C | str"