mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Code cleanup for prefetched types used in type evaluator.
This commit is contained in:
parent
32fa85e3ed
commit
ce229098e6
@ -602,28 +602,28 @@ export function createTypeEvaluator(
|
||||
let expectedTypeCache = new Map<number, Type>();
|
||||
let deferredClassCompletions: DeferredClassCompletion[] = [];
|
||||
let cancellationToken: CancellationToken | undefined;
|
||||
let isBasicTypesInitialized = false;
|
||||
let noneClassType: Type | undefined;
|
||||
let noneType: Type | undefined;
|
||||
let objectType: Type | undefined;
|
||||
let typeClassType: Type | undefined;
|
||||
let unionClassType: Type | undefined;
|
||||
let awaitableProtocolType: Type | undefined;
|
||||
let functionObj: Type | undefined;
|
||||
let tupleClassType: Type | undefined;
|
||||
let boolClassType: Type | undefined;
|
||||
let intClassType: Type | undefined;
|
||||
let strClassType: Type | undefined;
|
||||
let dictClassType: Type | undefined;
|
||||
let typedDictClassType: Type | undefined;
|
||||
let typedDictPrivateClassType: Type | undefined;
|
||||
let supportsKeysAndGetItemProtocolType: Type | undefined;
|
||||
let mappingType: Type | undefined;
|
||||
let printExpressionSpaceCount = 0;
|
||||
let incompleteGenerationCount = 0;
|
||||
|
||||
const returnTypeInferenceContextStack: ReturnTypeInferenceContext[] = [];
|
||||
let returnTypeInferenceTypeCache: Map<number, TypeCacheEntry> | undefined;
|
||||
let isPrefetchedTypesInitialized = false;
|
||||
|
||||
// Various types prefetched from stdlib stubs
|
||||
let noneTypeClass: Type | undefined;
|
||||
let objectClass: Type | undefined;
|
||||
let typeClass: Type | undefined;
|
||||
let unionClass: Type | undefined;
|
||||
let awaitableClass: Type | undefined;
|
||||
let functionClass: Type | undefined;
|
||||
let tupleClass: Type | undefined;
|
||||
let boolClass: Type | undefined;
|
||||
let intClass: Type | undefined;
|
||||
let strClass: Type | undefined;
|
||||
let dictClass: Type | undefined;
|
||||
let typedDictClassType: Type | undefined;
|
||||
let typedDictPrivateClass: Type | undefined;
|
||||
let supportsKeysAndGetItemClass: Type | undefined;
|
||||
let mappingClass: Type | undefined;
|
||||
|
||||
function runWithCancellationToken<T>(token: CancellationToken, callback: () => T): T {
|
||||
try {
|
||||
@ -847,7 +847,7 @@ export function createTypeEvaluator(
|
||||
// context, logging any errors in the process. This may require the
|
||||
// type of surrounding statements to be evaluated.
|
||||
function getType(node: ExpressionNode): Type | undefined {
|
||||
initializedBasicTypes(node);
|
||||
initializePrefetchedTypes(node);
|
||||
|
||||
let type = evaluateTypeForSubnode(node, () => {
|
||||
evaluateTypesForExpressionInContext(node);
|
||||
@ -940,54 +940,44 @@ export function createTypeEvaluator(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function initializedBasicTypes(node: ParseNode) {
|
||||
if (!isBasicTypesInitialized) {
|
||||
function initializePrefetchedTypes(node: ParseNode) {
|
||||
if (!isPrefetchedTypesInitialized) {
|
||||
// Some of these types have cyclical dependencies on each other,
|
||||
// so don't re-enter this block once we start executing it.
|
||||
isBasicTypesInitialized = true;
|
||||
isPrefetchedTypesInitialized = true;
|
||||
|
||||
objectType = getBuiltInObject(node, 'object');
|
||||
typeClassType = getBuiltInType(node, 'type');
|
||||
functionObj = getBuiltInObject(node, 'function');
|
||||
objectClass = getBuiltInType(node, 'object');
|
||||
typeClass = getBuiltInType(node, 'type');
|
||||
functionClass = getBuiltInType(node, 'function');
|
||||
|
||||
unionClassType = getTypesType(node, 'UnionType');
|
||||
if (unionClassType && isClass(unionClassType)) {
|
||||
unionClassType.details.flags |= ClassTypeFlags.SpecialFormClass;
|
||||
unionClass = getTypesType(node, 'UnionType');
|
||||
if (unionClass && isClass(unionClass)) {
|
||||
unionClass.details.flags |= ClassTypeFlags.SpecialFormClass;
|
||||
}
|
||||
|
||||
// Initialize and cache "Collection" to break a cyclical dependency
|
||||
// that occurs when resolving tuple below.
|
||||
getTypingType(node, 'Collection');
|
||||
|
||||
noneClassType = getTypeshedType(node, 'NoneType') ?? UnknownType.create();
|
||||
noneType = isInstantiableClass(noneClassType)
|
||||
? ClassType.cloneAsInstance(noneClassType)
|
||||
: UnknownType.create();
|
||||
|
||||
tupleClassType = getBuiltInType(node, 'tuple');
|
||||
boolClassType = getBuiltInType(node, 'bool');
|
||||
intClassType = getBuiltInType(node, 'int');
|
||||
strClassType = getBuiltInType(node, 'str');
|
||||
dictClassType = getBuiltInType(node, 'dict');
|
||||
noneTypeClass = getTypeshedType(node, 'NoneType') ?? UnknownType.create();
|
||||
tupleClass = getBuiltInType(node, 'tuple');
|
||||
boolClass = getBuiltInType(node, 'bool');
|
||||
intClass = getBuiltInType(node, 'int');
|
||||
strClass = getBuiltInType(node, 'str');
|
||||
dictClass = getBuiltInType(node, 'dict');
|
||||
typedDictClassType = getTypingType(node, 'TypedDict');
|
||||
typedDictPrivateClassType = getTypingType(node, '_TypedDict');
|
||||
awaitableProtocolType = getTypingType(node, 'Awaitable');
|
||||
mappingType = getTypingType(node, 'Mapping');
|
||||
typedDictPrivateClass = getTypingType(node, '_TypedDict');
|
||||
awaitableClass = getTypingType(node, 'Awaitable');
|
||||
mappingClass = getTypingType(node, 'Mapping');
|
||||
|
||||
supportsKeysAndGetItemProtocolType = getTypeshedType(node, 'SupportsKeysAndGetItem');
|
||||
if (!supportsKeysAndGetItemProtocolType) {
|
||||
supportsKeysAndGetItemClass = getTypeshedType(node, 'SupportsKeysAndGetItem');
|
||||
if (!supportsKeysAndGetItemClass) {
|
||||
// Fall back on 'Mapping' if 'SupportsKeysAndGetItem' is not available.
|
||||
supportsKeysAndGetItemProtocolType = mappingType;
|
||||
supportsKeysAndGetItemClass = mappingClass;
|
||||
}
|
||||
|
||||
// Wire up the `Any` class to the special-form version of our internal AnyType.
|
||||
const objectClass = getBuiltInType(node, 'object');
|
||||
if (
|
||||
objectClass &&
|
||||
isInstantiableClass(objectClass) &&
|
||||
typeClassType &&
|
||||
isInstantiableClass(typeClassType)
|
||||
) {
|
||||
if (objectClass && isInstantiableClass(objectClass) && typeClass && isInstantiableClass(typeClass)) {
|
||||
const anyClass = ClassType.createInstantiable(
|
||||
'Any',
|
||||
'typing.Any',
|
||||
@ -996,7 +986,7 @@ export function createTypeEvaluator(
|
||||
ClassTypeFlags.BuiltInClass | ClassTypeFlags.SpecialFormClass,
|
||||
/* typeSourceId */ -1,
|
||||
/* declaredMetaclass */ undefined,
|
||||
/* effectiveMetaclass */ typeClassType
|
||||
/* effectiveMetaclass */ typeClass
|
||||
);
|
||||
anyClass.details.baseClasses.push(objectClass);
|
||||
computeMroLinearization(anyClass);
|
||||
@ -1070,7 +1060,7 @@ export function createTypeEvaluator(
|
||||
// typeshed stubs, do so here. It would be better to fetch this when it's
|
||||
// needed in assignType, but we don't have access to the parse tree
|
||||
// at that point.
|
||||
initializedBasicTypes(node);
|
||||
initializePrefetchedTypes(node);
|
||||
|
||||
let typeResult = getTypeOfExpressionCore(node, flags, inferenceContext, signatureTracker);
|
||||
|
||||
@ -1699,8 +1689,8 @@ export function createTypeEvaluator(
|
||||
|
||||
if (ClassType.isBuiltIn(subtype, 'LiteralString')) {
|
||||
// Handle "LiteralString" specially.
|
||||
if (strClassType && isInstantiableClass(strClassType)) {
|
||||
let strInstance = ClassType.cloneAsInstance(strClassType);
|
||||
if (strClass && isInstantiableClass(strClass)) {
|
||||
let strInstance = ClassType.cloneAsInstance(strClass);
|
||||
|
||||
if (subtype.condition) {
|
||||
strInstance = TypeBase.cloneForCondition(strInstance, getTypeCondition(subtype));
|
||||
@ -2695,14 +2685,14 @@ export function createTypeEvaluator(
|
||||
// If errorNode is undefined, no errors are reported.
|
||||
function getTypeOfAwaitable(type: Type, errorNode?: ExpressionNode): Type {
|
||||
if (
|
||||
!awaitableProtocolType ||
|
||||
!isInstantiableClass(awaitableProtocolType) ||
|
||||
awaitableProtocolType.details.typeParameters.length !== 1
|
||||
!awaitableClass ||
|
||||
!isInstantiableClass(awaitableClass) ||
|
||||
awaitableClass.details.typeParameters.length !== 1
|
||||
) {
|
||||
return UnknownType.create();
|
||||
}
|
||||
|
||||
const awaitableProtocolObj = ClassType.cloneAsInstance(awaitableProtocolType);
|
||||
const awaitableProtocolObj = ClassType.cloneAsInstance(awaitableClass);
|
||||
|
||||
return mapSubtypes(type, (subtype) => {
|
||||
subtype = makeTopLevelTypeVarsConcrete(subtype);
|
||||
@ -2797,8 +2787,8 @@ export function createTypeEvaluator(
|
||||
[
|
||||
{
|
||||
type:
|
||||
intClassType && isInstantiableClass(intClassType)
|
||||
? ClassType.cloneAsInstance(intClassType)
|
||||
intClass && isInstantiableClass(intClass)
|
||||
? ClassType.cloneAsInstance(intClass)
|
||||
: UnknownType.create(),
|
||||
},
|
||||
],
|
||||
@ -2833,7 +2823,7 @@ export function createTypeEvaluator(
|
||||
// know anything more about them.
|
||||
nextReturnType = mapSubtypes(nextReturnType, (returnSubtype) => {
|
||||
if (isTypeVar(returnSubtype) && isUnpackedVariadicTypeVar(returnSubtype)) {
|
||||
return objectType ?? UnknownType.create();
|
||||
return getObjectType();
|
||||
}
|
||||
|
||||
return returnSubtype;
|
||||
@ -2973,25 +2963,23 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
function getTypedDictClassType(): ClassType | undefined {
|
||||
return typedDictPrivateClassType && isInstantiableClass(typedDictPrivateClassType)
|
||||
? typedDictPrivateClassType
|
||||
: undefined;
|
||||
return typedDictPrivateClass && isInstantiableClass(typedDictPrivateClass) ? typedDictPrivateClass : undefined;
|
||||
}
|
||||
|
||||
function getTupleClassType(): ClassType | undefined {
|
||||
return tupleClassType && isInstantiableClass(tupleClassType) ? tupleClassType : undefined;
|
||||
return tupleClass && isInstantiableClass(tupleClass) ? tupleClass : undefined;
|
||||
}
|
||||
|
||||
function getObjectType(): Type {
|
||||
return objectType ?? UnknownType.create();
|
||||
return objectClass ? convertToInstance(objectClass) : UnknownType.create();
|
||||
}
|
||||
|
||||
function getNoneType(): Type {
|
||||
return noneType ?? UnknownType.create();
|
||||
return noneTypeClass ? convertToInstance(noneTypeClass) : UnknownType.create();
|
||||
}
|
||||
|
||||
function getUnionClassType(): Type {
|
||||
return unionClassType ?? UnknownType.create();
|
||||
return unionClass ?? UnknownType.create();
|
||||
}
|
||||
|
||||
function getTypingType(node: ParseNode, symbolName: string): Type | undefined {
|
||||
@ -3790,24 +3778,13 @@ export function createTypeEvaluator(
|
||||
return mapSubtypes(type, (subtype) => {
|
||||
if (isParamSpec(subtype)) {
|
||||
if (subtype.paramSpecAccess === 'args') {
|
||||
if (objectType && isClassInstance(objectType)) {
|
||||
return makeTupleObject([{ type: objectType, isUnbounded: true }]);
|
||||
}
|
||||
|
||||
return UnknownType.create();
|
||||
return makeTupleObject([{ type: getObjectType(), isUnbounded: true }]);
|
||||
} else if (subtype.paramSpecAccess === 'kwargs') {
|
||||
if (
|
||||
dictClassType &&
|
||||
isInstantiableClass(dictClassType) &&
|
||||
strClassType &&
|
||||
isInstantiableClass(strClassType) &&
|
||||
objectType &&
|
||||
isClassInstance(objectType)
|
||||
) {
|
||||
if (dictClass && isInstantiableClass(dictClass) && strClass && isInstantiableClass(strClass)) {
|
||||
return ClassType.cloneAsInstance(
|
||||
ClassType.cloneForSpecialization(
|
||||
dictClassType,
|
||||
[convertToInstance(strClassType), objectType],
|
||||
dictClass,
|
||||
[convertToInstance(strClass), getObjectType()],
|
||||
/* isTypeArgumentExplicit */ true
|
||||
)
|
||||
);
|
||||
@ -3832,21 +3809,18 @@ export function createTypeEvaluator(
|
||||
// If it's in a union, convert to type or object.
|
||||
if (subtype.isVariadicInUnion) {
|
||||
if (TypeBase.isInstantiable(subtype)) {
|
||||
if (typeClassType && isInstantiableClass(typeClassType)) {
|
||||
return typeClassType;
|
||||
if (typeClass && isInstantiableClass(typeClass)) {
|
||||
return typeClass;
|
||||
}
|
||||
} else if (objectType) {
|
||||
return objectType;
|
||||
} else {
|
||||
return getObjectType();
|
||||
}
|
||||
|
||||
return AnyType.create();
|
||||
}
|
||||
|
||||
// Fall back to "*tuple[object, ...]".
|
||||
return makeTupleObject(
|
||||
[{ type: objectType ?? UnknownType.create(), isUnbounded: true }],
|
||||
/* isUnpacked */ true
|
||||
);
|
||||
return makeTupleObject([{ type: getObjectType(), isUnbounded: true }], /* isUnpacked */ true);
|
||||
}
|
||||
|
||||
if (isTypeVar(subtype)) {
|
||||
@ -3892,7 +3866,7 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
// Fall back to a bound of "object" if no bound is provided.
|
||||
let boundType = subtype.details.boundType ?? objectType ?? UnknownType.create();
|
||||
let boundType = subtype.details.boundType ?? getObjectType();
|
||||
boundType = TypeBase.isInstantiable(subtype) ? convertToInstantiable(boundType) : boundType;
|
||||
|
||||
return addConditionToType(boundType, [{ typeVar: subtype, constraintIndex: 0 }]);
|
||||
@ -4911,7 +4885,7 @@ export function createTypeEvaluator(
|
||||
let defaultType: Type;
|
||||
if (param.details.isDefaultExplicit || param.details.isParamSpec) {
|
||||
defaultType = applySolvedTypeVars(param, typeVarContext, { unknownIfNotFound: true });
|
||||
} else if (param.details.isVariadic && tupleClassType && isInstantiableClass(tupleClassType)) {
|
||||
} else if (param.details.isVariadic && tupleClass && isInstantiableClass(tupleClass)) {
|
||||
defaultType = makeTupleObject(
|
||||
[{ type: UnknownType.create(), isUnbounded: true }],
|
||||
/* isUnpackedTuple */ true
|
||||
@ -5486,8 +5460,9 @@ export function createTypeEvaluator(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isNoneInstance(subtype) && noneType && isClassInstance(noneType)) {
|
||||
const typeResult = getTypeOfBoundMember(node.memberName, noneType, memberName, usage, diag);
|
||||
if (isNoneInstance(subtype)) {
|
||||
assert(isClassInstance(subtype));
|
||||
const typeResult = getTypeOfBoundMember(node.memberName, subtype, memberName, usage, diag);
|
||||
|
||||
if (typeResult && !typeResult.typeErrors) {
|
||||
type = addConditionToType(typeResult.type, getTypeCondition(baseType));
|
||||
@ -5551,7 +5526,7 @@ export function createTypeEvaluator(
|
||||
} else {
|
||||
type = getTypeOfMemberAccessWithBaseType(
|
||||
node,
|
||||
{ type: functionObj ?? AnyType.create() },
|
||||
{ type: functionClass ? convertToInstance(functionClass) : UnknownType.create() },
|
||||
usage,
|
||||
flags
|
||||
).type;
|
||||
@ -6387,8 +6362,8 @@ export function createTypeEvaluator(
|
||||
argumentCategory: ArgumentCategory.Simple,
|
||||
typeResult: {
|
||||
type:
|
||||
strClassType && isInstantiableClass(strClassType)
|
||||
? ClassType.cloneWithLiteral(ClassType.cloneAsInstance(strClassType), memberName)
|
||||
strClass && isInstantiableClass(strClass)
|
||||
? ClassType.cloneWithLiteral(ClassType.cloneAsInstance(strClass), memberName)
|
||||
: AnyType.create(),
|
||||
},
|
||||
});
|
||||
@ -7307,9 +7282,9 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
function makeTupleObject(typeArgs: TupleTypeArgument[], isUnpackedTuple = false) {
|
||||
if (tupleClassType && isInstantiableClass(tupleClassType)) {
|
||||
if (tupleClass && isInstantiableClass(tupleClass)) {
|
||||
return convertToInstance(
|
||||
specializeTupleClass(tupleClassType, typeArgs, /* isTypeArgumentExplicit */ true, isUnpackedTuple)
|
||||
specializeTupleClass(tupleClass, typeArgs, /* isTypeArgumentExplicit */ true, isUnpackedTuple)
|
||||
);
|
||||
}
|
||||
|
||||
@ -7785,8 +7760,7 @@ export function createTypeEvaluator(
|
||||
typedDictClassType && isInstantiableClass(typedDictClassType)
|
||||
? createTypedDictTypeInlined(evaluatorInterface, node, typedDictClassType)
|
||||
: undefined;
|
||||
const keyTypeFallback =
|
||||
strClassType && isInstantiableClass(strClassType) ? strClassType : UnknownType.create();
|
||||
const keyTypeFallback = strClass && isInstantiableClass(strClass) ? strClass : UnknownType.create();
|
||||
|
||||
typeResult = {
|
||||
type: keyTypeFallback,
|
||||
@ -7923,7 +7897,7 @@ export function createTypeEvaluator(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!tupleClassType || !isInstantiableClass(tupleClassType)) {
|
||||
if (!tupleClass || !isInstantiableClass(tupleClass)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -7945,11 +7919,11 @@ export function createTypeEvaluator(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const tupleTypeVarContext = new TypeVarContext(getTypeVarScopeId(tupleClassType));
|
||||
const tupleTypeVarContext = new TypeVarContext(getTypeVarScopeId(tupleClass));
|
||||
if (
|
||||
!populateTypeVarContextBasedOnExpectedType(
|
||||
evaluatorInterface,
|
||||
ClassType.cloneAsInstance(tupleClassType),
|
||||
ClassType.cloneAsInstance(tupleClass),
|
||||
inferenceContext.expectedType,
|
||||
tupleTypeVarContext,
|
||||
ParseTreeUtils.getTypeVarScopesForNode(node),
|
||||
@ -7959,7 +7933,7 @@ export function createTypeEvaluator(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const specializedTuple = applySolvedTypeVars(tupleClassType, tupleTypeVarContext) as ClassType;
|
||||
const specializedTuple = applySolvedTypeVars(tupleClass, tupleTypeVarContext) as ClassType;
|
||||
if (!specializedTuple.typeArguments || specializedTuple.typeArguments.length !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
@ -8636,11 +8610,9 @@ export function createTypeEvaluator(
|
||||
} else if (
|
||||
effectiveTargetClass &&
|
||||
!isAnyOrUnknown(effectiveTargetClass) &&
|
||||
!derivesFromAnyOrUnknown(effectiveTargetClass) &&
|
||||
objectType &&
|
||||
isClassInstance(objectType)
|
||||
!derivesFromAnyOrUnknown(effectiveTargetClass)
|
||||
) {
|
||||
resultType = ClassType.cloneAsInstantiable(objectType);
|
||||
resultType = objectClass ?? UnknownType.create();
|
||||
} else {
|
||||
resultType = UnknownType.create();
|
||||
}
|
||||
@ -8693,9 +8665,9 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
// There's not much we can say about the type. Simply return object or type.
|
||||
if (objectType && isClassInstance(objectType) && typeClassType && isInstantiableClass(typeClassType)) {
|
||||
if (typeClass && isInstantiableClass(typeClass)) {
|
||||
return {
|
||||
type: resultIsInstance ? objectType : convertToInstance(typeClassType),
|
||||
type: resultIsInstance ? getObjectType() : convertToInstance(typeClass),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@ -10190,7 +10162,7 @@ export function createTypeEvaluator(
|
||||
// If this is a tuple with specified element types, use those
|
||||
// specified types rather than using the more generic iterator
|
||||
// type which will be a union of all element types.
|
||||
const combinedArgType = combineSameSizedTuples(makeTopLevelTypeVarsConcrete(argType), tupleClassType);
|
||||
const combinedArgType = combineSameSizedTuples(makeTopLevelTypeVarsConcrete(argType), tupleClass);
|
||||
|
||||
if (isClassInstance(combinedArgType) && isTupleClass(combinedArgType)) {
|
||||
const tupleTypeArgs = combinedArgType.tupleTypeArguments ?? [];
|
||||
@ -10848,13 +10820,13 @@ export function createTypeEvaluator(
|
||||
const strObjType = getBuiltInObject(errorNode, 'str');
|
||||
|
||||
if (
|
||||
supportsKeysAndGetItemProtocolType &&
|
||||
isInstantiableClass(supportsKeysAndGetItemProtocolType) &&
|
||||
supportsKeysAndGetItemClass &&
|
||||
isInstantiableClass(supportsKeysAndGetItemClass) &&
|
||||
strObjType &&
|
||||
isClassInstance(strObjType)
|
||||
) {
|
||||
const mappingTypeVarContext = new TypeVarContext(
|
||||
getTypeVarScopeId(supportsKeysAndGetItemProtocolType)
|
||||
getTypeVarScopeId(supportsKeysAndGetItemClass)
|
||||
);
|
||||
let isValidMappingType = false;
|
||||
|
||||
@ -10864,14 +10836,14 @@ export function createTypeEvaluator(
|
||||
isValidMappingType = true;
|
||||
} else if (
|
||||
assignType(
|
||||
ClassType.cloneAsInstance(supportsKeysAndGetItemProtocolType),
|
||||
ClassType.cloneAsInstance(supportsKeysAndGetItemClass),
|
||||
argType,
|
||||
/* diag */ undefined,
|
||||
mappingTypeVarContext
|
||||
)
|
||||
) {
|
||||
const specializedMapping = applySolvedTypeVars(
|
||||
supportsKeysAndGetItemProtocolType,
|
||||
supportsKeysAndGetItemClass,
|
||||
mappingTypeVarContext
|
||||
) as ClassType;
|
||||
const typeArgs = specializedMapping.typeArguments;
|
||||
@ -11740,7 +11712,7 @@ export function createTypeEvaluator(
|
||||
specializedReturnType.typeArguments &&
|
||||
specializedReturnType.typeArguments.length > 0
|
||||
) {
|
||||
if (boolClassType && isInstantiableClass(boolClassType)) {
|
||||
if (boolClass && isInstantiableClass(boolClass)) {
|
||||
let typeGuardType = specializedReturnType.typeArguments[0];
|
||||
|
||||
// If the first argument is a simple (non-constrained) TypeVar,
|
||||
@ -11760,7 +11732,7 @@ export function createTypeEvaluator(
|
||||
|
||||
const useTypeIsSemantics = ClassType.isBuiltIn(specializedReturnType, 'TypeIs');
|
||||
specializedReturnType = ClassType.cloneAsInstance(
|
||||
ClassType.cloneForTypeGuard(boolClassType, typeGuardType, useTypeIsSemantics)
|
||||
ClassType.cloneForTypeGuard(boolClass, typeGuardType, useTypeIsSemantics)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -13030,9 +13002,7 @@ export function createTypeEvaluator(
|
||||
let isBaseClassAny = false;
|
||||
|
||||
if (isAnyOrUnknown(baseClass)) {
|
||||
if (objectType && isClassInstance(objectType)) {
|
||||
baseClass = ClassType.cloneAsInstantiable(objectType);
|
||||
}
|
||||
baseClass = objectClass ?? UnknownType.create();
|
||||
|
||||
addDiagnostic(
|
||||
DiagnosticRule.reportGeneralTypeIssues,
|
||||
@ -13192,7 +13162,12 @@ export function createTypeEvaluator(
|
||||
let type: Type | undefined;
|
||||
|
||||
if (node.constType === KeywordType.None) {
|
||||
type = (flags & EvaluatorFlags.ExpectingInstantiableType) !== 0 ? noneClassType : noneType;
|
||||
if (noneTypeClass) {
|
||||
type =
|
||||
(flags & EvaluatorFlags.ExpectingInstantiableType) !== 0
|
||||
? noneTypeClass
|
||||
: convertToInstance(noneTypeClass);
|
||||
}
|
||||
} else if (
|
||||
node.constType === KeywordType.True ||
|
||||
node.constType === KeywordType.False ||
|
||||
@ -13294,16 +13269,16 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
if (isNoneInstance(subtype)) {
|
||||
if (objectType && isClassInstance(objectType)) {
|
||||
if (objectClass && isInstantiableClass(objectClass)) {
|
||||
// Use 'object' for 'None'.
|
||||
return handleSubtype(objectType);
|
||||
return handleSubtype(convertToInstance(objectClass));
|
||||
}
|
||||
}
|
||||
|
||||
if (isNoneTypeClass(subtype)) {
|
||||
if (typeClassType && isInstantiableClass(typeClassType)) {
|
||||
if (typeClass && isInstantiableClass(typeClass)) {
|
||||
// Use 'type' for 'type[None]'.
|
||||
return handleSubtype(ClassType.cloneAsInstance(typeClassType));
|
||||
return handleSubtype(ClassType.cloneAsInstance(typeClass));
|
||||
}
|
||||
}
|
||||
|
||||
@ -13754,10 +13729,10 @@ export function createTypeEvaluator(
|
||||
} else if (entryNode.nodeType === ParseNodeType.DictionaryExpandEntry) {
|
||||
let expectedType: Type | undefined;
|
||||
if (expectedKeyType && expectedValueType) {
|
||||
if (supportsKeysAndGetItemProtocolType && isInstantiableClass(supportsKeysAndGetItemProtocolType)) {
|
||||
if (supportsKeysAndGetItemClass && isInstantiableClass(supportsKeysAndGetItemClass)) {
|
||||
expectedType = ClassType.cloneAsInstance(
|
||||
ClassType.cloneForSpecialization(
|
||||
supportsKeysAndGetItemProtocolType,
|
||||
supportsKeysAndGetItemClass,
|
||||
[expectedKeyType, expectedValueType],
|
||||
/* isTypeArgumentExplicit */ true
|
||||
)
|
||||
@ -13797,8 +13772,8 @@ export function createTypeEvaluator(
|
||||
addUnknown = false;
|
||||
} else if (isClassInstance(unexpandedType) && ClassType.isTypedDictClass(unexpandedType)) {
|
||||
// Handle dictionary expansion for a TypedDict.
|
||||
if (strClassType && isInstantiableClass(strClassType)) {
|
||||
const strObject = ClassType.cloneAsInstance(strClassType);
|
||||
if (strClass && isInstantiableClass(strClass)) {
|
||||
const strObject = ClassType.cloneAsInstance(strClass);
|
||||
const tdEntries = getTypedDictMembersForClass(
|
||||
evaluatorInterface,
|
||||
unexpandedType,
|
||||
@ -13819,25 +13794,20 @@ export function createTypeEvaluator(
|
||||
keyTypes.push({ node: entryNode, type: ClassType.cloneAsInstance(strObject) });
|
||||
valueTypes.push({
|
||||
node: entryNode,
|
||||
type: tdEntries.extraItems?.valueType ?? objectType ?? UnknownType.create(),
|
||||
type: tdEntries.extraItems?.valueType ?? getObjectType(),
|
||||
});
|
||||
}
|
||||
|
||||
addUnknown = false;
|
||||
}
|
||||
} else if (
|
||||
supportsKeysAndGetItemProtocolType &&
|
||||
isInstantiableClass(supportsKeysAndGetItemProtocolType)
|
||||
) {
|
||||
const mappingTypeVarContext = new TypeVarContext(
|
||||
getTypeVarScopeId(supportsKeysAndGetItemProtocolType)
|
||||
);
|
||||
} else if (supportsKeysAndGetItemClass && isInstantiableClass(supportsKeysAndGetItemClass)) {
|
||||
const mappingTypeVarContext = new TypeVarContext(getTypeVarScopeId(supportsKeysAndGetItemClass));
|
||||
|
||||
supportsKeysAndGetItemProtocolType = selfSpecializeClass(supportsKeysAndGetItemProtocolType);
|
||||
supportsKeysAndGetItemClass = selfSpecializeClass(supportsKeysAndGetItemClass);
|
||||
|
||||
if (
|
||||
assignType(
|
||||
ClassType.cloneAsInstance(supportsKeysAndGetItemProtocolType),
|
||||
ClassType.cloneAsInstance(supportsKeysAndGetItemClass),
|
||||
unexpandedType,
|
||||
/* diag */ undefined,
|
||||
mappingTypeVarContext,
|
||||
@ -13846,7 +13816,7 @@ export function createTypeEvaluator(
|
||||
)
|
||||
) {
|
||||
const specializedMapping = applySolvedTypeVars(
|
||||
supportsKeysAndGetItemProtocolType,
|
||||
supportsKeysAndGetItemClass,
|
||||
mappingTypeVarContext
|
||||
) as ClassType;
|
||||
const typeArgs = specializedMapping.typeArguments;
|
||||
@ -14994,9 +14964,9 @@ export function createTypeEvaluator(
|
||||
typeArg0Type = UnknownType.create();
|
||||
}
|
||||
|
||||
let optionalType = combineTypes([typeArg0Type, noneClassType ?? UnknownType.create()]);
|
||||
if (unionClassType && isInstantiableClass(unionClassType)) {
|
||||
optionalType = TypeBase.cloneAsSpecialForm(optionalType, ClassType.cloneAsInstance(unionClassType));
|
||||
let optionalType = combineTypes([typeArg0Type, noneTypeClass ?? UnknownType.create()]);
|
||||
if (unionClass && isInstantiableClass(unionClass)) {
|
||||
optionalType = TypeBase.cloneAsSpecialForm(optionalType, ClassType.cloneAsInstance(unionClass));
|
||||
}
|
||||
|
||||
return optionalType;
|
||||
@ -15076,7 +15046,7 @@ export function createTypeEvaluator(
|
||||
} else if (itemExpr.constType === KeywordType.False) {
|
||||
type = cloneBuiltinClassWithLiteral(node, classType, 'bool', false);
|
||||
} else if (itemExpr.constType === KeywordType.None) {
|
||||
type = noneClassType ?? UnknownType.create();
|
||||
type = noneTypeClass ?? UnknownType.create();
|
||||
}
|
||||
} else if (itemExpr.nodeType === ParseNodeType.UnaryOperation) {
|
||||
if (itemExpr.operator === OperatorType.Subtract || itemExpr.operator === OperatorType.Add) {
|
||||
@ -15133,8 +15103,8 @@ export function createTypeEvaluator(
|
||||
|
||||
let result = combineTypes(literalTypes);
|
||||
|
||||
if (isUnion(result) && unionClassType && isInstantiableClass(unionClassType)) {
|
||||
result = TypeBase.cloneAsSpecialForm(result, ClassType.cloneAsInstance(unionClassType));
|
||||
if (isUnion(result) && unionClass && isInstantiableClass(unionClass)) {
|
||||
result = TypeBase.cloneAsSpecialForm(result, ClassType.cloneAsInstance(unionClass));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -15708,8 +15678,8 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
let unionType = combineTypes(types);
|
||||
if (unionClassType && isInstantiableClass(unionClassType)) {
|
||||
unionType = TypeBase.cloneAsSpecialForm(unionType, ClassType.cloneAsInstance(unionClassType));
|
||||
if (unionClass && isInstantiableClass(unionClass)) {
|
||||
unionType = TypeBase.cloneAsSpecialForm(unionType, ClassType.cloneAsInstance(unionClass));
|
||||
}
|
||||
|
||||
return unionType;
|
||||
@ -16024,7 +15994,7 @@ export function createTypeEvaluator(
|
||||
// Handle 'LiteralString' specially because we want it to act as
|
||||
// though it derives from 'str'.
|
||||
if (assignedName === 'LiteralString') {
|
||||
specialType.details.baseClasses.push(strClassType ?? AnyType.create());
|
||||
specialType.details.baseClasses.push(strClass ?? AnyType.create());
|
||||
computeMroLinearization(specialType);
|
||||
}
|
||||
|
||||
@ -16415,7 +16385,7 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
function getTypeOfClass(node: ClassNode): ClassTypeResult | undefined {
|
||||
initializedBasicTypes(node);
|
||||
initializePrefetchedTypes(node);
|
||||
|
||||
// Is this type already cached?
|
||||
const cachedClassType = readTypeCache(node.name, EvaluatorFlags.None);
|
||||
@ -17266,10 +17236,6 @@ export function createTypeEvaluator(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!objectType || !isClassInstance(objectType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Presumptively mark the variance inference as complete. This
|
||||
// prevents potential recursion.
|
||||
classType.details.requiresVarianceInference = false;
|
||||
@ -17310,8 +17276,7 @@ export function createTypeEvaluator(
|
||||
if (p.details.isVariadic) {
|
||||
return p;
|
||||
}
|
||||
assert(objectType !== undefined);
|
||||
return i === paramIndex ? objectType : dummyTypeObject;
|
||||
return i === paramIndex ? getObjectType() : dummyTypeObject;
|
||||
});
|
||||
|
||||
// Replace all type arguments with a dummy type except for the
|
||||
@ -17388,7 +17353,7 @@ export function createTypeEvaluator(
|
||||
if (!effectiveMetaclass || isInstantiableClass(effectiveMetaclass)) {
|
||||
for (const baseClass of classType.details.baseClasses) {
|
||||
if (isInstantiableClass(baseClass)) {
|
||||
const baseClassMeta = baseClass.details.effectiveMetaclass || typeClassType;
|
||||
const baseClassMeta = baseClass.details.effectiveMetaclass || typeClass;
|
||||
if (baseClassMeta && isInstantiableClass(baseClassMeta)) {
|
||||
// Make sure there is no metaclass conflict.
|
||||
if (!effectiveMetaclass) {
|
||||
@ -17704,7 +17669,7 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
function getTypeOfFunction(node: FunctionNode): FunctionTypeResult | undefined {
|
||||
initializedBasicTypes(node);
|
||||
initializePrefetchedTypes(node);
|
||||
|
||||
// Is this predecorated function type cached?
|
||||
let functionType = readTypeCache(node.name, EvaluatorFlags.None);
|
||||
@ -19740,7 +19705,7 @@ export function createTypeEvaluator(
|
||||
// be evaluated to provide sufficient context for the type. Evaluated types
|
||||
// are written back to the type cache for later retrieval.
|
||||
function evaluateTypesForStatement(node: ParseNode): void {
|
||||
initializedBasicTypes(node);
|
||||
initializePrefetchedTypes(node);
|
||||
|
||||
let curNode: ParseNode | undefined = node;
|
||||
|
||||
@ -20139,9 +20104,9 @@ export function createTypeEvaluator(
|
||||
}
|
||||
}
|
||||
|
||||
if (typeClassType && isInstantiableClass(typeClassType)) {
|
||||
if (typeClass && isInstantiableClass(typeClass)) {
|
||||
let typeType = createSpecialType(
|
||||
typeClassType,
|
||||
typeClass,
|
||||
typeArgs,
|
||||
1,
|
||||
/* allowParamSpec */ undefined,
|
||||
@ -22344,7 +22309,7 @@ export function createTypeEvaluator(
|
||||
getEffectiveTypeOfSymbol(member.symbol),
|
||||
member.classType,
|
||||
/* selfClass */ undefined,
|
||||
typeClassType ?? UnknownType.create()
|
||||
typeClass ?? UnknownType.create()
|
||||
);
|
||||
}
|
||||
return UnknownType.create();
|
||||
@ -22476,14 +22441,14 @@ export function createTypeEvaluator(
|
||||
|
||||
if (
|
||||
mappingValueType &&
|
||||
mappingType &&
|
||||
isInstantiableClass(mappingType) &&
|
||||
strClassType &&
|
||||
isInstantiableClass(strClassType)
|
||||
mappingClass &&
|
||||
isInstantiableClass(mappingClass) &&
|
||||
strClass &&
|
||||
isInstantiableClass(strClass)
|
||||
) {
|
||||
srcType = ClassType.cloneForSpecialization(
|
||||
mappingType,
|
||||
[ClassType.cloneAsInstance(strClassType), mappingValueType],
|
||||
mappingClass,
|
||||
[ClassType.cloneAsInstance(strClass), mappingValueType],
|
||||
/* isTypeArgumentExplicit */ true
|
||||
);
|
||||
}
|
||||
@ -22492,14 +22457,14 @@ export function createTypeEvaluator(
|
||||
|
||||
if (
|
||||
dictValueType &&
|
||||
dictClassType &&
|
||||
isInstantiableClass(dictClassType) &&
|
||||
strClassType &&
|
||||
isInstantiableClass(strClassType)
|
||||
dictClass &&
|
||||
isInstantiableClass(dictClass) &&
|
||||
strClass &&
|
||||
isInstantiableClass(strClass)
|
||||
) {
|
||||
srcType = ClassType.cloneForSpecialization(
|
||||
dictClassType,
|
||||
[ClassType.cloneAsInstance(strClassType), dictValueType],
|
||||
dictClass,
|
||||
[ClassType.cloneAsInstance(strClass), dictValueType],
|
||||
/* isTypeArgumentExplicit */ true
|
||||
);
|
||||
}
|
||||
@ -22840,7 +22805,7 @@ export function createTypeEvaluator(
|
||||
const skipAdjustment =
|
||||
destArgsToCapture === 1 && isVariadicTypeVar(destTypeArgs[srcVariadicIndex].type);
|
||||
|
||||
if (!skipAdjustment && tupleClassType && isInstantiableClass(tupleClassType)) {
|
||||
if (!skipAdjustment && tupleClass && isInstantiableClass(tupleClass)) {
|
||||
const removedArgs = destTypeArgs.splice(srcVariadicIndex, destArgsToCapture);
|
||||
|
||||
// Package up the remaining type arguments into a tuple object.
|
||||
@ -22868,7 +22833,7 @@ export function createTypeEvaluator(
|
||||
// If the dest contains a variadic element, determine which source
|
||||
// args map to this element and package them up into an unpacked tuple.
|
||||
if (isVariadicTypeVar(destTypeArgs[destUnboundedOrVariadicIndex].type)) {
|
||||
if (tupleClassType && isInstantiableClass(tupleClassType)) {
|
||||
if (tupleClass && isInstantiableClass(tupleClass)) {
|
||||
const removedArgs = srcTypeArgs.splice(destUnboundedOrVariadicIndex, srcArgsToCapture);
|
||||
|
||||
let variadicTuple: Type;
|
||||
@ -23929,11 +23894,11 @@ export function createTypeEvaluator(
|
||||
}
|
||||
} else if (
|
||||
ClassType.isBuiltIn(concreteSrcType, 'LiteralString') &&
|
||||
strClassType &&
|
||||
isInstantiableClass(strClassType) &&
|
||||
strClass &&
|
||||
isInstantiableClass(strClass) &&
|
||||
(flags & AssignTypeFlags.EnforceInvariance) === 0
|
||||
) {
|
||||
concreteSrcType = ClassType.cloneAsInstance(strClassType);
|
||||
concreteSrcType = ClassType.cloneAsInstance(strClass);
|
||||
}
|
||||
|
||||
if (
|
||||
@ -23968,10 +23933,10 @@ export function createTypeEvaluator(
|
||||
}
|
||||
|
||||
// All functions are considered instances of "builtins.function".
|
||||
if (functionObj && isClassInstance(functionObj)) {
|
||||
if (functionClass) {
|
||||
return assignType(
|
||||
destType,
|
||||
functionObj,
|
||||
convertToInstance(functionClass),
|
||||
diag,
|
||||
destTypeVarContext,
|
||||
srcTypeVarContext,
|
||||
@ -24248,11 +24213,11 @@ export function createTypeEvaluator(
|
||||
|
||||
// Are we trying to assign None to a protocol?
|
||||
if (isNoneInstance(srcType) && isClassInstance(destType) && ClassType.isProtocolClass(destType)) {
|
||||
if (noneClassType && isInstantiableClass(noneClassType)) {
|
||||
if (noneTypeClass && isInstantiableClass(noneTypeClass)) {
|
||||
return assignClassToProtocol(
|
||||
evaluatorInterface,
|
||||
ClassType.cloneAsInstantiable(destType),
|
||||
ClassType.cloneAsInstance(noneClassType),
|
||||
ClassType.cloneAsInstance(noneTypeClass),
|
||||
diag,
|
||||
destTypeVarContext,
|
||||
srcTypeVarContext,
|
||||
@ -24930,8 +24895,8 @@ export function createTypeEvaluator(
|
||||
if (field[0] !== '__call__' && !field[1].isIgnoredForProtocolMatch()) {
|
||||
let fieldIsPartOfFunction = false;
|
||||
|
||||
if (functionObj && isClass(functionObj)) {
|
||||
if (ClassType.getSymbolTable(functionObj).has(field[0])) {
|
||||
if (functionClass && isClass(functionClass)) {
|
||||
if (ClassType.getSymbolTable(functionClass).has(field[0])) {
|
||||
fieldIsPartOfFunction = true;
|
||||
}
|
||||
}
|
||||
@ -25873,13 +25838,13 @@ export function createTypeEvaluator(
|
||||
if (
|
||||
isClassInstance(srcReturnType) &&
|
||||
ClassType.isBuiltIn(srcReturnType, ['TypeGuard', 'TypeIs']) &&
|
||||
boolClassType &&
|
||||
isInstantiableClass(boolClassType)
|
||||
boolClass &&
|
||||
isInstantiableClass(boolClass)
|
||||
) {
|
||||
if (
|
||||
assignType(
|
||||
destReturnType,
|
||||
ClassType.cloneAsInstance(boolClassType),
|
||||
ClassType.cloneAsInstance(boolClass),
|
||||
returnDiag?.createAddendum(),
|
||||
destTypeVarContext,
|
||||
srcTypeVarContext,
|
||||
|
Loading…
Reference in New Issue
Block a user