@zzzen/pyright-internal 1.2.0-dev.20230716 → 1.2.0-dev.20230723
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +13 -21
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +12 -1
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +25 -2
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +11 -1
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.js +11 -9
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/namedTuples.js +1 -0
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +7 -2
- package/dist/analyzer/typeCacheUtils.js +11 -7
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +652 -498
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +3 -2
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +42 -7
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.js +10 -0
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +2 -2
- package/dist/analyzer/types.js +11 -2
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundThreadBase.js +1 -1
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +7 -10
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.js +7 -1
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +5 -2
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +7 -0
- package/dist/localization/localize.js +17 -1
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +1 -0
- package/dist/localization/package.nls.de.json +1 -0
- package/dist/localization/package.nls.en-us.json +6 -5
- package/dist/localization/package.nls.es.json +1 -0
- package/dist/localization/package.nls.fr.json +1 -0
- package/dist/localization/package.nls.it.json +1 -0
- package/dist/localization/package.nls.ja.json +1 -0
- package/dist/localization/package.nls.ko.json +1 -0
- package/dist/localization/package.nls.pl.json +1 -0
- package/dist/localization/package.nls.pt-br.json +1 -0
- package/dist/localization/package.nls.qps-ploc.json +1 -0
- package/dist/localization/package.nls.ru.json +1 -0
- package/dist/localization/package.nls.tr.json +1 -0
- package/dist/localization/package.nls.zh-cn.json +1 -0
- package/dist/localization/package.nls.zh-tw.json +1 -0
- package/dist/tests/checker.test.js +2 -2
- package/dist/tests/completions.test.js +40 -0
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/config.test.js +12 -0
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js +40 -0
- package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js.map +1 -0
- package/dist/tests/typeEvaluator1.test.js +17 -1
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +13 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +1 -1
- package/dist/tests/typeEvaluator4.test.js +5 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/package.json +8 -7
@@ -175,7 +175,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
175
175
|
let typeCache = new Map();
|
176
176
|
let effectiveTypeCache = new Map();
|
177
177
|
let expectedTypeCache = new Map();
|
178
|
-
let
|
178
|
+
let deferredClassCompletions = [];
|
179
179
|
let cancellationToken;
|
180
180
|
let isBasicTypesInitialized = false;
|
181
181
|
let noneType;
|
@@ -1420,6 +1420,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1420
1420
|
let classOrObjectBase;
|
1421
1421
|
let memberAccessClass;
|
1422
1422
|
let bindFunction = true;
|
1423
|
+
let useDescriptorSetterType = false;
|
1423
1424
|
switch (expression.nodeType) {
|
1424
1425
|
case 38 /* Name */: {
|
1425
1426
|
const symbolWithScope = lookUpSymbolRecursive(expression, expression.value, /* honorCodeFlow */ true);
|
@@ -1460,6 +1461,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1460
1461
|
if (classMemberInfo === null || classMemberInfo === void 0 ? void 0 : classMemberInfo.isInstanceMember) {
|
1461
1462
|
bindFunction = false;
|
1462
1463
|
}
|
1464
|
+
useDescriptorSetterType = true;
|
1463
1465
|
}
|
1464
1466
|
else if ((0, types_1.isInstantiableClass)(baseType)) {
|
1465
1467
|
classMemberInfo = (0, typeUtils_1.lookUpClassMember)(baseType, expression.memberName.value, 8 /* SkipInstanceVariables */ | 16 /* DeclaredTypesOnly */);
|
@@ -1505,7 +1507,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1505
1507
|
let declaredType = (_b = getDeclaredTypeOfSymbol(symbol)) === null || _b === void 0 ? void 0 : _b.type;
|
1506
1508
|
if (declaredType) {
|
1507
1509
|
// If it's a descriptor, we need to get the setter type.
|
1508
|
-
if ((0, types_1.isClassInstance)(declaredType)) {
|
1510
|
+
if (useDescriptorSetterType && (0, types_1.isClassInstance)(declaredType)) {
|
1509
1511
|
const setterInfo = (0, typeUtils_1.lookUpClassMember)(declaredType, '__set__');
|
1510
1512
|
const setter = setterInfo ? getTypeOfMember(setterInfo) : undefined;
|
1511
1513
|
if (setterInfo && setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 3) {
|
@@ -1908,7 +1910,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1908
1910
|
}
|
1909
1911
|
function isDiagnosticSuppressedForNode(node) {
|
1910
1912
|
return (suppressedNodeStack.some((suppressedNode) => ParseTreeUtils.isNodeContainedWithin(node, suppressedNode)) ||
|
1911
|
-
|
1913
|
+
speculativeTypeTracker.isSpeculative(node, /* ignoreIfDiagnosticsAllowed */ true));
|
1912
1914
|
}
|
1913
1915
|
function addDiagnostic(diagLevel, rule, message, node, range) {
|
1914
1916
|
if (diagLevel === 'none') {
|
@@ -2392,20 +2394,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2392
2394
|
// its bound type and a constrained TypeVar is expanded to its individual
|
2393
2395
|
// constrained types). If conditionFilter is specified, conditions that
|
2394
2396
|
// do not match will be ignored.
|
2395
|
-
function mapSubtypesExpandTypeVars(type, conditionFilter, callback) {
|
2397
|
+
function mapSubtypesExpandTypeVars(type, conditionFilter, callback, recursionCount = 0) {
|
2396
2398
|
const newSubtypes = [];
|
2397
2399
|
let typeChanged = false;
|
2398
|
-
|
2400
|
+
function expandSubtype(unexpandedType, isLastSubtype) {
|
2399
2401
|
let expandedType = (0, types_1.isUnion)(unexpandedType) ? unexpandedType : makeTopLevelTypeVarsConcrete(unexpandedType);
|
2400
2402
|
expandedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedType);
|
2401
|
-
(0, typeUtils_1.doForEachSubtype)(expandedType, (subtype) => {
|
2403
|
+
(0, typeUtils_1.doForEachSubtype)(expandedType, (subtype, index, allSubtypes) => {
|
2402
2404
|
var _a;
|
2403
2405
|
if (conditionFilter) {
|
2404
|
-
|
2406
|
+
const filteredType = applyConditionFilterToType(subtype, conditionFilter, recursionCount);
|
2407
|
+
if (!filteredType) {
|
2405
2408
|
return undefined;
|
2406
2409
|
}
|
2410
|
+
subtype = filteredType;
|
2407
2411
|
}
|
2408
|
-
let transformedType = callback(subtype, unexpandedType);
|
2412
|
+
let transformedType = callback(subtype, unexpandedType, isLastSubtype && index === allSubtypes.length - 1);
|
2409
2413
|
if (transformedType !== unexpandedType) {
|
2410
2414
|
typeChanged = true;
|
2411
2415
|
}
|
@@ -2419,14 +2423,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2419
2423
|
}
|
2420
2424
|
return undefined;
|
2421
2425
|
});
|
2422
|
-
}
|
2426
|
+
}
|
2423
2427
|
if ((0, types_1.isUnion)(type)) {
|
2424
|
-
type.subtypes.forEach((subtype) => {
|
2425
|
-
expandSubtype(subtype);
|
2428
|
+
type.subtypes.forEach((subtype, index) => {
|
2429
|
+
expandSubtype(subtype, index === type.subtypes.length - 1);
|
2426
2430
|
});
|
2427
2431
|
}
|
2428
2432
|
else {
|
2429
|
-
expandSubtype(type);
|
2433
|
+
expandSubtype(type, /* isLastSubtype */ true);
|
2430
2434
|
}
|
2431
2435
|
if (!typeChanged) {
|
2432
2436
|
return type;
|
@@ -2438,6 +2442,40 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2438
2442
|
}
|
2439
2443
|
return newType;
|
2440
2444
|
}
|
2445
|
+
function applyConditionFilterToType(type, conditionFilter, recursionCount) {
|
2446
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
2447
|
+
return type;
|
2448
|
+
}
|
2449
|
+
recursionCount++;
|
2450
|
+
// If the type has a condition associated with it, make sure it's compatible.
|
2451
|
+
if (!types_1.TypeCondition.isCompatible((0, typeUtils_1.getTypeCondition)(type), conditionFilter)) {
|
2452
|
+
return undefined;
|
2453
|
+
}
|
2454
|
+
// If the type is generic, see if any of its type arguments should be filtered.
|
2455
|
+
// This is possible only in cases where the type parameter is covariant.
|
2456
|
+
// TODO - handle functions and tuples
|
2457
|
+
if ((0, types_1.isClass)(type) && type.typeArguments && !type.tupleTypeArguments) {
|
2458
|
+
inferTypeParameterVarianceForClass(type);
|
2459
|
+
let typeWasTransformed = false;
|
2460
|
+
const filteredTypeArgs = type.typeArguments.map((typeArg, index) => {
|
2461
|
+
const variance = types_1.TypeVarType.getVariance(type.details.typeParameters[index]);
|
2462
|
+
if (variance !== 3 /* Covariant */) {
|
2463
|
+
return typeArg;
|
2464
|
+
}
|
2465
|
+
const filteredTypeArg = mapSubtypesExpandTypeVars(typeArg, conditionFilter, (expandedSubtype) => {
|
2466
|
+
return expandedSubtype;
|
2467
|
+
}, recursionCount);
|
2468
|
+
if (filteredTypeArg !== typeArg) {
|
2469
|
+
typeWasTransformed = true;
|
2470
|
+
}
|
2471
|
+
return filteredTypeArg;
|
2472
|
+
});
|
2473
|
+
if (typeWasTransformed) {
|
2474
|
+
return types_1.ClassType.cloneForSpecialization(type, filteredTypeArgs, /* isTypeArgumentExplicit */ true);
|
2475
|
+
}
|
2476
|
+
}
|
2477
|
+
return type;
|
2478
|
+
}
|
2441
2479
|
function markNamesAccessed(node, names) {
|
2442
2480
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
2443
2481
|
const scope = ScopeUtils.getScopeForNode(node);
|
@@ -2814,7 +2852,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2814
2852
|
// Verify that the name does not refer to a (non type alias) variable.
|
2815
2853
|
if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
|
2816
2854
|
let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
|
2817
|
-
if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
|
2855
|
+
if ((0, types_1.isClass)(type) && !type.includeSubclasses && !symbol.hasTypedDeclarations()) {
|
2818
2856
|
// This check exempts class types that are created by calling
|
2819
2857
|
// NewType, NamedTuple, and by invoking a metaclass directly.
|
2820
2858
|
isAllowedTypeForVariable = true;
|
@@ -2892,13 +2930,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2892
2930
|
function getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType) {
|
2893
2931
|
// This function applies only to variables, parameters, and imports, not to other
|
2894
2932
|
// types of symbols.
|
2895
|
-
|
2896
|
-
|
2897
|
-
.every((decl) => decl.type === 1 /* Variable */ ||
|
2933
|
+
const decls = symbolWithScope.symbol.getDeclarations();
|
2934
|
+
if (!decls.every((decl) => decl.type === 1 /* Variable */ ||
|
2898
2935
|
decl.type === 2 /* Parameter */ ||
|
2899
2936
|
decl.type === 8 /* Alias */)) {
|
2900
2937
|
return undefined;
|
2901
2938
|
}
|
2939
|
+
// If the symbol is modified in scopes other than the one in which it is
|
2940
|
+
// declared (e.g. through a nonlocal or global binding), it is not eligible
|
2941
|
+
// for code flow analysis.
|
2942
|
+
if (!decls.every((decl) => decl.type === 2 /* Parameter */ ||
|
2943
|
+
ScopeUtils.getScopeForNode(decl.node) === symbolWithScope.scope)) {
|
2944
|
+
return undefined;
|
2945
|
+
}
|
2902
2946
|
// If the symbol is a variable captured by an inner function
|
2903
2947
|
// or lambda, see if we can infer the type from the outer scope.
|
2904
2948
|
const scopeHierarchy = ScopeUtils.getScopeHierarchy(node, symbolWithScope.scope);
|
@@ -2934,7 +2978,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2934
2978
|
return !codeFlowEngine.isFlowNodeReachable(declCodeFlowNode, innerScopeCodeFlowNode,
|
2935
2979
|
/* ignoreNoReturn */ true);
|
2936
2980
|
})) {
|
2937
|
-
|
2981
|
+
let typeAtStart = effectiveType;
|
2982
|
+
if (symbolWithScope.symbol.isInitiallyUnbound()) {
|
2983
|
+
typeAtStart = types_1.UnboundType.create();
|
2984
|
+
}
|
2985
|
+
return getFlowTypeOfReference(node, symbolWithScope.symbol.id, typeAtStart, innerScopeNode);
|
2938
2986
|
}
|
2939
2987
|
}
|
2940
2988
|
}
|
@@ -3290,7 +3338,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3290
3338
|
baseType = objectType;
|
3291
3339
|
}
|
3292
3340
|
}
|
3293
|
-
|
3341
|
+
function getTypeOfNoneBase(subtype) {
|
3294
3342
|
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
3295
3343
|
if (types_1.TypeBase.isInstance(subtype)) {
|
3296
3344
|
return getTypeOfObjectMember(node.memberName, types_1.ClassType.cloneAsInstance(noneType), memberName, usage, diag);
|
@@ -3300,7 +3348,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3300
3348
|
}
|
3301
3349
|
}
|
3302
3350
|
return undefined;
|
3303
|
-
}
|
3351
|
+
}
|
3304
3352
|
if ((0, types_1.isParamSpec)(baseType) && baseType.paramSpecAccess) {
|
3305
3353
|
baseType = makeTopLevelTypeVarsConcrete(baseType);
|
3306
3354
|
}
|
@@ -3346,11 +3394,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3346
3394
|
if (baseType.details.recursiveTypeAliasName) {
|
3347
3395
|
return { type: types_1.UnknownType.create(/* isIncomplete */ true), isIncomplete: true };
|
3348
3396
|
}
|
3349
|
-
|
3350
|
-
|
3351
|
-
|
3352
|
-
|
3353
|
-
|
3397
|
+
if (!baseType.details.isVariadic) {
|
3398
|
+
return getTypeOfMemberAccessWithBaseType(node, {
|
3399
|
+
type: makeTopLevelTypeVarsConcrete(baseType),
|
3400
|
+
bindToType: baseType,
|
3401
|
+
isIncomplete,
|
3402
|
+
}, usage, 0 /* None */);
|
3403
|
+
}
|
3404
|
+
break;
|
3354
3405
|
}
|
3355
3406
|
case 7 /* Class */: {
|
3356
3407
|
if (types_1.TypeBase.isInstantiable(baseType)) {
|
@@ -3821,7 +3872,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3821
3872
|
type: types_1.ClassType.isClassProperty(lookupClass)
|
3822
3873
|
? baseTypeClass
|
3823
3874
|
: isAccessedThroughObject
|
3824
|
-
? bindToType
|
3875
|
+
? bindToType !== null && bindToType !== void 0 ? bindToType : types_1.ClassType.cloneAsInstance(baseTypeClass)
|
3825
3876
|
: types_1.NoneType.createInstance(),
|
3826
3877
|
},
|
3827
3878
|
},
|
@@ -3970,8 +4021,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3970
4021
|
// If this function is an instance member (e.g. a lambda that was
|
3971
4022
|
// assigned to an instance variable), don't perform any binding.
|
3972
4023
|
if (!isAccessedThroughObject || (memberInfo && !memberInfo.isInstanceMember)) {
|
4024
|
+
let effectiveBindToType = bindToType;
|
4025
|
+
if (bindToType && !(0, typeUtils_1.isInstantiableMetaclass)(baseTypeClass)) {
|
4026
|
+
// If bindToType is an instantiable class or TypeVar but we're targeting
|
4027
|
+
// an instance method (in a non-metaclass), we need to convert
|
4028
|
+
// the bindToType to an instance.
|
4029
|
+
const targetMethod = (0, types_1.isFunction)(concreteSubtype)
|
4030
|
+
? concreteSubtype
|
4031
|
+
: concreteSubtype.overloads[0];
|
4032
|
+
if (types_1.FunctionType.isInstanceMethod(targetMethod) && !types_1.TypeBase.isInstance(bindToType)) {
|
4033
|
+
effectiveBindToType = (0, typeUtils_1.convertToInstance)(bindToType);
|
4034
|
+
}
|
4035
|
+
}
|
3973
4036
|
return bindFunctionToClassOrObject(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode,
|
3974
|
-
/* recursionCount */ undefined, treatConstructorAsClassMember,
|
4037
|
+
/* recursionCount */ undefined, treatConstructorAsClassMember, effectiveBindToType);
|
3975
4038
|
}
|
3976
4039
|
}
|
3977
4040
|
if (usage.method === 'set') {
|
@@ -5263,6 +5326,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5263
5326
|
function getTypeOfCall(node, flags, inferenceContext) {
|
5264
5327
|
var _a;
|
5265
5328
|
let baseTypeResult;
|
5329
|
+
// Check for the use of `type(x)` within a type annotation. This isn't
|
5330
|
+
// allowed, and it's a common mistake, so we want to emit a diagnostic
|
5331
|
+
// that guides the user to the right solution.
|
5266
5332
|
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
|
5267
5333
|
node.leftExpression.nodeType === 38 /* Name */ &&
|
5268
5334
|
node.leftExpression.value === 'type') {
|
@@ -5324,20 +5390,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5324
5390
|
}
|
5325
5391
|
}
|
5326
5392
|
else {
|
5327
|
-
// Check for an attempt to invoke an abstract static or class method.
|
5328
|
-
if ((0, types_1.isFunction)(baseTypeResult.type) &&
|
5329
|
-
baseTypeResult.type.boundToType &&
|
5330
|
-
(0, types_1.isInstantiableClass)(baseTypeResult.type.boundToType) &&
|
5331
|
-
!baseTypeResult.type.boundToType.includeSubclasses) {
|
5332
|
-
if (types_1.FunctionType.isAbstractMethod(baseTypeResult.type)) {
|
5333
|
-
if (types_1.FunctionType.isStaticMethod(baseTypeResult.type) ||
|
5334
|
-
types_1.FunctionType.isClassMethod(baseTypeResult.type)) {
|
5335
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
|
5336
|
-
method: baseTypeResult.type.details.name,
|
5337
|
-
}), node.leftExpression);
|
5338
|
-
}
|
5339
|
-
}
|
5340
|
-
}
|
5341
5393
|
const callResult = validateCallArguments(node, argList, baseTypeResult,
|
5342
5394
|
/* typeVarContext */ undefined,
|
5343
5395
|
/* skipUnknownArgCheck */ false, inferenceContext);
|
@@ -5776,7 +5828,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5776
5828
|
// If there were multiple possible matches, evaluate the type as
|
5777
5829
|
// Unknown, but include the "possible types" to allow for completion
|
5778
5830
|
// suggestions.
|
5779
|
-
if (!isDefinitiveMatchFound) {
|
5831
|
+
if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
|
5780
5832
|
possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
|
5781
5833
|
// Did the filtering produce a single result? If so, we're done.
|
5782
5834
|
if (possibleMatchResults.length === 1) {
|
@@ -5984,24 +6036,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5984
6036
|
}
|
5985
6037
|
return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
|
5986
6038
|
}
|
5987
|
-
// Create a helper function that evaluates the overload that
|
5988
|
-
// the arg/param lists.
|
5989
|
-
function
|
5990
|
-
// Find the match with the
|
5991
|
-
//
|
5992
|
-
|
5993
|
-
|
6039
|
+
// Create a helper function that evaluates the overload that best
|
6040
|
+
// matches the arg/param lists.
|
6041
|
+
function evaluateUsingBestMatchingOverload(skipUnknownArgCheck) {
|
6042
|
+
// Find the match with the smallest argument match score. If there
|
6043
|
+
// are more than one with the same score, use the one with the
|
6044
|
+
// largest index. Later overloads tend to be more general.
|
6045
|
+
const bestMatch = filteredMatchResults.reduce((previous, current) => {
|
6046
|
+
if (current.argumentMatchScore === previous.argumentMatchScore) {
|
6047
|
+
return current.overloadIndex > previous.overloadIndex ? current : previous;
|
6048
|
+
}
|
6049
|
+
return current.argumentMatchScore < previous.argumentMatchScore ? current : previous;
|
5994
6050
|
});
|
5995
6051
|
const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
|
5996
|
-
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(
|
6052
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(bestMatch.overload));
|
5997
6053
|
effectiveTypeVarContext.unlock();
|
5998
|
-
return validateFunctionArgumentTypesWithContext(errorNode,
|
6054
|
+
return validateFunctionArgumentTypesWithContext(errorNode, bestMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5999
6055
|
}
|
6000
6056
|
// If there is only one possible arg/param match among the overloads,
|
6001
6057
|
// use the normal type matching mechanism because it is faster and
|
6002
6058
|
// will provide a clearer error message.
|
6003
6059
|
if (filteredMatchResults.length === 1) {
|
6004
|
-
return
|
6060
|
+
return evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ false);
|
6005
6061
|
}
|
6006
6062
|
let expandedArgTypes = [argList.map((arg) => undefined)];
|
6007
6063
|
let isTypeIncomplete = !!typeResult.isIncomplete;
|
@@ -6044,7 +6100,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6044
6100
|
// in speculative mode because it's very expensive, and we're going to
|
6045
6101
|
// suppress the diagnostic anyway.
|
6046
6102
|
if (!isDiagnosticSuppressedForNode(errorNode) && !isTypeIncomplete) {
|
6047
|
-
const result =
|
6103
|
+
const result = evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ true);
|
6048
6104
|
// Replace the result with an unknown type since we don't know
|
6049
6105
|
// what overload should have been used.
|
6050
6106
|
result.returnType = types_1.UnknownType.create();
|
@@ -6120,334 +6176,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6120
6176
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
6121
6177
|
}
|
6122
6178
|
let returnType = mapSubtypesExpandTypeVars(callTypeResult.type,
|
6123
|
-
/* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype) => {
|
6124
|
-
|
6125
|
-
|
6126
|
-
|
6127
|
-
|
6128
|
-
// Touch all of the args so they're marked accessed. Don't bother
|
6129
|
-
// doing this if the call type is incomplete because this will need
|
6130
|
-
// to be done again once it is complete.
|
6131
|
-
if (!callTypeResult.isIncomplete) {
|
6132
|
-
argList.forEach((arg) => {
|
6133
|
-
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6134
|
-
getTypeOfArgument(arg);
|
6135
|
-
}
|
6136
|
-
});
|
6137
|
-
}
|
6138
|
-
return expandedSubtype;
|
6139
|
-
}
|
6140
|
-
case 5 /* Function */: {
|
6141
|
-
if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
|
6142
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
|
6143
|
-
type: printType(expandedSubtype),
|
6144
|
-
}), errorNode);
|
6145
|
-
argumentErrors = true;
|
6146
|
-
return undefined;
|
6147
|
-
}
|
6148
|
-
// The stdlib collections/__init__.pyi stub file defines namedtuple
|
6149
|
-
// as a function rather than a class, so we need to check for it here.
|
6150
|
-
if (expandedSubtype.details.builtInName === 'namedtuple') {
|
6151
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
|
6152
|
-
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
6153
|
-
/* includesTypes */ false);
|
6154
|
-
}
|
6155
|
-
// Handle the NewType specially, replacing the normal return type.
|
6156
|
-
if (expandedSubtype.details.builtInName === 'NewType') {
|
6157
|
-
return createNewType(errorNode, argList);
|
6158
|
-
}
|
6159
|
-
let effectiveTypeVarContext = typeVarContext;
|
6160
|
-
if (!effectiveTypeVarContext) {
|
6161
|
-
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6162
|
-
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
|
6163
|
-
// There are certain cases, such as with super().__new__(cls) calls where
|
6164
|
-
// the call is a constructor but the proper TypeVar scope has been lost.
|
6165
|
-
// We'll add a wildcard TypeVar scope here. This is a bit of a hack and
|
6166
|
-
// we may need to revisit this in the future.
|
6167
|
-
if (types_1.FunctionType.isConstructorMethod(expandedSubtype)) {
|
6168
|
-
effectiveTypeVarContext.addSolveForScope(types_1.WildcardTypeVarScopeId);
|
6169
|
-
}
|
6170
|
-
}
|
6171
|
-
const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6172
|
-
if (functionResult.isTypeIncomplete) {
|
6173
|
-
isTypeIncomplete = true;
|
6174
|
-
}
|
6175
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
|
6176
|
-
if (functionResult.argumentErrors) {
|
6177
|
-
argumentErrors = true;
|
6178
|
-
}
|
6179
|
-
else {
|
6180
|
-
specializedInitSelfType = functionResult.specializedInitSelfType;
|
6181
|
-
// Call the function transform logic to handle special-cased functions.
|
6182
|
-
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
|
6183
|
-
argumentErrors: functionResult.argumentErrors,
|
6184
|
-
returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
|
6185
|
-
isTypeIncomplete,
|
6186
|
-
});
|
6187
|
-
functionResult.returnType = transformed.returnType;
|
6188
|
-
if (transformed.isTypeIncomplete) {
|
6189
|
-
isTypeIncomplete = true;
|
6190
|
-
}
|
6191
|
-
if (transformed.argumentErrors) {
|
6192
|
-
argumentErrors = true;
|
6193
|
-
}
|
6194
|
-
}
|
6195
|
-
if (expandedSubtype.details.builtInName === '__import__') {
|
6196
|
-
// For the special __import__ type, we'll override the return type to be "Any".
|
6197
|
-
// This is required because we don't know what module was imported, and we don't
|
6198
|
-
// want to fail type checks when accessing members of the resulting module type.
|
6199
|
-
return types_1.AnyType.create();
|
6200
|
-
}
|
6201
|
-
return functionResult.returnType;
|
6202
|
-
}
|
6203
|
-
case 6 /* OverloadedFunction */: {
|
6204
|
-
// Handle the 'cast' call as a special case.
|
6205
|
-
if (expandedSubtype.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
|
6206
|
-
return evaluateCastCall(argList, errorNode);
|
6207
|
-
}
|
6208
|
-
const functionResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6209
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
|
6210
|
-
if (functionResult.isTypeIncomplete) {
|
6211
|
-
isTypeIncomplete = true;
|
6212
|
-
}
|
6213
|
-
if (functionResult.argumentErrors) {
|
6214
|
-
argumentErrors = true;
|
6215
|
-
}
|
6216
|
-
else {
|
6217
|
-
specializedInitSelfType = functionResult.specializedInitSelfType;
|
6218
|
-
// Call the function transform logic to handle special-cased functions.
|
6219
|
-
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
|
6220
|
-
argumentErrors: functionResult.argumentErrors,
|
6221
|
-
returnType: (_b = functionResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
|
6222
|
-
isTypeIncomplete,
|
6223
|
-
});
|
6224
|
-
functionResult.returnType = transformed.returnType;
|
6225
|
-
if (transformed.isTypeIncomplete) {
|
6226
|
-
isTypeIncomplete = true;
|
6227
|
-
}
|
6228
|
-
if (transformed.argumentErrors) {
|
6229
|
-
argumentErrors = true;
|
6230
|
-
}
|
6231
|
-
}
|
6232
|
-
return (_c = functionResult.returnType) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
|
6233
|
-
}
|
6234
|
-
case 7 /* Class */: {
|
6235
|
-
if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
|
6236
|
-
if (expandedSubtype.literalValue !== undefined) {
|
6237
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
|
6238
|
-
argumentErrors = true;
|
6239
|
-
return types_1.UnknownType.create();
|
6240
|
-
}
|
6241
|
-
if (types_1.ClassType.isBuiltIn(expandedSubtype)) {
|
6242
|
-
const className = expandedSubtype.aliasName || expandedSubtype.details.name;
|
6243
|
-
if (className === 'type') {
|
6244
|
-
// Validate the constructor arguments.
|
6245
|
-
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6246
|
-
// Handle the 'type' call specially.
|
6247
|
-
if (argList.length === 1) {
|
6248
|
-
// The one-parameter form of "type" returns the class
|
6249
|
-
// for the specified object.
|
6250
|
-
const argType = getTypeOfArgument(argList[0]).type;
|
6251
|
-
return (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
|
6252
|
-
if ((0, types_1.isClassInstance)(subtype) ||
|
6253
|
-
((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
|
6254
|
-
(0, types_1.isNoneInstance)(subtype)) {
|
6255
|
-
return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
|
6256
|
-
}
|
6257
|
-
else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
|
6258
|
-
return types_1.FunctionType.cloneAsInstantiable(subtype);
|
6259
|
-
}
|
6260
|
-
return types_1.AnyType.create();
|
6261
|
-
});
|
6262
|
-
}
|
6263
|
-
else if (argList.length >= 2) {
|
6264
|
-
// The two-parameter form of "type" returns a new class type
|
6265
|
-
// built from the specified base types.
|
6266
|
-
return createType(errorNode, argList) || types_1.AnyType.create();
|
6267
|
-
}
|
6268
|
-
// If the parameter to type() is not statically known,
|
6269
|
-
// fall back to Any.
|
6270
|
-
return types_1.AnyType.create();
|
6271
|
-
}
|
6272
|
-
if (className === 'TypeVar') {
|
6273
|
-
return createTypeVarType(errorNode, expandedSubtype, argList);
|
6274
|
-
}
|
6275
|
-
if (className === 'TypeVarTuple') {
|
6276
|
-
return createTypeVarTupleType(errorNode, expandedSubtype, argList);
|
6277
|
-
}
|
6278
|
-
if (className === 'ParamSpec') {
|
6279
|
-
return createParamSpecType(errorNode, expandedSubtype, argList);
|
6280
|
-
}
|
6281
|
-
if (className === 'TypeAliasType') {
|
6282
|
-
const newTypeAlias = createTypeAliasType(errorNode, argList);
|
6283
|
-
if (newTypeAlias) {
|
6284
|
-
return newTypeAlias;
|
6285
|
-
}
|
6286
|
-
}
|
6287
|
-
if (className === 'NamedTuple') {
|
6288
|
-
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
6289
|
-
/* includesTypes */ true);
|
6290
|
-
}
|
6291
|
-
if (className === 'NewType') {
|
6292
|
-
return createNewType(errorNode, argList);
|
6293
|
-
}
|
6294
|
-
if (className === 'Protocol' ||
|
6295
|
-
className === 'Generic' ||
|
6296
|
-
className === 'Callable' ||
|
6297
|
-
className === 'Concatenate' ||
|
6298
|
-
className === 'Type') {
|
6299
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
6300
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
|
6301
|
-
return types_1.AnyType.create();
|
6302
|
-
}
|
6303
|
-
if ((0, types_1.isClass)(unexpandedSubtype) && (0, enums_1.isKnownEnumType)(className)) {
|
6304
|
-
return ((_d = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedSubtype, argList)) !== null && _d !== void 0 ? _d : types_1.UnknownType.create());
|
6305
|
-
}
|
6306
|
-
if (className === 'TypedDict') {
|
6307
|
-
return (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedSubtype, argList);
|
6308
|
-
}
|
6309
|
-
if (className === 'auto' && argList.length === 0) {
|
6310
|
-
return (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode);
|
6311
|
-
}
|
6312
|
-
}
|
6313
|
-
if (types_1.ClassType.supportsAbstractMethods(expandedSubtype)) {
|
6314
|
-
const abstractMethods = getAbstractMethods(expandedSubtype);
|
6315
|
-
if (abstractMethods.length > 0 &&
|
6316
|
-
!expandedSubtype.includeSubclasses &&
|
6317
|
-
!(0, types_1.isTypeVar)(unexpandedSubtype)) {
|
6318
|
-
// If the class is abstract, it can't be instantiated.
|
6319
|
-
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
6320
|
-
const errorsToDisplay = 2;
|
6321
|
-
abstractMethods.forEach((abstractMethod, index) => {
|
6322
|
-
if (index === errorsToDisplay) {
|
6323
|
-
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
|
6324
|
-
count: abstractMethods.length - errorsToDisplay,
|
6325
|
-
}));
|
6326
|
-
}
|
6327
|
-
else if (index < errorsToDisplay) {
|
6328
|
-
if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
|
6329
|
-
const className = abstractMethod.classType.details.name;
|
6330
|
-
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
|
6331
|
-
type: className,
|
6332
|
-
name: abstractMethod.symbolName,
|
6333
|
-
}));
|
6334
|
-
}
|
6335
|
-
}
|
6336
|
-
});
|
6337
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
|
6338
|
-
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
|
6339
|
-
type: expandedSubtype.details.name,
|
6340
|
-
}) + diagAddendum.getString(), errorNode);
|
6341
|
-
}
|
6342
|
-
}
|
6343
|
-
if (types_1.ClassType.isProtocolClass(expandedSubtype) && !expandedSubtype.includeSubclasses) {
|
6344
|
-
// If the class is a protocol, it can't be instantiated.
|
6345
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
|
6346
|
-
type: expandedSubtype.details.name,
|
6347
|
-
}), errorNode);
|
6348
|
-
}
|
6349
|
-
// Assume this is a call to the constructor.
|
6350
|
-
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6351
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, constructorResult.overloadsUsedForCall);
|
6352
|
-
if (constructorResult.argumentErrors) {
|
6353
|
-
argumentErrors = true;
|
6354
|
-
}
|
6355
|
-
if (constructorResult.isTypeIncomplete) {
|
6356
|
-
isTypeIncomplete = true;
|
6357
|
-
}
|
6358
|
-
let returnType = constructorResult.returnType;
|
6359
|
-
// If the expandedSubtype originated from a TypeVar, convert
|
6360
|
-
// the constructed type back to the TypeVar. For example, if
|
6361
|
-
// we have `cls: Type[_T]` followed by `_T()`.
|
6362
|
-
if ((0, types_1.isTypeVar)(unexpandedSubtype)) {
|
6363
|
-
returnType = (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
|
6364
|
-
}
|
6365
|
-
// If we instantiated a type, transform it into a class.
|
6366
|
-
// This can happen if someone directly instantiates a metaclass
|
6367
|
-
// deriving from type.
|
6368
|
-
if (returnType &&
|
6369
|
-
(0, types_1.isClassInstance)(returnType) &&
|
6370
|
-
returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
|
6371
|
-
let newClassName = '__class_' + returnType.details.name;
|
6372
|
-
if (argList.length === 3) {
|
6373
|
-
const firstArgType = getTypeOfArgument(argList[0]).type;
|
6374
|
-
if ((0, types_1.isClassInstance)(firstArgType) &&
|
6375
|
-
types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
|
6376
|
-
typeof firstArgType.literalValue === 'string') {
|
6377
|
-
newClassName = firstArgType.literalValue;
|
6378
|
-
}
|
6379
|
-
}
|
6380
|
-
const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '', AnalyzerNodeInfo.getFileInfo(errorNode).filePath, 0 /* None */, ParseTreeUtils.getTypeSourceId(errorNode), types_1.ClassType.cloneAsInstantiable(returnType), types_1.ClassType.cloneAsInstantiable(returnType));
|
6381
|
-
newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
|
6382
|
-
newClassType.details.effectiveMetaclass = expandedSubtype;
|
6383
|
-
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
6384
|
-
return newClassType;
|
6385
|
-
}
|
6386
|
-
return returnType;
|
6387
|
-
}
|
6388
|
-
else {
|
6389
|
-
const memberType = (_e = getTypeOfObjectMember(errorNode, expandedSubtype, '__call__',
|
6390
|
-
/* usage */ undefined,
|
6391
|
-
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _e === void 0 ? void 0 : _e.type;
|
6392
|
-
if (memberType) {
|
6393
|
-
const functionResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6394
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
|
6395
|
-
if (functionResult.argumentErrors) {
|
6396
|
-
argumentErrors = true;
|
6397
|
-
}
|
6398
|
-
if ((0, types_1.isTypeVar)(unexpandedSubtype) &&
|
6399
|
-
types_1.TypeBase.isInstantiable(unexpandedSubtype) &&
|
6400
|
-
(0, types_1.isClass)(expandedSubtype) &&
|
6401
|
-
types_1.ClassType.isBuiltIn(expandedSubtype, 'type')) {
|
6402
|
-
// Handle the case where a Type[T] is being called. We presume this
|
6403
|
-
// will instantiate an object of type T.
|
6404
|
-
return (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
|
6405
|
-
}
|
6406
|
-
return (_f = functionResult.returnType) !== null && _f !== void 0 ? _f : types_1.UnknownType.create();
|
6407
|
-
}
|
6408
|
-
if (!memberType || !(0, types_1.isAnyOrUnknown)(memberType)) {
|
6409
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6410
|
-
type: printType(expandedSubtype),
|
6411
|
-
}), errorNode);
|
6412
|
-
}
|
6413
|
-
return types_1.UnknownType.create();
|
6414
|
-
}
|
6179
|
+
/* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
|
6180
|
+
return useSpeculativeMode(isLastIteration ? undefined : errorNode, () => {
|
6181
|
+
const callResult = validateCallArgumentsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6182
|
+
if (callResult.argumentErrors) {
|
6183
|
+
argumentErrors = true;
|
6415
6184
|
}
|
6416
|
-
|
6417
|
-
|
6418
|
-
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
6419
|
-
const functionResult = validateCallArguments(errorNode, argList, { type: noneType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6420
|
-
if (functionResult.isTypeIncomplete) {
|
6421
|
-
isTypeIncomplete = true;
|
6422
|
-
}
|
6423
|
-
if (functionResult.argumentErrors) {
|
6424
|
-
argumentErrors = true;
|
6425
|
-
}
|
6426
|
-
}
|
6427
|
-
return types_1.NoneType.createInstance();
|
6428
|
-
}
|
6429
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
|
6430
|
-
return undefined;
|
6185
|
+
if (callResult.isTypeIncomplete) {
|
6186
|
+
isTypeIncomplete = true;
|
6431
6187
|
}
|
6432
|
-
|
6433
|
-
// but we still need to handle the case of Type[T] where
|
6434
|
-
// T is a constrained type that contains a union. We also
|
6435
|
-
// need to handle recursive type aliases.
|
6436
|
-
case 10 /* TypeVar */: {
|
6437
|
-
expandedSubtype = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedSubtype);
|
6438
|
-
const callResult = validateCallArguments(errorNode, argList, { type: expandedSubtype }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6188
|
+
if (callResult.overloadsUsedForCall) {
|
6439
6189
|
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
|
6440
|
-
if (callResult.argumentErrors) {
|
6441
|
-
argumentErrors = true;
|
6442
|
-
}
|
6443
|
-
return (_g = callResult.returnType) !== null && _g !== void 0 ? _g : types_1.UnknownType.create();
|
6444
|
-
}
|
6445
|
-
case 8 /* Module */: {
|
6446
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
|
6447
|
-
return undefined;
|
6448
6190
|
}
|
6449
|
-
|
6450
|
-
|
6191
|
+
specializedInitSelfType = callResult.specializedInitSelfType;
|
6192
|
+
return callResult.returnType;
|
6193
|
+
}, {
|
6194
|
+
allowDiagnostics: true,
|
6195
|
+
});
|
6451
6196
|
});
|
6452
6197
|
// If we ended up with a "Never" type because all code paths returned
|
6453
6198
|
// undefined due to argument errors, transform the result into an Unknown
|
@@ -6463,10 +6208,350 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6463
6208
|
overloadsUsedForCall,
|
6464
6209
|
};
|
6465
6210
|
}
|
6211
|
+
function validateCallArgumentsForSubtype(errorNode, argList, expandedCallType, unexpandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6212
|
+
switch (expandedCallType.category) {
|
6213
|
+
case 4 /* Never */:
|
6214
|
+
case 1 /* Unknown */:
|
6215
|
+
case 2 /* Any */: {
|
6216
|
+
// Touch all of the args so they're marked accessed. Don't bother
|
6217
|
+
// doing this if the call type is incomplete because this will need
|
6218
|
+
// to be done again once it is complete.
|
6219
|
+
if (!isCallTypeIncomplete) {
|
6220
|
+
argList.forEach((arg) => {
|
6221
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6222
|
+
getTypeOfArgument(arg);
|
6223
|
+
}
|
6224
|
+
});
|
6225
|
+
}
|
6226
|
+
return { returnType: expandedCallType };
|
6227
|
+
}
|
6228
|
+
case 5 /* Function */: {
|
6229
|
+
return validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6230
|
+
}
|
6231
|
+
case 6 /* OverloadedFunction */: {
|
6232
|
+
return validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6233
|
+
}
|
6234
|
+
case 7 /* Class */: {
|
6235
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6236
|
+
return validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext);
|
6237
|
+
}
|
6238
|
+
return validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6239
|
+
}
|
6240
|
+
case 3 /* None */: {
|
6241
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6242
|
+
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
6243
|
+
const callResult = validateCallForInstantiableClass(errorNode, argList, noneType, noneType, skipUnknownArgCheck, inferenceContext);
|
6244
|
+
return { ...callResult, returnType: types_1.NoneType.createInstance() };
|
6245
|
+
}
|
6246
|
+
return { returnType: types_1.NoneType.createInstance() };
|
6247
|
+
}
|
6248
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
|
6249
|
+
return { argumentErrors: true };
|
6250
|
+
}
|
6251
|
+
// TypeVars should have been expanded in most cases,
|
6252
|
+
// but we still need to handle the case of Type[T] where
|
6253
|
+
// T is a constrained type that contains a union. We also
|
6254
|
+
// need to handle recursive type aliases.
|
6255
|
+
case 10 /* TypeVar */: {
|
6256
|
+
return validateCallArguments(errorNode, argList, { type: (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedCallType), isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6257
|
+
}
|
6258
|
+
case 8 /* Module */: {
|
6259
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
|
6260
|
+
return { argumentErrors: true };
|
6261
|
+
}
|
6262
|
+
}
|
6263
|
+
return { argumentErrors: true };
|
6264
|
+
}
|
6265
|
+
function validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
6266
|
+
var _a;
|
6267
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6268
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
|
6269
|
+
type: printType(expandedCallType),
|
6270
|
+
}), errorNode);
|
6271
|
+
return { returnType: undefined, argumentErrors: true };
|
6272
|
+
}
|
6273
|
+
// Check for an attempt to invoke an abstract static or class method.
|
6274
|
+
if (expandedCallType.boundToType &&
|
6275
|
+
(0, types_1.isInstantiableClass)(expandedCallType.boundToType) &&
|
6276
|
+
!expandedCallType.boundToType.includeSubclasses) {
|
6277
|
+
if (types_1.FunctionType.isAbstractMethod(expandedCallType)) {
|
6278
|
+
if (types_1.FunctionType.isStaticMethod(expandedCallType) || types_1.FunctionType.isClassMethod(expandedCallType)) {
|
6279
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
|
6280
|
+
method: expandedCallType.details.name,
|
6281
|
+
}), errorNode.nodeType === 9 /* Call */ ? errorNode.leftExpression : errorNode);
|
6282
|
+
}
|
6283
|
+
}
|
6284
|
+
}
|
6285
|
+
// The stdlib collections/__init__.pyi stub file defines namedtuple
|
6286
|
+
// as a function rather than a class, so we need to check for it here.
|
6287
|
+
if (expandedCallType.details.builtInName === 'namedtuple') {
|
6288
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
|
6289
|
+
return {
|
6290
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ false),
|
6291
|
+
};
|
6292
|
+
}
|
6293
|
+
// Handle the NewType specially, replacing the normal return type.
|
6294
|
+
if (expandedCallType.details.builtInName === 'NewType') {
|
6295
|
+
return { returnType: createNewType(errorNode, argList) };
|
6296
|
+
}
|
6297
|
+
let effectiveTypeVarContext = typeVarContext;
|
6298
|
+
if (!effectiveTypeVarContext) {
|
6299
|
+
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6300
|
+
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
|
6301
|
+
}
|
6302
|
+
const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6303
|
+
let isTypeIncomplete = !!functionResult.isTypeIncomplete;
|
6304
|
+
let returnType = functionResult.returnType;
|
6305
|
+
let argumentErrors = !!functionResult.argumentErrors;
|
6306
|
+
if (!argumentErrors) {
|
6307
|
+
// Call the function transform logic to handle special-cased functions.
|
6308
|
+
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
6309
|
+
argumentErrors: !!functionResult.argumentErrors,
|
6310
|
+
returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
|
6311
|
+
isTypeIncomplete,
|
6312
|
+
});
|
6313
|
+
returnType = transformed.returnType;
|
6314
|
+
if (transformed.isTypeIncomplete) {
|
6315
|
+
isTypeIncomplete = true;
|
6316
|
+
}
|
6317
|
+
if (transformed.argumentErrors) {
|
6318
|
+
argumentErrors = true;
|
6319
|
+
}
|
6320
|
+
}
|
6321
|
+
if (expandedCallType.details.builtInName === '__import__') {
|
6322
|
+
// For the special __import__ type, we'll override the return type to be "Any".
|
6323
|
+
// This is required because we don't know what module was imported, and we don't
|
6324
|
+
// want to fail type checks when accessing members of the resulting module type.
|
6325
|
+
returnType = types_1.AnyType.create();
|
6326
|
+
}
|
6327
|
+
return {
|
6328
|
+
returnType,
|
6329
|
+
isTypeIncomplete,
|
6330
|
+
argumentErrors,
|
6331
|
+
overloadsUsedForCall: functionResult.overloadsUsedForCall,
|
6332
|
+
specializedInitSelfType: functionResult.specializedInitSelfType,
|
6333
|
+
};
|
6334
|
+
}
|
6335
|
+
function validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
6336
|
+
var _a, _b;
|
6337
|
+
// Handle the 'cast' call as a special case.
|
6338
|
+
if (expandedCallType.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
|
6339
|
+
return { returnType: evaluateCastCall(argList, errorNode) };
|
6340
|
+
}
|
6341
|
+
const callResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6342
|
+
let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
|
6343
|
+
let isTypeIncomplete = !!callResult.isTypeIncomplete;
|
6344
|
+
let argumentErrors = !!callResult.argumentErrors;
|
6345
|
+
if (!argumentErrors) {
|
6346
|
+
// Call the function transform logic to handle special-cased functions.
|
6347
|
+
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
6348
|
+
argumentErrors: !!callResult.argumentErrors,
|
6349
|
+
returnType: (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
|
6350
|
+
isTypeIncomplete,
|
6351
|
+
});
|
6352
|
+
returnType = transformed.returnType;
|
6353
|
+
if (transformed.isTypeIncomplete) {
|
6354
|
+
isTypeIncomplete = true;
|
6355
|
+
}
|
6356
|
+
if (transformed.argumentErrors) {
|
6357
|
+
argumentErrors = true;
|
6358
|
+
}
|
6359
|
+
}
|
6360
|
+
return {
|
6361
|
+
returnType,
|
6362
|
+
isTypeIncomplete,
|
6363
|
+
argumentErrors,
|
6364
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
6365
|
+
specializedInitSelfType: callResult.specializedInitSelfType,
|
6366
|
+
};
|
6367
|
+
}
|
6368
|
+
function validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext) {
|
6369
|
+
var _a;
|
6370
|
+
if (expandedCallType.literalValue !== undefined) {
|
6371
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
|
6372
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6373
|
+
}
|
6374
|
+
if (types_1.ClassType.isBuiltIn(expandedCallType)) {
|
6375
|
+
const className = expandedCallType.aliasName || expandedCallType.details.name;
|
6376
|
+
if (className === 'type') {
|
6377
|
+
// Validate the constructor arguments.
|
6378
|
+
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
|
6379
|
+
// Handle the 'type' call specially.
|
6380
|
+
if (argList.length === 1) {
|
6381
|
+
// The one-parameter form of "type" returns the class
|
6382
|
+
// for the specified object.
|
6383
|
+
const argType = getTypeOfArgument(argList[0]).type;
|
6384
|
+
const returnType = (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
|
6385
|
+
if ((0, types_1.isClassInstance)(subtype) ||
|
6386
|
+
((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
|
6387
|
+
(0, types_1.isNoneInstance)(subtype)) {
|
6388
|
+
return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
|
6389
|
+
}
|
6390
|
+
else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
|
6391
|
+
return types_1.FunctionType.cloneAsInstantiable(subtype);
|
6392
|
+
}
|
6393
|
+
return types_1.AnyType.create();
|
6394
|
+
});
|
6395
|
+
return { returnType };
|
6396
|
+
}
|
6397
|
+
if (argList.length >= 2) {
|
6398
|
+
// The two-parameter form of "type" returns a new class type
|
6399
|
+
// built from the specified base types.
|
6400
|
+
return { returnType: createType(errorNode, argList) || types_1.AnyType.create() };
|
6401
|
+
}
|
6402
|
+
// If the parameter to type() is not statically known,
|
6403
|
+
// fall back to Any.
|
6404
|
+
return { returnType: types_1.AnyType.create() };
|
6405
|
+
}
|
6406
|
+
if (className === 'TypeVar') {
|
6407
|
+
return {
|
6408
|
+
returnType: createTypeVarType(errorNode, expandedCallType, argList),
|
6409
|
+
};
|
6410
|
+
}
|
6411
|
+
if (className === 'TypeVarTuple') {
|
6412
|
+
return {
|
6413
|
+
returnType: createTypeVarTupleType(errorNode, expandedCallType, argList),
|
6414
|
+
};
|
6415
|
+
}
|
6416
|
+
if (className === 'ParamSpec') {
|
6417
|
+
return {
|
6418
|
+
returnType: createParamSpecType(errorNode, expandedCallType, argList),
|
6419
|
+
};
|
6420
|
+
}
|
6421
|
+
if (className === 'TypeAliasType') {
|
6422
|
+
const newTypeAlias = createTypeAliasType(errorNode, argList);
|
6423
|
+
if (newTypeAlias) {
|
6424
|
+
return { returnType: newTypeAlias };
|
6425
|
+
}
|
6426
|
+
}
|
6427
|
+
if (className === 'NamedTuple') {
|
6428
|
+
return {
|
6429
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
|
6430
|
+
};
|
6431
|
+
}
|
6432
|
+
if (className === 'NewType') {
|
6433
|
+
return { returnType: createNewType(errorNode, argList) };
|
6434
|
+
}
|
6435
|
+
if (className === 'Protocol' ||
|
6436
|
+
className === 'Generic' ||
|
6437
|
+
className === 'Callable' ||
|
6438
|
+
className === 'Concatenate' ||
|
6439
|
+
className === 'Type') {
|
6440
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
6441
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
|
6442
|
+
return { returnType: types_1.AnyType.create() };
|
6443
|
+
}
|
6444
|
+
if ((0, types_1.isClass)(unexpandedCallType) && (0, enums_1.isKnownEnumType)(className)) {
|
6445
|
+
return {
|
6446
|
+
returnType: (_a = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedCallType, argList)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(),
|
6447
|
+
};
|
6448
|
+
}
|
6449
|
+
if (className === 'TypedDict') {
|
6450
|
+
return { returnType: (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedCallType, argList) };
|
6451
|
+
}
|
6452
|
+
if (className === 'auto' && argList.length === 0) {
|
6453
|
+
return { returnType: (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode) };
|
6454
|
+
}
|
6455
|
+
}
|
6456
|
+
if (types_1.ClassType.supportsAbstractMethods(expandedCallType)) {
|
6457
|
+
const abstractMethods = getAbstractMethods(expandedCallType);
|
6458
|
+
if (abstractMethods.length > 0 && !expandedCallType.includeSubclasses && !(0, types_1.isTypeVar)(unexpandedCallType)) {
|
6459
|
+
// If the class is abstract, it can't be instantiated.
|
6460
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
6461
|
+
const errorsToDisplay = 2;
|
6462
|
+
abstractMethods.forEach((abstractMethod, index) => {
|
6463
|
+
if (index === errorsToDisplay) {
|
6464
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
|
6465
|
+
count: abstractMethods.length - errorsToDisplay,
|
6466
|
+
}));
|
6467
|
+
}
|
6468
|
+
else if (index < errorsToDisplay) {
|
6469
|
+
if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
|
6470
|
+
const className = abstractMethod.classType.details.name;
|
6471
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
|
6472
|
+
type: className,
|
6473
|
+
name: abstractMethod.symbolName,
|
6474
|
+
}));
|
6475
|
+
}
|
6476
|
+
}
|
6477
|
+
});
|
6478
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
|
6479
|
+
type: expandedCallType.details.name,
|
6480
|
+
}) + diagAddendum.getString(), errorNode);
|
6481
|
+
}
|
6482
|
+
}
|
6483
|
+
if (types_1.ClassType.isProtocolClass(expandedCallType) && !expandedCallType.includeSubclasses) {
|
6484
|
+
// If the class is a protocol, it can't be instantiated.
|
6485
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
|
6486
|
+
type: expandedCallType.details.name,
|
6487
|
+
}), errorNode);
|
6488
|
+
}
|
6489
|
+
// Assume this is a call to the constructor.
|
6490
|
+
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
|
6491
|
+
const overloadsUsedForCall = constructorResult.overloadsUsedForCall;
|
6492
|
+
const argumentErrors = constructorResult.argumentErrors;
|
6493
|
+
const isTypeIncomplete = constructorResult.isTypeIncomplete;
|
6494
|
+
let returnType = constructorResult.returnType;
|
6495
|
+
// If the expandedCallType originated from a TypeVar, convert
|
6496
|
+
// the constructed type back to the TypeVar. For example, if
|
6497
|
+
// we have `cls: Type[_T]` followed by `_T()`.
|
6498
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType)) {
|
6499
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
6500
|
+
}
|
6501
|
+
// If we instantiated a type, transform it into a class.
|
6502
|
+
// This can happen if someone directly instantiates a metaclass
|
6503
|
+
// deriving from type.
|
6504
|
+
if (returnType &&
|
6505
|
+
(0, types_1.isClassInstance)(returnType) &&
|
6506
|
+
returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
|
6507
|
+
let newClassName = '__class_' + returnType.details.name;
|
6508
|
+
if (argList.length === 3) {
|
6509
|
+
const firstArgType = getTypeOfArgument(argList[0]).type;
|
6510
|
+
if ((0, types_1.isClassInstance)(firstArgType) &&
|
6511
|
+
types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
|
6512
|
+
typeof firstArgType.literalValue === 'string') {
|
6513
|
+
newClassName = firstArgType.literalValue;
|
6514
|
+
}
|
6515
|
+
}
|
6516
|
+
const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '', AnalyzerNodeInfo.getFileInfo(errorNode).filePath, 0 /* None */, ParseTreeUtils.getTypeSourceId(errorNode), types_1.ClassType.cloneAsInstantiable(returnType), types_1.ClassType.cloneAsInstantiable(returnType));
|
6517
|
+
newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
|
6518
|
+
newClassType.details.effectiveMetaclass = expandedCallType;
|
6519
|
+
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
6520
|
+
returnType = newClassType;
|
6521
|
+
}
|
6522
|
+
return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
|
6523
|
+
}
|
6524
|
+
function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6525
|
+
var _a, _b;
|
6526
|
+
const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
|
6527
|
+
/* usage */ undefined,
|
6528
|
+
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
6529
|
+
if (!memberType) {
|
6530
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6531
|
+
type: printType(expandedCallType),
|
6532
|
+
}), errorNode);
|
6533
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6534
|
+
}
|
6535
|
+
const callResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6536
|
+
let returnType = (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
|
6537
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType) &&
|
6538
|
+
types_1.TypeBase.isInstantiable(unexpandedCallType) &&
|
6539
|
+
(0, types_1.isClass)(expandedCallType) &&
|
6540
|
+
types_1.ClassType.isBuiltIn(expandedCallType, 'type')) {
|
6541
|
+
// Handle the case where a Type[T] is being called. We presume this
|
6542
|
+
// will instantiate an object of type T.
|
6543
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
6544
|
+
}
|
6545
|
+
return {
|
6546
|
+
returnType,
|
6547
|
+
argumentErrors: callResult.argumentErrors,
|
6548
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
6549
|
+
};
|
6550
|
+
}
|
6466
6551
|
// Evaluates the type of the "cast" call.
|
6467
6552
|
function evaluateCastCall(argList, errorNode) {
|
6468
6553
|
// Verify that the cast is necessary.
|
6469
|
-
const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
|
6554
|
+
const castToType = getTypeOfArgumentExpectingType(argList[0], { enforceTypeAnnotationRules: true }).type;
|
6470
6555
|
const castFromType = getTypeOfArgument(argList[1]).type;
|
6471
6556
|
if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
|
6472
6557
|
if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
|
@@ -7328,6 +7413,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7328
7413
|
paramSpecArgList,
|
7329
7414
|
activeParam,
|
7330
7415
|
relevance,
|
7416
|
+
argumentMatchScore: 0,
|
7331
7417
|
};
|
7332
7418
|
}
|
7333
7419
|
// After having matched arguments with parameters, this function evaluates the
|
@@ -7403,7 +7489,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7403
7489
|
const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
|
7404
7490
|
/* typeArguments */ undefined,
|
7405
7491
|
/* isTypeArgumentExplicit */ false);
|
7406
|
-
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext
|
7492
|
+
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext, {
|
7493
|
+
unknownIfNotFound: true,
|
7494
|
+
});
|
7407
7495
|
}
|
7408
7496
|
}
|
7409
7497
|
else if ((0, types_1.isFunction)(effectiveReturnType)) {
|
@@ -7426,6 +7514,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7426
7514
|
const type = matchResults.overload;
|
7427
7515
|
let isTypeIncomplete = matchResults.isTypeIncomplete;
|
7428
7516
|
let argumentErrors = false;
|
7517
|
+
let argumentMatchScore = 0;
|
7429
7518
|
let specializedInitSelfType;
|
7430
7519
|
let anyOrUnknownArgument;
|
7431
7520
|
const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
|
@@ -7527,7 +7616,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7527
7616
|
let sawParamSpecKwargs = false;
|
7528
7617
|
let condition = [];
|
7529
7618
|
const argResults = [];
|
7530
|
-
matchResults.argParams.forEach((argParam) => {
|
7619
|
+
matchResults.argParams.forEach((argParam, argParamIndex) => {
|
7531
7620
|
var _a;
|
7532
7621
|
const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
|
7533
7622
|
skipUnknownArgCheck,
|
@@ -7536,6 +7625,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7536
7625
|
argResults.push(argResult);
|
7537
7626
|
if (!argResult.isCompatible) {
|
7538
7627
|
argumentErrors = true;
|
7628
|
+
// Add the inverse index so earlier parameters represent larger errors.
|
7629
|
+
// This will help the heuristics in the overload error paths to pick the
|
7630
|
+
// most likely intended overload if none of them match.
|
7631
|
+
argumentMatchScore += 1 + (matchResults.argParams.length - argParamIndex);
|
7539
7632
|
}
|
7540
7633
|
if (argResult.isTypeIncomplete) {
|
7541
7634
|
isTypeIncomplete = true;
|
@@ -7565,6 +7658,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7565
7658
|
if (matchResults.paramSpecArgList && matchResults.paramSpecTarget) {
|
7566
7659
|
if (!validateFunctionArgumentsForParamSpec(errorNode, matchResults.paramSpecArgList, matchResults.paramSpecTarget, typeVarContext, typeCondition)) {
|
7567
7660
|
argumentErrors = true;
|
7661
|
+
argumentMatchScore += 1;
|
7568
7662
|
}
|
7569
7663
|
}
|
7570
7664
|
else if (type.details.paramSpec) {
|
@@ -7573,6 +7667,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7573
7667
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecArgsMissing().format({ type: printType(type.details.paramSpec) }), errorNode);
|
7574
7668
|
}
|
7575
7669
|
argumentErrors = true;
|
7670
|
+
argumentMatchScore += 1;
|
7576
7671
|
}
|
7577
7672
|
}
|
7578
7673
|
// Calculate the return type.
|
@@ -7654,6 +7749,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7654
7749
|
if (specializedInitSelfType) {
|
7655
7750
|
specializedInitSelfType = (0, typeUtils_1.applySolvedTypeVars)(specializedInitSelfType, typeVarContext);
|
7656
7751
|
}
|
7752
|
+
matchResults.argumentMatchScore = argumentMatchScore;
|
7657
7753
|
return {
|
7658
7754
|
argumentErrors,
|
7659
7755
|
argResults,
|
@@ -7698,7 +7794,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7698
7794
|
// specific use case. We may need to make this more sophisticated in
|
7699
7795
|
// the future.
|
7700
7796
|
if ((0, types_1.isFunction)(returnType) && !returnType.details.name) {
|
7701
|
-
|
7797
|
+
const typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgumentsRecursive)(returnType);
|
7798
|
+
// If there are no unsolved type variables, we're done. If there are
|
7799
|
+
// unsolved type parameters, treat them as though they are rescoped
|
7800
|
+
// to the callable.
|
7801
|
+
if (typeVarsInReturnType.length > 0) {
|
7802
|
+
return types_1.FunctionType.cloneWithNewTypeVarScopeId(returnType, types_1.WildcardTypeVarScopeId, typeVarsInReturnType);
|
7803
|
+
}
|
7702
7804
|
}
|
7703
7805
|
return returnType;
|
7704
7806
|
}
|
@@ -8816,9 +8918,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8816
8918
|
// Dict and MutableMapping types have invariant value types, so they
|
8817
8919
|
// cannot be narrowed further. Other super-types like Mapping, Collection,
|
8818
8920
|
// and Iterable use covariant value types, so they can be narrowed.
|
8819
|
-
|
8820
|
-
|
8821
|
-
|
8921
|
+
let isValueTypeInvariant = false;
|
8922
|
+
if ((0, types_1.isClassInstance)(inferenceContext.expectedType)) {
|
8923
|
+
if (inferenceContext.expectedType.details.typeParameters.length >= 2) {
|
8924
|
+
const valueTypeParam = inferenceContext.expectedType.details.typeParameters[1];
|
8925
|
+
if (types_1.TypeVarType.getVariance(valueTypeParam) === 2 /* Invariant */) {
|
8926
|
+
isValueTypeInvariant = true;
|
8927
|
+
}
|
8928
|
+
}
|
8929
|
+
}
|
8822
8930
|
// Infer the key and value types if possible.
|
8823
8931
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8824
8932
|
/* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
@@ -9416,7 +9524,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9416
9524
|
if (returnTypeResult.isIncomplete) {
|
9417
9525
|
isIncomplete = true;
|
9418
9526
|
}
|
9419
|
-
},
|
9527
|
+
}, {
|
9528
|
+
dependentType: inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType,
|
9529
|
+
});
|
9420
9530
|
// Mark the function type as no longer being evaluated.
|
9421
9531
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
9422
9532
|
return { type: functionType, isIncomplete };
|
@@ -9642,13 +9752,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9642
9752
|
}
|
9643
9753
|
return true;
|
9644
9754
|
}
|
9645
|
-
//
|
9646
|
-
//
|
9647
|
-
//
|
9648
|
-
// present, should specify the return type.
|
9755
|
+
// Evaluates the type arguments for a Callable type. It should have zero
|
9756
|
+
// to two arguments.The first argument, if present, should be an ellipsis,
|
9757
|
+
// a ParamSpec, a Concatenate, or a list of positional parameter types.
|
9758
|
+
// The second argument, if present, should specify the return type.
|
9649
9759
|
function createCallableType(typeArgs, errorNode) {
|
9650
|
-
// Create a new function that is marked as "static" so there is later
|
9651
|
-
// no attempt to bind it as though it's an instance or class method.
|
9652
9760
|
const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
|
9653
9761
|
types_1.TypeBase.setSpecialForm(functionType);
|
9654
9762
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
@@ -10342,12 +10450,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10342
10450
|
// Determine if there are any generic type parameters associated
|
10343
10451
|
// with this type alias.
|
10344
10452
|
typeParameters = [];
|
10345
|
-
|
10346
|
-
|
10347
|
-
|
10348
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10349
|
-
});
|
10350
|
-
}
|
10453
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
10454
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10455
|
+
});
|
10351
10456
|
// Don't include any synthesized type variables.
|
10352
10457
|
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
10353
10458
|
}
|
@@ -10881,10 +10986,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10881
10986
|
// If the base class is partially evaluated, install a callback
|
10882
10987
|
// so we can fix up this class (e.g. compute the MRO) when the
|
10883
10988
|
// dependent class is completed.
|
10884
|
-
|
10885
|
-
dependency: argType,
|
10886
|
-
callback: () => completeClassTypeDeferred(classType, node, node.name),
|
10887
|
-
});
|
10989
|
+
registerDeferredClassCompletion(node, argType);
|
10888
10990
|
}
|
10889
10991
|
if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
|
10890
10992
|
if (!fileInfo.isStubFile &&
|
@@ -11200,8 +11302,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11200
11302
|
(0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
|
11201
11303
|
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
|
11202
11304
|
}
|
11203
|
-
// Run any class
|
11204
|
-
|
11305
|
+
// Run any deferred class completions that depend on this class.
|
11306
|
+
runDeferredClassCompletions(classType);
|
11307
|
+
// If there are any outstanding deferred class completions registered that
|
11308
|
+
// were not removed by the call to runDeferredClassCompletions, assume that
|
11309
|
+
// the current class may depend on them and register for deferred completion.
|
11310
|
+
registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
|
11205
11311
|
// Synthesize TypedDict methods.
|
11206
11312
|
if (types_1.ClassType.isTypedDictClass(classType)) {
|
11207
11313
|
(0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
|
@@ -11434,21 +11540,47 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11434
11540
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarsNotInGenericOrProtocol() + diag.getString(), errorNode);
|
11435
11541
|
}
|
11436
11542
|
}
|
11437
|
-
//
|
11438
|
-
//
|
11439
|
-
//
|
11440
|
-
|
11441
|
-
|
11442
|
-
|
11443
|
-
|
11543
|
+
// Records the fact that the specified class requires "deferred completion" because
|
11544
|
+
// one of its base classes has not yet been fully evaluated. If the caller passes
|
11545
|
+
// undefined for "dependsUpon", then the class is added to all outstanding deferred
|
11546
|
+
// completions.
|
11547
|
+
function registerDeferredClassCompletion(classToComplete, dependsUpon) {
|
11548
|
+
if (dependsUpon) {
|
11549
|
+
// See if there is an existing entry for this dependency.
|
11550
|
+
const entry = deferredClassCompletions.find((e) => types_1.ClassType.isSameGenericClass(e.dependsUpon, dependsUpon));
|
11551
|
+
if (entry) {
|
11552
|
+
entry.classesToComplete.push(classToComplete);
|
11553
|
+
}
|
11554
|
+
else {
|
11555
|
+
deferredClassCompletions.push({ dependsUpon, classesToComplete: [classToComplete] });
|
11556
|
+
}
|
11557
|
+
}
|
11558
|
+
else {
|
11559
|
+
deferredClassCompletions.forEach((e) => {
|
11560
|
+
e.classesToComplete.push(classToComplete);
|
11561
|
+
});
|
11562
|
+
}
|
11563
|
+
}
|
11564
|
+
// Runs any registered "deferred class completions" that depend on the specified
|
11565
|
+
// class type. This allows us to complete any work that requires dependent classes
|
11566
|
+
// to be completed.
|
11567
|
+
function runDeferredClassCompletions(type) {
|
11568
|
+
deferredClassCompletions.forEach((e) => {
|
11569
|
+
if (types_1.ClassType.isSameGenericClass(e.dependsUpon, type)) {
|
11570
|
+
e.classesToComplete.forEach((classNode) => {
|
11571
|
+
const classType = readTypeCache(classNode.name, 0 /* None */);
|
11572
|
+
if (classType) {
|
11573
|
+
completeClassTypeDeferred(classType, classNode.name);
|
11574
|
+
}
|
11575
|
+
});
|
11444
11576
|
}
|
11445
11577
|
});
|
11446
|
-
// Remove any
|
11447
|
-
|
11578
|
+
// Remove any completions that depend on this type.
|
11579
|
+
deferredClassCompletions = deferredClassCompletions.filter((e) => !types_1.ClassType.isSameGenericClass(e.dependsUpon, type));
|
11448
11580
|
}
|
11449
11581
|
// Recomputes the MRO and effective metaclass for the class after dependent
|
11450
11582
|
// classes have been fully constructed.
|
11451
|
-
function completeClassTypeDeferred(type,
|
11583
|
+
function completeClassTypeDeferred(type, errorNode) {
|
11452
11584
|
// Recompute the MRO linearization.
|
11453
11585
|
if (!(0, typeUtils_1.computeMroLinearization)(type)) {
|
11454
11586
|
addError(localize_1.Localizer.Diagnostic.methodOrdering(), errorNode);
|
@@ -13273,10 +13405,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13273
13405
|
// Handle "type" specially, since it needs to act like "Type"
|
13274
13406
|
// in Python 3.9 and newer.
|
13275
13407
|
if (types_1.ClassType.isBuiltIn(classType, 'type') && typeArgs) {
|
13276
|
-
|
13277
|
-
|
13278
|
-
|
13279
|
-
|
13408
|
+
if (typeArgs.length >= 1) {
|
13409
|
+
// PEP 484 says that type[Any] should be considered
|
13410
|
+
// equivalent to type.
|
13411
|
+
if ((0, types_1.isAnyOrUnknown)(typeArgs[0].type)) {
|
13412
|
+
return { type: classType };
|
13413
|
+
}
|
13414
|
+
// Treat type[function] as illegal.
|
13415
|
+
if ((0, types_1.isFunction)(typeArgs[0].type) || (0, types_1.isOverloadedFunction)(typeArgs[0].type)) {
|
13416
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationWithCallable(), typeArgs[0].node);
|
13417
|
+
return { type: types_1.UnknownType.create() };
|
13418
|
+
}
|
13280
13419
|
}
|
13281
13420
|
const typeClass = getTypingType(errorNode, 'Type');
|
13282
13421
|
if (typeClass && (0, types_1.isInstantiableClass)(typeClass)) {
|
@@ -13528,13 +13667,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13528
13667
|
// used in cases where the argument is expected to be a type
|
13529
13668
|
// and therefore follows the normal rules of types (e.g. they
|
13530
13669
|
// can be forward-declared in stubs, etc.).
|
13531
|
-
function getTypeOfArgumentExpectingType(arg) {
|
13670
|
+
function getTypeOfArgumentExpectingType(arg, options) {
|
13532
13671
|
if (arg.typeResult) {
|
13533
13672
|
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
13534
13673
|
}
|
13535
13674
|
// If there was no defined type provided, there should always
|
13536
13675
|
// be a value expression from which we can retrieve the type.
|
13537
|
-
return getTypeOfExpressionExpectingType(arg.valueExpression);
|
13676
|
+
return getTypeOfExpressionExpectingType(arg.valueExpression, options);
|
13538
13677
|
}
|
13539
13678
|
function getTypeOfExpressionExpectingType(node, options) {
|
13540
13679
|
let flags = 128 /* ExpectingInstantiableType */ |
|
@@ -13565,6 +13704,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13565
13704
|
if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
|
13566
13705
|
flags |= 32 /* DisallowParamSpec */;
|
13567
13706
|
}
|
13707
|
+
if (options === null || options === void 0 ? void 0 : options.enforceTypeAnnotationRules) {
|
13708
|
+
flags |= 256 /* ExpectingTypeAnnotation */;
|
13709
|
+
}
|
13568
13710
|
return getTypeOfExpression(node, flags);
|
13569
13711
|
}
|
13570
13712
|
function getBuiltInType(node, name) {
|
@@ -13695,11 +13837,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13695
13837
|
// types, under the assumption that we're performing speculative evaluations.
|
13696
13838
|
// If speculativeNode is undefined, speculative mode is not used. This is
|
13697
13839
|
// useful in cases where we conditionally want to use speculative mode.
|
13698
|
-
function useSpeculativeMode(speculativeNode, callback,
|
13840
|
+
function useSpeculativeMode(speculativeNode, callback, options) {
|
13699
13841
|
if (!speculativeNode) {
|
13700
13842
|
return callback();
|
13701
13843
|
}
|
13702
|
-
speculativeTypeTracker.enterSpeculativeContext(speculativeNode,
|
13844
|
+
speculativeTypeTracker.enterSpeculativeContext(speculativeNode, options);
|
13703
13845
|
try {
|
13704
13846
|
const result = callback();
|
13705
13847
|
speculativeTypeTracker.leaveSpeculativeContext();
|
@@ -15156,6 +15298,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15156
15298
|
}
|
15157
15299
|
}
|
15158
15300
|
});
|
15301
|
+
if (!isAssignable) {
|
15302
|
+
return false;
|
15303
|
+
}
|
15159
15304
|
// Now handle generic base classes.
|
15160
15305
|
destType.details.baseClasses.forEach((baseClass) => {
|
15161
15306
|
if ((0, types_1.isInstantiableClass)(baseClass) &&
|
@@ -15401,63 +15546,50 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15401
15546
|
srcTypeArgs = srcType.typeArguments;
|
15402
15547
|
}
|
15403
15548
|
let isCompatible = true;
|
15404
|
-
|
15405
|
-
|
15406
|
-
|
15407
|
-
|
15408
|
-
|
15409
|
-
|
15410
|
-
|
15411
|
-
|
15412
|
-
|
15413
|
-
|
15414
|
-
|
15415
|
-
|
15416
|
-
|
15417
|
-
|
15418
|
-
|
15419
|
-
|
15420
|
-
|
15421
|
-
|
15422
|
-
|
15423
|
-
|
15424
|
-
|
15425
|
-
|
15426
|
-
|
15427
|
-
|
15428
|
-
|
15429
|
-
|
15430
|
-
|
15431
|
-
|
15432
|
-
if (
|
15433
|
-
if (
|
15549
|
+
srcTypeArgs === null || srcTypeArgs === void 0 ? void 0 : srcTypeArgs.forEach((srcTypeArg, srcArgIndex) => {
|
15550
|
+
// In most cases, the number of type args should match the number
|
15551
|
+
// of type arguments, but there are a few special cases where this
|
15552
|
+
// isn't true (e.g. assigning a Tuple[X, Y, Z] to a tuple[W]).
|
15553
|
+
const destArgIndex = srcArgIndex >= destTypeArgs.length ? destTypeArgs.length - 1 : srcArgIndex;
|
15554
|
+
const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
|
15555
|
+
const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
|
15556
|
+
const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
|
15557
|
+
const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
|
15558
|
+
let effectiveFlags;
|
15559
|
+
let errorSource;
|
15560
|
+
if (variance === 3 /* Covariant */) {
|
15561
|
+
effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
|
15562
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
|
15563
|
+
}
|
15564
|
+
else if (variance === 4 /* Contravariant */) {
|
15565
|
+
effectiveFlags =
|
15566
|
+
(flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */;
|
15567
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant;
|
15568
|
+
}
|
15569
|
+
else {
|
15570
|
+
effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
|
15571
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
|
15572
|
+
}
|
15573
|
+
if (!assignType(variance === 4 /* Contravariant */ ? srcTypeArg : destTypeArg, variance === 4 /* Contravariant */ ? destTypeArg : srcTypeArg, assignmentDiag, variance === 4 /* Contravariant */ ? srcTypeVarContext : destTypeVarContext, variance === 4 /* Contravariant */ ? destTypeVarContext : srcTypeVarContext, effectiveFlags, recursionCount)) {
|
15574
|
+
// Don't report errors with type variables in "pseudo-random"
|
15575
|
+
// classes since these type variables are not real.
|
15576
|
+
if (!types_1.ClassType.isPseudoGenericClass(destType)) {
|
15577
|
+
if (diag) {
|
15578
|
+
if (destTypeParam) {
|
15434
15579
|
const childDiag = diag.createAddendum();
|
15435
|
-
childDiag.addMessage(
|
15580
|
+
childDiag.addMessage(errorSource().format({
|
15436
15581
|
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15582
|
+
...printSrcDestTypes(srcTypeArg, destTypeArg),
|
15437
15583
|
}));
|
15438
|
-
childDiag.addAddendum(assignmentDiag);
|
15439
15584
|
}
|
15440
|
-
|
15441
|
-
|
15442
|
-
}
|
15443
|
-
else {
|
15444
|
-
if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
15445
|
-
// Don't report errors with type variables in "pseudo-random"
|
15446
|
-
// classes since these type variables are not real.
|
15447
|
-
if (!types_1.ClassType.isPseudoGenericClass(destType)) {
|
15448
|
-
if (diag) {
|
15449
|
-
const childDiag = diag.createAddendum();
|
15450
|
-
childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant().format({
|
15451
|
-
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15452
|
-
}));
|
15453
|
-
childDiag.addAddendum(assignmentDiag);
|
15454
|
-
}
|
15455
|
-
isCompatible = false;
|
15585
|
+
else {
|
15586
|
+
diag.addAddendum(assignmentDiag);
|
15456
15587
|
}
|
15457
15588
|
}
|
15589
|
+
isCompatible = false;
|
15458
15590
|
}
|
15459
15591
|
}
|
15460
|
-
}
|
15592
|
+
});
|
15461
15593
|
return isCompatible;
|
15462
15594
|
}
|
15463
15595
|
// Determines if the source type can be assigned to the dest type.
|
@@ -15647,8 +15779,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15647
15779
|
destType.details.parameters.length <= 2) {
|
15648
15780
|
return true;
|
15649
15781
|
}
|
15650
|
-
|
15651
|
-
|
15782
|
+
if (!(0, types_1.isUnion)(destType)) {
|
15783
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
15784
|
+
return false;
|
15785
|
+
}
|
15652
15786
|
}
|
15653
15787
|
}
|
15654
15788
|
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
@@ -15678,25 +15812,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15678
15812
|
return true;
|
15679
15813
|
}
|
15680
15814
|
if ((0, types_1.isUnion)(destType)) {
|
15815
|
+
// If both the source and dest are unions, use assignFromUnionType which has
|
15816
|
+
// special-case logic to handle this case.
|
15681
15817
|
if ((0, types_1.isUnion)(srcType)) {
|
15682
|
-
|
15683
|
-
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount)
|
15684
|
-
return true;
|
15685
|
-
}
|
15818
|
+
return assignFromUnionType(destType, srcType,
|
15819
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount);
|
15686
15820
|
}
|
15687
|
-
|
15688
|
-
|
15689
|
-
|
15690
|
-
|
15691
|
-
|
15692
|
-
|
15693
|
-
|
15694
|
-
|
15695
|
-
|
15696
|
-
srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
|
15697
|
-
}
|
15698
|
-
return true;
|
15821
|
+
const clonedDestTypeVarContext = destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone();
|
15822
|
+
const clonedSrcTypeVarContext = srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone();
|
15823
|
+
if (assignToUnionType(destType, srcType,
|
15824
|
+
/* diag */ undefined, clonedDestTypeVarContext, clonedSrcTypeVarContext, originalFlags, recursionCount)) {
|
15825
|
+
if (destTypeVarContext && clonedDestTypeVarContext) {
|
15826
|
+
destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
|
15827
|
+
}
|
15828
|
+
if (srcTypeVarContext && clonedSrcTypeVarContext) {
|
15829
|
+
srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
|
15699
15830
|
}
|
15831
|
+
return true;
|
15700
15832
|
}
|
15701
15833
|
}
|
15702
15834
|
const expandedSrcType = makeTopLevelTypeVarsConcrete(srcType);
|
@@ -16047,6 +16179,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16047
16179
|
// whose primary type matches.
|
16048
16180
|
remainingSrcSubtypes.forEach((srcSubtype) => {
|
16049
16181
|
const destTypeIndex = remainingDestSubtypes.findIndex((destSubtype) => {
|
16182
|
+
if ((0, types_1.isTypeSame)(destSubtype, srcSubtype)) {
|
16183
|
+
return true;
|
16184
|
+
}
|
16050
16185
|
if ((0, types_1.isClass)(srcSubtype) &&
|
16051
16186
|
(0, types_1.isClass)(destSubtype) &&
|
16052
16187
|
types_1.TypeBase.isInstance(srcSubtype) === types_1.TypeBase.isInstance(destSubtype) &&
|
@@ -16071,6 +16206,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16071
16206
|
// If there is are remaining dest subtypes and they're all type variables,
|
16072
16207
|
// attempt to assign the remaining source subtypes to them.
|
16073
16208
|
if (canUseFastPath && (remainingDestSubtypes.length !== 0 || remainingSrcSubtypes.length !== 0)) {
|
16209
|
+
if ((flags & 1 /* EnforceInvariance */) !== 0) {
|
16210
|
+
// If we have no src subtypes remaining but not all dest types have been subsumed
|
16211
|
+
// by other dest types, then the types are not compatible if we're enforcing invariance.
|
16212
|
+
if (remainingSrcSubtypes.length === 0) {
|
16213
|
+
return remainingDestSubtypes.every((destSubtype) => isTypeSubsumedByOtherType(destSubtype, destType.subtypes,
|
16214
|
+
/* allowAnyToSubsume */ true, recursionCount));
|
16215
|
+
}
|
16216
|
+
}
|
16074
16217
|
const isReversed = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
|
16075
16218
|
const effectiveDestSubtypes = isReversed ? remainingSrcSubtypes : remainingDestSubtypes;
|
16076
16219
|
if (effectiveDestSubtypes.length === 0 || effectiveDestSubtypes.some((t) => !(0, types_1.isTypeVar)(t))) {
|
@@ -16122,21 +16265,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16122
16265
|
}
|
16123
16266
|
if (!assignType(destType, subtype,
|
16124
16267
|
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
16125
|
-
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
16126
16268
|
// Determine if the current subtype is subsumed by another subtype
|
16127
16269
|
// in the same union. If so, we can ignore this.
|
16128
|
-
|
16129
|
-
|
16130
|
-
if (!isSubtypeSubsumed &&
|
16131
|
-
!(0, types_1.isTypeSame)(innerSubtype, subtype) &&
|
16132
|
-
!(0, types_1.isAnyOrUnknown)(innerSubtype) &&
|
16133
|
-
isProperSubtype(innerSubtype, concreteSubtype, recursionCount)) {
|
16134
|
-
isSubtypeSubsumed = true;
|
16135
|
-
}
|
16136
|
-
});
|
16270
|
+
const isSubtypeSubsumed = isTypeSubsumedByOtherType(subtype, srcType.subtypes,
|
16271
|
+
/* allowAnyToSubsume */ false, recursionCount);
|
16137
16272
|
// Try again with a concrete version of the subtype.
|
16138
16273
|
if (!isSubtypeSubsumed &&
|
16139
|
-
!assignType(destType,
|
16274
|
+
!assignType(destType, subtype, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
16140
16275
|
isIncompatible = true;
|
16141
16276
|
}
|
16142
16277
|
}
|
@@ -16147,6 +16282,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16147
16282
|
}
|
16148
16283
|
return true;
|
16149
16284
|
}
|
16285
|
+
// Determines whether a type is "subsumed by" (i.e. is a proper subtype of) one
|
16286
|
+
// of the other types in a list.
|
16287
|
+
function isTypeSubsumedByOtherType(type, otherTypes, allowAnyToSubsume, recursionCount = 0) {
|
16288
|
+
const concreteType = makeTopLevelTypeVarsConcrete(type);
|
16289
|
+
for (const otherType of otherTypes) {
|
16290
|
+
if ((0, types_1.isTypeSame)(otherType, type)) {
|
16291
|
+
continue;
|
16292
|
+
}
|
16293
|
+
if ((0, types_1.isAnyOrUnknown)(otherType)) {
|
16294
|
+
if (allowAnyToSubsume) {
|
16295
|
+
return true;
|
16296
|
+
}
|
16297
|
+
}
|
16298
|
+
else if (isProperSubtype(otherType, concreteType, recursionCount)) {
|
16299
|
+
return true;
|
16300
|
+
}
|
16301
|
+
}
|
16302
|
+
return false;
|
16303
|
+
}
|
16150
16304
|
// Determines whether the srcType is a subtype of destType but the converse
|
16151
16305
|
// is not true. It's important that we check both directions to avoid
|
16152
16306
|
// matches for types like `tuple[Any]` and `tuple[int]` from being considered
|