@zzzen/pyright-internal 1.2.0-dev.20230716 → 1.2.0-dev.20230730
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/backgroundAnalysisProgram.d.ts +2 -2
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/binder.js +0 -1
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +15 -45
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +17 -10
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +36 -12
- 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 +36 -14
- 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/patternMatching.js +24 -0
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +4 -2
- package/dist/analyzer/program.js +31 -25
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +5 -0
- package/dist/analyzer/sourceFile.js +11 -5
- package/dist/analyzer/sourceFile.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 +858 -639
- 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 +43 -8
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +4 -2
- package/dist/analyzer/typeUtils.js +65 -13
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -4
- package/dist/analyzer/types.js +20 -5
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +4 -4
- package/dist/backgroundAnalysisBase.js +6 -6
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.js +1 -1
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +5 -1
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/diagnosticRules.d.ts +1 -0
- package/dist/common/diagnosticRules.js +1 -0
- package/dist/common/diagnosticRules.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +7 -10
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.js +10 -4
- 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 -4
- package/dist/localization/localize.js +17 -2
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +6 -6
- package/dist/localization/package.nls.de.json +6 -6
- package/dist/localization/package.nls.en-us.json +6 -6
- package/dist/localization/package.nls.es.json +6 -6
- package/dist/localization/package.nls.fr.json +6 -6
- package/dist/localization/package.nls.it.json +6 -6
- package/dist/localization/package.nls.ja.json +6 -6
- package/dist/localization/package.nls.ko.json +6 -6
- package/dist/localization/package.nls.pl.json +6 -6
- package/dist/localization/package.nls.pt-br.json +6 -6
- package/dist/localization/package.nls.qps-ploc.json +6 -6
- package/dist/localization/package.nls.ru.json +6 -6
- package/dist/localization/package.nls.tr.json +6 -6
- package/dist/localization/package.nls.zh-cn.json +6 -6
- package/dist/localization/package.nls.zh-tw.json +6 -6
- 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 +24 -2
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +14 -4
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +9 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +8 -4
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/package.json +7 -6
@@ -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)) {
|
@@ -3767,7 +3818,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3767
3818
|
// a descriptor protocol, only 'get' operations are allowed. If it's accessed
|
3768
3819
|
// through the object, all access methods are supported.
|
3769
3820
|
if (isAccessedThroughObject || usage.method === 'get') {
|
3770
|
-
lookupClass =
|
3821
|
+
lookupClass = types_1.ClassType.cloneAsInstance(concreteSubtype.details.effectiveMetaclass);
|
3771
3822
|
isAccessedThroughMetaclass = true;
|
3772
3823
|
}
|
3773
3824
|
else {
|
@@ -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') {
|
@@ -4578,7 +4641,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4578
4641
|
const isFinalAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'Final');
|
4579
4642
|
const isClassVarAnnotation = (0, types_1.isInstantiableClass)(concreteSubtype) && types_1.ClassType.isBuiltIn(concreteSubtype, 'ClassVar');
|
4580
4643
|
// Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
|
4581
|
-
|
4644
|
+
// This feature is currently experimental.
|
4645
|
+
const supportsTypedDictTypeArg = AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
|
4646
|
+
(0, types_1.isInstantiableClass)(concreteSubtype) &&
|
4582
4647
|
types_1.ClassType.isBuiltIn(concreteSubtype, 'dict') &&
|
4583
4648
|
!concreteSubtype.aliasName;
|
4584
4649
|
let typeArgs = getTypeArgs(node, flags, {
|
@@ -5263,6 +5328,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5263
5328
|
function getTypeOfCall(node, flags, inferenceContext) {
|
5264
5329
|
var _a;
|
5265
5330
|
let baseTypeResult;
|
5331
|
+
// Check for the use of `type(x)` within a type annotation. This isn't
|
5332
|
+
// allowed, and it's a common mistake, so we want to emit a diagnostic
|
5333
|
+
// that guides the user to the right solution.
|
5266
5334
|
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
|
5267
5335
|
node.leftExpression.nodeType === 38 /* Name */ &&
|
5268
5336
|
node.leftExpression.value === 'type') {
|
@@ -5324,20 +5392,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5324
5392
|
}
|
5325
5393
|
}
|
5326
5394
|
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
5395
|
const callResult = validateCallArguments(node, argList, baseTypeResult,
|
5342
5396
|
/* typeVarContext */ undefined,
|
5343
5397
|
/* skipUnknownArgCheck */ false, inferenceContext);
|
@@ -5776,7 +5830,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5776
5830
|
// If there were multiple possible matches, evaluate the type as
|
5777
5831
|
// Unknown, but include the "possible types" to allow for completion
|
5778
5832
|
// suggestions.
|
5779
|
-
if (!isDefinitiveMatchFound) {
|
5833
|
+
if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
|
5780
5834
|
possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
|
5781
5835
|
// Did the filtering produce a single result? If so, we're done.
|
5782
5836
|
if (possibleMatchResults.length === 1) {
|
@@ -5984,24 +6038,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5984
6038
|
}
|
5985
6039
|
return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
|
5986
6040
|
}
|
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
|
-
|
6041
|
+
// Create a helper function that evaluates the overload that best
|
6042
|
+
// matches the arg/param lists.
|
6043
|
+
function evaluateUsingBestMatchingOverload(skipUnknownArgCheck) {
|
6044
|
+
// Find the match with the smallest argument match score. If there
|
6045
|
+
// are more than one with the same score, use the one with the
|
6046
|
+
// largest index. Later overloads tend to be more general.
|
6047
|
+
const bestMatch = filteredMatchResults.reduce((previous, current) => {
|
6048
|
+
if (current.argumentMatchScore === previous.argumentMatchScore) {
|
6049
|
+
return current.overloadIndex > previous.overloadIndex ? current : previous;
|
6050
|
+
}
|
6051
|
+
return current.argumentMatchScore < previous.argumentMatchScore ? current : previous;
|
5994
6052
|
});
|
5995
6053
|
const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
|
5996
|
-
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(
|
6054
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(bestMatch.overload));
|
5997
6055
|
effectiveTypeVarContext.unlock();
|
5998
|
-
return validateFunctionArgumentTypesWithContext(errorNode,
|
6056
|
+
return validateFunctionArgumentTypesWithContext(errorNode, bestMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5999
6057
|
}
|
6000
6058
|
// If there is only one possible arg/param match among the overloads,
|
6001
6059
|
// use the normal type matching mechanism because it is faster and
|
6002
6060
|
// will provide a clearer error message.
|
6003
6061
|
if (filteredMatchResults.length === 1) {
|
6004
|
-
return
|
6062
|
+
return evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ false);
|
6005
6063
|
}
|
6006
6064
|
let expandedArgTypes = [argList.map((arg) => undefined)];
|
6007
6065
|
let isTypeIncomplete = !!typeResult.isIncomplete;
|
@@ -6044,7 +6102,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6044
6102
|
// in speculative mode because it's very expensive, and we're going to
|
6045
6103
|
// suppress the diagnostic anyway.
|
6046
6104
|
if (!isDiagnosticSuppressedForNode(errorNode) && !isTypeIncomplete) {
|
6047
|
-
const result =
|
6105
|
+
const result = evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ true);
|
6048
6106
|
// Replace the result with an unknown type since we don't know
|
6049
6107
|
// what overload should have been used.
|
6050
6108
|
result.returnType = types_1.UnknownType.create();
|
@@ -6120,334 +6178,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6120
6178
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
6121
6179
|
}
|
6122
6180
|
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
|
-
}
|
6181
|
+
/* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
|
6182
|
+
return useSpeculativeMode(isLastIteration ? undefined : errorNode, () => {
|
6183
|
+
const callResult = validateCallArgumentsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6184
|
+
if (callResult.argumentErrors) {
|
6185
|
+
argumentErrors = true;
|
6415
6186
|
}
|
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;
|
6187
|
+
if (callResult.isTypeIncomplete) {
|
6188
|
+
isTypeIncomplete = true;
|
6431
6189
|
}
|
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);
|
6190
|
+
if (callResult.overloadsUsedForCall) {
|
6439
6191
|
(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
6192
|
}
|
6449
|
-
|
6450
|
-
|
6193
|
+
specializedInitSelfType = callResult.specializedInitSelfType;
|
6194
|
+
return callResult.returnType;
|
6195
|
+
}, {
|
6196
|
+
allowDiagnostics: true,
|
6197
|
+
});
|
6451
6198
|
});
|
6452
6199
|
// If we ended up with a "Never" type because all code paths returned
|
6453
6200
|
// undefined due to argument errors, transform the result into an Unknown
|
@@ -6463,10 +6210,350 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6463
6210
|
overloadsUsedForCall,
|
6464
6211
|
};
|
6465
6212
|
}
|
6213
|
+
function validateCallArgumentsForSubtype(errorNode, argList, expandedCallType, unexpandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6214
|
+
switch (expandedCallType.category) {
|
6215
|
+
case 4 /* Never */:
|
6216
|
+
case 1 /* Unknown */:
|
6217
|
+
case 2 /* Any */: {
|
6218
|
+
// Touch all of the args so they're marked accessed. Don't bother
|
6219
|
+
// doing this if the call type is incomplete because this will need
|
6220
|
+
// to be done again once it is complete.
|
6221
|
+
if (!isCallTypeIncomplete) {
|
6222
|
+
argList.forEach((arg) => {
|
6223
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6224
|
+
getTypeOfArgument(arg);
|
6225
|
+
}
|
6226
|
+
});
|
6227
|
+
}
|
6228
|
+
return { returnType: expandedCallType };
|
6229
|
+
}
|
6230
|
+
case 5 /* Function */: {
|
6231
|
+
return validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6232
|
+
}
|
6233
|
+
case 6 /* OverloadedFunction */: {
|
6234
|
+
return validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6235
|
+
}
|
6236
|
+
case 7 /* Class */: {
|
6237
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6238
|
+
return validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext);
|
6239
|
+
}
|
6240
|
+
return validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6241
|
+
}
|
6242
|
+
case 3 /* None */: {
|
6243
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6244
|
+
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
6245
|
+
const callResult = validateCallForInstantiableClass(errorNode, argList, noneType, noneType, skipUnknownArgCheck, inferenceContext);
|
6246
|
+
return { ...callResult, returnType: types_1.NoneType.createInstance() };
|
6247
|
+
}
|
6248
|
+
return { returnType: types_1.NoneType.createInstance() };
|
6249
|
+
}
|
6250
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
|
6251
|
+
return { argumentErrors: true };
|
6252
|
+
}
|
6253
|
+
// TypeVars should have been expanded in most cases,
|
6254
|
+
// but we still need to handle the case of Type[T] where
|
6255
|
+
// T is a constrained type that contains a union. We also
|
6256
|
+
// need to handle recursive type aliases.
|
6257
|
+
case 10 /* TypeVar */: {
|
6258
|
+
return validateCallArguments(errorNode, argList, { type: (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedCallType), isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6259
|
+
}
|
6260
|
+
case 8 /* Module */: {
|
6261
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
|
6262
|
+
return { argumentErrors: true };
|
6263
|
+
}
|
6264
|
+
}
|
6265
|
+
return { argumentErrors: true };
|
6266
|
+
}
|
6267
|
+
function validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
6268
|
+
var _a;
|
6269
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6270
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
|
6271
|
+
type: printType(expandedCallType),
|
6272
|
+
}), errorNode);
|
6273
|
+
return { returnType: undefined, argumentErrors: true };
|
6274
|
+
}
|
6275
|
+
// Check for an attempt to invoke an abstract static or class method.
|
6276
|
+
if (expandedCallType.boundToType &&
|
6277
|
+
(0, types_1.isInstantiableClass)(expandedCallType.boundToType) &&
|
6278
|
+
!expandedCallType.boundToType.includeSubclasses) {
|
6279
|
+
if (types_1.FunctionType.isAbstractMethod(expandedCallType)) {
|
6280
|
+
if (types_1.FunctionType.isStaticMethod(expandedCallType) || types_1.FunctionType.isClassMethod(expandedCallType)) {
|
6281
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
|
6282
|
+
method: expandedCallType.details.name,
|
6283
|
+
}), errorNode.nodeType === 9 /* Call */ ? errorNode.leftExpression : errorNode);
|
6284
|
+
}
|
6285
|
+
}
|
6286
|
+
}
|
6287
|
+
// The stdlib collections/__init__.pyi stub file defines namedtuple
|
6288
|
+
// as a function rather than a class, so we need to check for it here.
|
6289
|
+
if (expandedCallType.details.builtInName === 'namedtuple') {
|
6290
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
|
6291
|
+
return {
|
6292
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ false),
|
6293
|
+
};
|
6294
|
+
}
|
6295
|
+
// Handle the NewType specially, replacing the normal return type.
|
6296
|
+
if (expandedCallType.details.builtInName === 'NewType') {
|
6297
|
+
return { returnType: createNewType(errorNode, argList) };
|
6298
|
+
}
|
6299
|
+
let effectiveTypeVarContext = typeVarContext;
|
6300
|
+
if (!effectiveTypeVarContext) {
|
6301
|
+
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6302
|
+
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
|
6303
|
+
}
|
6304
|
+
const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6305
|
+
let isTypeIncomplete = !!functionResult.isTypeIncomplete;
|
6306
|
+
let returnType = functionResult.returnType;
|
6307
|
+
let argumentErrors = !!functionResult.argumentErrors;
|
6308
|
+
if (!argumentErrors) {
|
6309
|
+
// Call the function transform logic to handle special-cased functions.
|
6310
|
+
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
6311
|
+
argumentErrors: !!functionResult.argumentErrors,
|
6312
|
+
returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
|
6313
|
+
isTypeIncomplete,
|
6314
|
+
});
|
6315
|
+
returnType = transformed.returnType;
|
6316
|
+
if (transformed.isTypeIncomplete) {
|
6317
|
+
isTypeIncomplete = true;
|
6318
|
+
}
|
6319
|
+
if (transformed.argumentErrors) {
|
6320
|
+
argumentErrors = true;
|
6321
|
+
}
|
6322
|
+
}
|
6323
|
+
if (expandedCallType.details.builtInName === '__import__') {
|
6324
|
+
// For the special __import__ type, we'll override the return type to be "Any".
|
6325
|
+
// This is required because we don't know what module was imported, and we don't
|
6326
|
+
// want to fail type checks when accessing members of the resulting module type.
|
6327
|
+
returnType = types_1.AnyType.create();
|
6328
|
+
}
|
6329
|
+
return {
|
6330
|
+
returnType,
|
6331
|
+
isTypeIncomplete,
|
6332
|
+
argumentErrors,
|
6333
|
+
overloadsUsedForCall: functionResult.overloadsUsedForCall,
|
6334
|
+
specializedInitSelfType: functionResult.specializedInitSelfType,
|
6335
|
+
};
|
6336
|
+
}
|
6337
|
+
function validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
6338
|
+
var _a, _b;
|
6339
|
+
// Handle the 'cast' call as a special case.
|
6340
|
+
if (expandedCallType.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
|
6341
|
+
return { returnType: evaluateCastCall(argList, errorNode) };
|
6342
|
+
}
|
6343
|
+
const callResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6344
|
+
let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
|
6345
|
+
let isTypeIncomplete = !!callResult.isTypeIncomplete;
|
6346
|
+
let argumentErrors = !!callResult.argumentErrors;
|
6347
|
+
if (!argumentErrors) {
|
6348
|
+
// Call the function transform logic to handle special-cased functions.
|
6349
|
+
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
6350
|
+
argumentErrors: !!callResult.argumentErrors,
|
6351
|
+
returnType: (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
|
6352
|
+
isTypeIncomplete,
|
6353
|
+
});
|
6354
|
+
returnType = transformed.returnType;
|
6355
|
+
if (transformed.isTypeIncomplete) {
|
6356
|
+
isTypeIncomplete = true;
|
6357
|
+
}
|
6358
|
+
if (transformed.argumentErrors) {
|
6359
|
+
argumentErrors = true;
|
6360
|
+
}
|
6361
|
+
}
|
6362
|
+
return {
|
6363
|
+
returnType,
|
6364
|
+
isTypeIncomplete,
|
6365
|
+
argumentErrors,
|
6366
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
6367
|
+
specializedInitSelfType: callResult.specializedInitSelfType,
|
6368
|
+
};
|
6369
|
+
}
|
6370
|
+
function validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext) {
|
6371
|
+
var _a;
|
6372
|
+
if (expandedCallType.literalValue !== undefined) {
|
6373
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
|
6374
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6375
|
+
}
|
6376
|
+
if (types_1.ClassType.isBuiltIn(expandedCallType)) {
|
6377
|
+
const className = expandedCallType.aliasName || expandedCallType.details.name;
|
6378
|
+
if (className === 'type') {
|
6379
|
+
// Validate the constructor arguments.
|
6380
|
+
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
|
6381
|
+
// Handle the 'type' call specially.
|
6382
|
+
if (argList.length === 1) {
|
6383
|
+
// The one-parameter form of "type" returns the class
|
6384
|
+
// for the specified object.
|
6385
|
+
const argType = getTypeOfArgument(argList[0]).type;
|
6386
|
+
const returnType = (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
|
6387
|
+
if ((0, types_1.isClassInstance)(subtype) ||
|
6388
|
+
((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
|
6389
|
+
(0, types_1.isNoneInstance)(subtype)) {
|
6390
|
+
return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
|
6391
|
+
}
|
6392
|
+
else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
|
6393
|
+
return types_1.FunctionType.cloneAsInstantiable(subtype);
|
6394
|
+
}
|
6395
|
+
return types_1.AnyType.create();
|
6396
|
+
});
|
6397
|
+
return { returnType };
|
6398
|
+
}
|
6399
|
+
if (argList.length >= 2) {
|
6400
|
+
// The two-parameter form of "type" returns a new class type
|
6401
|
+
// built from the specified base types.
|
6402
|
+
return { returnType: createType(errorNode, argList) || types_1.AnyType.create() };
|
6403
|
+
}
|
6404
|
+
// If the parameter to type() is not statically known,
|
6405
|
+
// fall back to Any.
|
6406
|
+
return { returnType: types_1.AnyType.create() };
|
6407
|
+
}
|
6408
|
+
if (className === 'TypeVar') {
|
6409
|
+
return {
|
6410
|
+
returnType: createTypeVarType(errorNode, expandedCallType, argList),
|
6411
|
+
};
|
6412
|
+
}
|
6413
|
+
if (className === 'TypeVarTuple') {
|
6414
|
+
return {
|
6415
|
+
returnType: createTypeVarTupleType(errorNode, expandedCallType, argList),
|
6416
|
+
};
|
6417
|
+
}
|
6418
|
+
if (className === 'ParamSpec') {
|
6419
|
+
return {
|
6420
|
+
returnType: createParamSpecType(errorNode, expandedCallType, argList),
|
6421
|
+
};
|
6422
|
+
}
|
6423
|
+
if (className === 'TypeAliasType') {
|
6424
|
+
const newTypeAlias = createTypeAliasType(errorNode, argList);
|
6425
|
+
if (newTypeAlias) {
|
6426
|
+
return { returnType: newTypeAlias };
|
6427
|
+
}
|
6428
|
+
}
|
6429
|
+
if (className === 'NamedTuple') {
|
6430
|
+
return {
|
6431
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
|
6432
|
+
};
|
6433
|
+
}
|
6434
|
+
if (className === 'NewType') {
|
6435
|
+
return { returnType: createNewType(errorNode, argList) };
|
6436
|
+
}
|
6437
|
+
if (className === 'Protocol' ||
|
6438
|
+
className === 'Generic' ||
|
6439
|
+
className === 'Callable' ||
|
6440
|
+
className === 'Concatenate' ||
|
6441
|
+
className === 'Type') {
|
6442
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
6443
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
|
6444
|
+
return { returnType: types_1.AnyType.create() };
|
6445
|
+
}
|
6446
|
+
if ((0, types_1.isClass)(unexpandedCallType) && (0, enums_1.isKnownEnumType)(className)) {
|
6447
|
+
return {
|
6448
|
+
returnType: (_a = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedCallType, argList)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(),
|
6449
|
+
};
|
6450
|
+
}
|
6451
|
+
if (className === 'TypedDict') {
|
6452
|
+
return { returnType: (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedCallType, argList) };
|
6453
|
+
}
|
6454
|
+
if (className === 'auto' && argList.length === 0) {
|
6455
|
+
return { returnType: (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode) };
|
6456
|
+
}
|
6457
|
+
}
|
6458
|
+
if (types_1.ClassType.supportsAbstractMethods(expandedCallType)) {
|
6459
|
+
const abstractMethods = getAbstractMethods(expandedCallType);
|
6460
|
+
if (abstractMethods.length > 0 && !expandedCallType.includeSubclasses && !(0, types_1.isTypeVar)(unexpandedCallType)) {
|
6461
|
+
// If the class is abstract, it can't be instantiated.
|
6462
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
6463
|
+
const errorsToDisplay = 2;
|
6464
|
+
abstractMethods.forEach((abstractMethod, index) => {
|
6465
|
+
if (index === errorsToDisplay) {
|
6466
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
|
6467
|
+
count: abstractMethods.length - errorsToDisplay,
|
6468
|
+
}));
|
6469
|
+
}
|
6470
|
+
else if (index < errorsToDisplay) {
|
6471
|
+
if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
|
6472
|
+
const className = abstractMethod.classType.details.name;
|
6473
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
|
6474
|
+
type: className,
|
6475
|
+
name: abstractMethod.symbolName,
|
6476
|
+
}));
|
6477
|
+
}
|
6478
|
+
}
|
6479
|
+
});
|
6480
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
|
6481
|
+
type: expandedCallType.details.name,
|
6482
|
+
}) + diagAddendum.getString(), errorNode);
|
6483
|
+
}
|
6484
|
+
}
|
6485
|
+
if (types_1.ClassType.isProtocolClass(expandedCallType) && !expandedCallType.includeSubclasses) {
|
6486
|
+
// If the class is a protocol, it can't be instantiated.
|
6487
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
|
6488
|
+
type: expandedCallType.details.name,
|
6489
|
+
}), errorNode);
|
6490
|
+
}
|
6491
|
+
// Assume this is a call to the constructor.
|
6492
|
+
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
|
6493
|
+
const overloadsUsedForCall = constructorResult.overloadsUsedForCall;
|
6494
|
+
const argumentErrors = constructorResult.argumentErrors;
|
6495
|
+
const isTypeIncomplete = constructorResult.isTypeIncomplete;
|
6496
|
+
let returnType = constructorResult.returnType;
|
6497
|
+
// If the expandedCallType originated from a TypeVar, convert
|
6498
|
+
// the constructed type back to the TypeVar. For example, if
|
6499
|
+
// we have `cls: Type[_T]` followed by `_T()`.
|
6500
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType)) {
|
6501
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
6502
|
+
}
|
6503
|
+
// If we instantiated a type, transform it into a class.
|
6504
|
+
// This can happen if someone directly instantiates a metaclass
|
6505
|
+
// deriving from type.
|
6506
|
+
if (returnType &&
|
6507
|
+
(0, types_1.isClassInstance)(returnType) &&
|
6508
|
+
returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
|
6509
|
+
let newClassName = '__class_' + returnType.details.name;
|
6510
|
+
if (argList.length === 3) {
|
6511
|
+
const firstArgType = getTypeOfArgument(argList[0]).type;
|
6512
|
+
if ((0, types_1.isClassInstance)(firstArgType) &&
|
6513
|
+
types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
|
6514
|
+
typeof firstArgType.literalValue === 'string') {
|
6515
|
+
newClassName = firstArgType.literalValue;
|
6516
|
+
}
|
6517
|
+
}
|
6518
|
+
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));
|
6519
|
+
newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
|
6520
|
+
newClassType.details.effectiveMetaclass = expandedCallType;
|
6521
|
+
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
6522
|
+
returnType = newClassType;
|
6523
|
+
}
|
6524
|
+
return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
|
6525
|
+
}
|
6526
|
+
function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6527
|
+
var _a, _b;
|
6528
|
+
const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
|
6529
|
+
/* usage */ undefined,
|
6530
|
+
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
6531
|
+
if (!memberType) {
|
6532
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6533
|
+
type: printType(expandedCallType),
|
6534
|
+
}), errorNode);
|
6535
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6536
|
+
}
|
6537
|
+
const callResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6538
|
+
let returnType = (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
|
6539
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType) &&
|
6540
|
+
types_1.TypeBase.isInstantiable(unexpandedCallType) &&
|
6541
|
+
(0, types_1.isClass)(expandedCallType) &&
|
6542
|
+
types_1.ClassType.isBuiltIn(expandedCallType, 'type')) {
|
6543
|
+
// Handle the case where a Type[T] is being called. We presume this
|
6544
|
+
// will instantiate an object of type T.
|
6545
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
6546
|
+
}
|
6547
|
+
return {
|
6548
|
+
returnType,
|
6549
|
+
argumentErrors: callResult.argumentErrors,
|
6550
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
6551
|
+
};
|
6552
|
+
}
|
6466
6553
|
// Evaluates the type of the "cast" call.
|
6467
6554
|
function evaluateCastCall(argList, errorNode) {
|
6468
6555
|
// Verify that the cast is necessary.
|
6469
|
-
const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
|
6556
|
+
const castToType = getTypeOfArgumentExpectingType(argList[0], { enforceTypeAnnotationRules: true }).type;
|
6470
6557
|
const castFromType = getTypeOfArgument(argList[1]).type;
|
6471
6558
|
if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
|
6472
6559
|
if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
|
@@ -7328,6 +7415,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7328
7415
|
paramSpecArgList,
|
7329
7416
|
activeParam,
|
7330
7417
|
relevance,
|
7418
|
+
argumentMatchScore: 0,
|
7331
7419
|
};
|
7332
7420
|
}
|
7333
7421
|
// After having matched arguments with parameters, this function evaluates the
|
@@ -7403,7 +7491,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7403
7491
|
const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
|
7404
7492
|
/* typeArguments */ undefined,
|
7405
7493
|
/* isTypeArgumentExplicit */ false);
|
7406
|
-
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext
|
7494
|
+
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext, {
|
7495
|
+
unknownIfNotFound: true,
|
7496
|
+
});
|
7407
7497
|
}
|
7408
7498
|
}
|
7409
7499
|
else if ((0, types_1.isFunction)(effectiveReturnType)) {
|
@@ -7426,6 +7516,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7426
7516
|
const type = matchResults.overload;
|
7427
7517
|
let isTypeIncomplete = matchResults.isTypeIncomplete;
|
7428
7518
|
let argumentErrors = false;
|
7519
|
+
let argumentMatchScore = 0;
|
7429
7520
|
let specializedInitSelfType;
|
7430
7521
|
let anyOrUnknownArgument;
|
7431
7522
|
const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
|
@@ -7527,7 +7618,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7527
7618
|
let sawParamSpecKwargs = false;
|
7528
7619
|
let condition = [];
|
7529
7620
|
const argResults = [];
|
7530
|
-
matchResults.argParams.forEach((argParam) => {
|
7621
|
+
matchResults.argParams.forEach((argParam, argParamIndex) => {
|
7531
7622
|
var _a;
|
7532
7623
|
const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
|
7533
7624
|
skipUnknownArgCheck,
|
@@ -7536,6 +7627,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7536
7627
|
argResults.push(argResult);
|
7537
7628
|
if (!argResult.isCompatible) {
|
7538
7629
|
argumentErrors = true;
|
7630
|
+
// Add the inverse index so earlier parameters represent larger errors.
|
7631
|
+
// This will help the heuristics in the overload error paths to pick the
|
7632
|
+
// most likely intended overload if none of them match.
|
7633
|
+
argumentMatchScore += 1 + (matchResults.argParams.length - argParamIndex);
|
7539
7634
|
}
|
7540
7635
|
if (argResult.isTypeIncomplete) {
|
7541
7636
|
isTypeIncomplete = true;
|
@@ -7561,11 +7656,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7561
7656
|
}
|
7562
7657
|
}
|
7563
7658
|
});
|
7659
|
+
let paramSpecTypeVarContext = [];
|
7564
7660
|
// Handle the assignment of additional arguments that map to a param spec.
|
7565
7661
|
if (matchResults.paramSpecArgList && matchResults.paramSpecTarget) {
|
7566
|
-
|
7662
|
+
const paramSpecArgResult = validateFunctionArgumentsForParamSpec(errorNode, matchResults.paramSpecArgList, matchResults.paramSpecTarget, typeVarContext, typeCondition);
|
7663
|
+
if (paramSpecArgResult.argumentErrors) {
|
7567
7664
|
argumentErrors = true;
|
7665
|
+
argumentMatchScore += 1;
|
7568
7666
|
}
|
7667
|
+
paramSpecTypeVarContext = paramSpecArgResult.typeVarContexts;
|
7569
7668
|
}
|
7570
7669
|
else if (type.details.paramSpec) {
|
7571
7670
|
if (!sawParamSpecArgs || !sawParamSpecKwargs) {
|
@@ -7573,6 +7672,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7573
7672
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecArgsMissing().format({ type: printType(type.details.paramSpec) }), errorNode);
|
7574
7673
|
}
|
7575
7674
|
argumentErrors = true;
|
7675
|
+
argumentMatchScore += 1;
|
7576
7676
|
}
|
7577
7677
|
}
|
7578
7678
|
// Calculate the return type.
|
@@ -7618,17 +7718,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7618
7718
|
applyInScopePlaceholders: true,
|
7619
7719
|
});
|
7620
7720
|
specializedReturnType = (0, typeUtils_1.addConditionToType)(specializedReturnType, typeCondition);
|
7721
|
+
// If the function includes a ParamSpec and the captured signature(s) includes
|
7722
|
+
// generic types, we may need to apply those solved TypeVars.
|
7723
|
+
if (paramSpecTypeVarContext.length > 0) {
|
7724
|
+
paramSpecTypeVarContext.forEach((paramSpecTypeVarContext) => {
|
7725
|
+
if (paramSpecTypeVarContext) {
|
7726
|
+
specializedReturnType = (0, typeUtils_1.applySolvedTypeVars)(specializedReturnType, paramSpecTypeVarContext);
|
7727
|
+
}
|
7728
|
+
});
|
7729
|
+
}
|
7621
7730
|
// If the final return type is an unpacked tuple, turn it into a normal (unpacked) tuple.
|
7622
7731
|
if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
|
7623
7732
|
specializedReturnType = types_1.ClassType.cloneForUnpacked(specializedReturnType, /* isUnpackedTuple */ false);
|
7624
7733
|
}
|
7625
|
-
// Handle 'TypeGuard'
|
7626
|
-
//
|
7627
|
-
// narrowed type.
|
7734
|
+
// Handle 'TypeGuard' specially. We'll transform the return type into a 'bool'
|
7735
|
+
// object with a type argument that reflects the narrowed type.
|
7628
7736
|
if ((0, types_1.isClassInstance)(specializedReturnType) &&
|
7629
|
-
types_1.ClassType.isBuiltIn(specializedReturnType,
|
7737
|
+
types_1.ClassType.isBuiltIn(specializedReturnType, 'TypeGuard') &&
|
7630
7738
|
specializedReturnType.typeArguments &&
|
7631
|
-
specializedReturnType.typeArguments.length > 0
|
7739
|
+
specializedReturnType.typeArguments.length > 0 &&
|
7740
|
+
(0, types_1.isClassInstance)(returnType) &&
|
7741
|
+
returnType.typeArguments &&
|
7742
|
+
returnType.typeArguments.length > 0) {
|
7632
7743
|
if (boolClassType && (0, types_1.isInstantiableClass)(boolClassType)) {
|
7633
7744
|
let typeGuardType = specializedReturnType.typeArguments[0];
|
7634
7745
|
// If the first argument is a simple (non-constrained) TypeVar,
|
@@ -7647,13 +7758,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7647
7758
|
]);
|
7648
7759
|
}
|
7649
7760
|
}
|
7650
|
-
|
7761
|
+
let useStrictTypeGuardSemantics = false;
|
7762
|
+
if (AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.enableExperimentalFeatures) {
|
7763
|
+
// Determine the type of the first parameter.
|
7764
|
+
const paramIndex = type.boundToType ? 1 : 0;
|
7765
|
+
if (paramIndex < type.details.parameters.length) {
|
7766
|
+
const paramType = types_1.FunctionType.getEffectiveParameterType(type, paramIndex);
|
7767
|
+
// If the type guard meets the requirements that the first parameter
|
7768
|
+
// type is a proper subtype of the return type, we can use strict
|
7769
|
+
// type guard semantics.
|
7770
|
+
if (assignType(paramType, returnType.typeArguments[0])) {
|
7771
|
+
useStrictTypeGuardSemantics = true;
|
7772
|
+
}
|
7773
|
+
}
|
7774
|
+
}
|
7775
|
+
specializedReturnType = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForTypeGuard(boolClassType, typeGuardType, useStrictTypeGuardSemantics));
|
7651
7776
|
}
|
7652
7777
|
}
|
7653
7778
|
specializedReturnType = adjustCallableReturnType(specializedReturnType);
|
7654
7779
|
if (specializedInitSelfType) {
|
7655
7780
|
specializedInitSelfType = (0, typeUtils_1.applySolvedTypeVars)(specializedInitSelfType, typeVarContext);
|
7656
7781
|
}
|
7782
|
+
matchResults.argumentMatchScore = argumentMatchScore;
|
7657
7783
|
return {
|
7658
7784
|
argumentErrors,
|
7659
7785
|
argResults,
|
@@ -7698,7 +7824,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7698
7824
|
// specific use case. We may need to make this more sophisticated in
|
7699
7825
|
// the future.
|
7700
7826
|
if ((0, types_1.isFunction)(returnType) && !returnType.details.name) {
|
7701
|
-
|
7827
|
+
const typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgumentsRecursive)(returnType);
|
7828
|
+
// If there are no unsolved type variables, we're done. If there are
|
7829
|
+
// unsolved type parameters, treat them as though they are rescoped
|
7830
|
+
// to the callable.
|
7831
|
+
if (typeVarsInReturnType.length > 0) {
|
7832
|
+
return types_1.FunctionType.cloneWithNewTypeVarScopeId(returnType, types_1.WildcardTypeVarScopeId, typeVarsInReturnType);
|
7833
|
+
}
|
7702
7834
|
}
|
7703
7835
|
return returnType;
|
7704
7836
|
}
|
@@ -7735,12 +7867,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7735
7867
|
return validateFunctionArgumentsForParamSpecSignature(errorNode, argList, paramSpec, signatureContexts[0], conditionFilter);
|
7736
7868
|
}
|
7737
7869
|
const filteredSignatureContexts = [];
|
7870
|
+
const typeVarContexts = [];
|
7738
7871
|
signatureContexts.forEach((context) => {
|
7739
7872
|
// Use speculative mode to avoid emitting errors or caching types.
|
7740
7873
|
useSpeculativeMode(errorNode, () => {
|
7741
|
-
|
7874
|
+
const paramSpecArgResult = validateFunctionArgumentsForParamSpecSignature(errorNode, argList, paramSpec, context, conditionFilter);
|
7875
|
+
if (!paramSpecArgResult.argumentErrors) {
|
7742
7876
|
filteredSignatureContexts.push(context);
|
7743
7877
|
}
|
7878
|
+
(0, collectionUtils_1.appendArray)(typeVarContexts, paramSpecArgResult.typeVarContexts);
|
7744
7879
|
});
|
7745
7880
|
});
|
7746
7881
|
// Copy back any compatible signature contexts if any were compatible.
|
@@ -7748,109 +7883,121 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7748
7883
|
destTypeVarContext.copySignatureContexts(filteredSignatureContexts);
|
7749
7884
|
}
|
7750
7885
|
// Evaluate non-speculatively to produce a final result and cache types.
|
7751
|
-
|
7886
|
+
const paramSpecArgResult = validateFunctionArgumentsForParamSpecSignature(errorNode, argList, paramSpec, filteredSignatureContexts.length > 0 ? filteredSignatureContexts[0] : signatureContexts[0], conditionFilter);
|
7887
|
+
return { argumentErrors: paramSpecArgResult.argumentErrors, typeVarContexts };
|
7752
7888
|
}
|
7753
7889
|
function validateFunctionArgumentsForParamSpecSignature(errorNode, argList, paramSpec, typeVarContext, conditionFilter) {
|
7754
7890
|
var _a;
|
7755
7891
|
const paramSpecType = typeVarContext.getParamSpecType(paramSpec);
|
7756
7892
|
if (!paramSpecType) {
|
7757
7893
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotBound().format({ type: printType(paramSpec) }), ((_a = argList[0]) === null || _a === void 0 ? void 0 : _a.valueExpression) || errorNode);
|
7758
|
-
return
|
7894
|
+
return { argumentErrors: true, typeVarContexts: [undefined] };
|
7759
7895
|
}
|
7760
7896
|
const liveTypeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
|
7761
7897
|
const srcTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(paramSpecType));
|
7762
7898
|
let reportedArgError = false;
|
7763
|
-
// Build a map of all named parameters.
|
7764
|
-
const paramMap = new Map();
|
7765
|
-
const paramSpecParams = paramSpecType.details.parameters;
|
7766
|
-
paramSpecParams.forEach((param) => {
|
7767
|
-
if (param.name) {
|
7768
|
-
paramMap.set(param.name, param);
|
7769
|
-
}
|
7770
|
-
});
|
7771
|
-
let positionalIndex = 0;
|
7772
|
-
let positionalIndexLimit = paramSpecParams.findIndex((paramInfo) => paramInfo.category !== 0 /* Simple */);
|
7773
|
-
if (positionalIndexLimit < 0) {
|
7774
|
-
positionalIndexLimit = paramSpecParams.length;
|
7775
|
-
}
|
7776
|
-
const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
|
7777
|
-
const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
|
7778
|
-
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
7779
7899
|
let sawUnpackedListArgument = false;
|
7780
7900
|
let sawUnpackedDictArgument = false;
|
7781
|
-
|
7782
|
-
|
7783
|
-
|
7784
|
-
|
7785
|
-
|
7786
|
-
|
7787
|
-
|
7788
|
-
|
7789
|
-
|
7790
|
-
|
7791
|
-
|
7792
|
-
|
7793
|
-
|
7794
|
-
|
7795
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), arg.name || errorNode);
|
7796
|
-
reportedArgError = true;
|
7901
|
+
let paramMap = new Map();
|
7902
|
+
// We'll use two passes in case there are type variables that depend
|
7903
|
+
// on later arguments.
|
7904
|
+
const passCount = 2;
|
7905
|
+
for (let i = 0; i < passCount; i++) {
|
7906
|
+
// Unless we're on the last pass, use speculative mode to suppress
|
7907
|
+
// any diagnostics.
|
7908
|
+
useSpeculativeMode(i < passCount - 1 ? errorNode : undefined, () => {
|
7909
|
+
// Build a map of all named parameters.
|
7910
|
+
paramMap = new Map();
|
7911
|
+
const paramSpecParams = paramSpecType.details.parameters;
|
7912
|
+
paramSpecParams.forEach((param) => {
|
7913
|
+
if (param.name) {
|
7914
|
+
paramMap.set(param.name, param);
|
7797
7915
|
}
|
7798
|
-
}
|
7799
|
-
|
7800
|
-
|
7801
|
-
|
7802
|
-
|
7803
|
-
|
7804
|
-
|
7916
|
+
});
|
7917
|
+
let positionalIndex = 0;
|
7918
|
+
let positionalIndexLimit = paramSpecParams.findIndex((paramInfo) => paramInfo.category !== 0 /* Simple */);
|
7919
|
+
if (positionalIndexLimit < 0) {
|
7920
|
+
positionalIndexLimit = paramSpecParams.length;
|
7921
|
+
}
|
7922
|
+
const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
|
7923
|
+
const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
|
7924
|
+
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
7925
|
+
argList.forEach((arg) => {
|
7926
|
+
var _a;
|
7927
|
+
if (arg.argumentCategory === 0 /* Simple */) {
|
7928
|
+
let paramType;
|
7929
|
+
if (arg.name) {
|
7930
|
+
const paramInfo = paramMap.get(arg.name.value);
|
7931
|
+
if (paramInfo) {
|
7932
|
+
paramType = paramInfo.type;
|
7933
|
+
paramMap.delete(arg.name.value);
|
7934
|
+
}
|
7935
|
+
else if (kwargsParam) {
|
7936
|
+
paramType = kwargsParam.type;
|
7937
|
+
}
|
7938
|
+
else {
|
7939
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), arg.name || errorNode);
|
7940
|
+
reportedArgError = true;
|
7941
|
+
}
|
7942
|
+
}
|
7943
|
+
else {
|
7944
|
+
if (positionalIndex < positionalIndexLimit) {
|
7945
|
+
const paramInfo = paramSpecParams[positionalIndex];
|
7946
|
+
paramType = paramInfo.type;
|
7947
|
+
if (paramInfo.name) {
|
7948
|
+
paramMap.delete(paramInfo.name);
|
7949
|
+
}
|
7950
|
+
}
|
7951
|
+
else if (argsParam) {
|
7952
|
+
paramType = argsParam.type;
|
7953
|
+
}
|
7954
|
+
else {
|
7955
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, paramSpecParams.length === 1
|
7956
|
+
? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
|
7957
|
+
: localize_1.Localizer.Diagnostic.argPositionalExpectedCount().format({
|
7958
|
+
expected: paramSpecParams.length,
|
7959
|
+
}), (_a = arg.valueExpression) !== null && _a !== void 0 ? _a : errorNode);
|
7960
|
+
reportedArgError = true;
|
7961
|
+
}
|
7962
|
+
positionalIndex++;
|
7963
|
+
}
|
7964
|
+
if (paramType) {
|
7965
|
+
const argResult = validateArgType({
|
7966
|
+
paramCategory: 0 /* Simple */,
|
7967
|
+
paramType: (0, typeUtils_1.transformExpectedType)(paramType, liveTypeVarScopes,
|
7968
|
+
/* usageOffset */ undefined),
|
7969
|
+
requiresTypeVarMatching: false,
|
7970
|
+
argument: arg,
|
7971
|
+
errorNode: arg.valueExpression || errorNode,
|
7972
|
+
}, srcTypeVarContext, signatureTracker,
|
7973
|
+
/* functionType */ undefined, { conditionFilter });
|
7974
|
+
if (!argResult.isCompatible) {
|
7975
|
+
reportedArgError = true;
|
7976
|
+
}
|
7805
7977
|
}
|
7806
7978
|
}
|
7807
|
-
else if (
|
7808
|
-
|
7979
|
+
else if (arg.argumentCategory === 1 /* UnpackedList */) {
|
7980
|
+
sawUnpackedListArgument = true;
|
7981
|
+
// See if there is an *args parameter.
|
7982
|
+
const argsParam = paramSpecParams.find((param) => param.category === 1 /* ArgsList */ && param.name);
|
7983
|
+
if (argsParam && paramMap.has(argsParam.name)) {
|
7984
|
+
// TODO - validate args type
|
7985
|
+
paramMap.delete(argsParam.name);
|
7986
|
+
}
|
7809
7987
|
}
|
7810
7988
|
else {
|
7811
|
-
|
7812
|
-
|
7813
|
-
|
7814
|
-
|
7815
|
-
|
7816
|
-
|
7817
|
-
|
7818
|
-
|
7819
|
-
}
|
7820
|
-
if (paramType) {
|
7821
|
-
const argResult = validateArgType({
|
7822
|
-
paramCategory: 0 /* Simple */,
|
7823
|
-
paramType: (0, typeUtils_1.transformExpectedType)(paramType, liveTypeVarScopes, /* usageOffset */ undefined),
|
7824
|
-
requiresTypeVarMatching: false,
|
7825
|
-
argument: arg,
|
7826
|
-
errorNode: arg.valueExpression || errorNode,
|
7827
|
-
}, srcTypeVarContext, signatureTracker,
|
7828
|
-
/* functionType */ undefined, { conditionFilter });
|
7829
|
-
if (!argResult.isCompatible) {
|
7830
|
-
reportedArgError = true;
|
7989
|
+
sawUnpackedDictArgument = true;
|
7990
|
+
(0, debug_1.assert)(arg.argumentCategory === 2 /* UnpackedDictionary */);
|
7991
|
+
// See if there is an *kwargs parameter.
|
7992
|
+
const kwargsParam = paramSpecParams.find((param) => param.category === 2 /* KwargsDict */);
|
7993
|
+
if (kwargsParam && paramMap.has(kwargsParam.name)) {
|
7994
|
+
// TODO - validate kwargs type
|
7995
|
+
paramMap.delete(kwargsParam.name);
|
7996
|
+
}
|
7831
7997
|
}
|
7832
|
-
}
|
7833
|
-
}
|
7834
|
-
|
7835
|
-
sawUnpackedListArgument = true;
|
7836
|
-
// See if there is an *args parameter.
|
7837
|
-
const argsParam = paramSpecParams.find((param) => param.category === 1 /* ArgsList */ && param.name);
|
7838
|
-
if (argsParam && paramMap.has(argsParam.name)) {
|
7839
|
-
// TODO - validate args type
|
7840
|
-
paramMap.delete(argsParam.name);
|
7841
|
-
}
|
7842
|
-
}
|
7843
|
-
else {
|
7844
|
-
sawUnpackedDictArgument = true;
|
7845
|
-
(0, debug_1.assert)(arg.argumentCategory === 2 /* UnpackedDictionary */);
|
7846
|
-
// See if there is an *kwargs parameter.
|
7847
|
-
const kwargsParam = paramSpecParams.find((param) => param.category === 2 /* KwargsDict */);
|
7848
|
-
if (kwargsParam && paramMap.has(kwargsParam.name)) {
|
7849
|
-
// TODO - validate kwargs type
|
7850
|
-
paramMap.delete(kwargsParam.name);
|
7851
|
-
}
|
7852
|
-
}
|
7853
|
-
});
|
7998
|
+
});
|
7999
|
+
});
|
8000
|
+
}
|
7854
8001
|
// Report any missing parameters.
|
7855
8002
|
if (!reportedArgError) {
|
7856
8003
|
let unassignedParams = Array.from(paramMap.keys());
|
@@ -7873,7 +8020,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7873
8020
|
if (!reportedArgError) {
|
7874
8021
|
(0, typeUtils_1.applySourceContextTypeVarsToSignature)(typeVarContext, srcTypeVarContext);
|
7875
8022
|
}
|
7876
|
-
return
|
8023
|
+
return {
|
8024
|
+
argumentErrors: reportedArgError,
|
8025
|
+
typeVarContexts: [reportedArgError ? srcTypeVarContext : undefined],
|
8026
|
+
};
|
7877
8027
|
}
|
7878
8028
|
function validateArgType(argParam, typeVarContext, signatureTracker, typeResult, options) {
|
7879
8029
|
var _a;
|
@@ -8816,9 +8966,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8816
8966
|
// Dict and MutableMapping types have invariant value types, so they
|
8817
8967
|
// cannot be narrowed further. Other super-types like Mapping, Collection,
|
8818
8968
|
// and Iterable use covariant value types, so they can be narrowed.
|
8819
|
-
|
8820
|
-
|
8821
|
-
|
8969
|
+
let isValueTypeInvariant = false;
|
8970
|
+
if ((0, types_1.isClassInstance)(inferenceContext.expectedType)) {
|
8971
|
+
if (inferenceContext.expectedType.details.typeParameters.length >= 2) {
|
8972
|
+
const valueTypeParam = inferenceContext.expectedType.details.typeParameters[1];
|
8973
|
+
if (types_1.TypeVarType.getVariance(valueTypeParam) === 2 /* Invariant */) {
|
8974
|
+
isValueTypeInvariant = true;
|
8975
|
+
}
|
8976
|
+
}
|
8977
|
+
}
|
8822
8978
|
// Infer the key and value types if possible.
|
8823
8979
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8824
8980
|
/* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
@@ -9416,7 +9572,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9416
9572
|
if (returnTypeResult.isIncomplete) {
|
9417
9573
|
isIncomplete = true;
|
9418
9574
|
}
|
9419
|
-
},
|
9575
|
+
}, {
|
9576
|
+
dependentType: inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType,
|
9577
|
+
});
|
9420
9578
|
// Mark the function type as no longer being evaluated.
|
9421
9579
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
9422
9580
|
return { type: functionType, isIncomplete };
|
@@ -9642,13 +9800,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9642
9800
|
}
|
9643
9801
|
return true;
|
9644
9802
|
}
|
9645
|
-
//
|
9646
|
-
//
|
9647
|
-
//
|
9648
|
-
// present, should specify the return type.
|
9803
|
+
// Evaluates the type arguments for a Callable type. It should have zero
|
9804
|
+
// to two arguments.The first argument, if present, should be an ellipsis,
|
9805
|
+
// a ParamSpec, a Concatenate, or a list of positional parameter types.
|
9806
|
+
// The second argument, if present, should specify the return type.
|
9649
9807
|
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
9808
|
const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
|
9653
9809
|
types_1.TypeBase.setSpecialForm(functionType);
|
9654
9810
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
@@ -10342,12 +10498,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10342
10498
|
// Determine if there are any generic type parameters associated
|
10343
10499
|
// with this type alias.
|
10344
10500
|
typeParameters = [];
|
10345
|
-
|
10346
|
-
|
10347
|
-
|
10348
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10349
|
-
});
|
10350
|
-
}
|
10501
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
10502
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10503
|
+
});
|
10351
10504
|
// Don't include any synthesized type variables.
|
10352
10505
|
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
10353
10506
|
}
|
@@ -10458,7 +10611,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10458
10611
|
['TypeAlias', { alias: '', module: 'builtins' }],
|
10459
10612
|
['Concatenate', { alias: '', module: 'builtins' }],
|
10460
10613
|
['TypeGuard', { alias: '', module: 'builtins' }],
|
10461
|
-
['StrictTypeGuard', { alias: '', module: 'builtins' }],
|
10462
10614
|
['Unpack', { alias: '', module: 'builtins' }],
|
10463
10615
|
['Required', { alias: '', module: 'builtins' }],
|
10464
10616
|
['NotRequired', { alias: '', module: 'builtins' }],
|
@@ -10468,7 +10620,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10468
10620
|
['LiteralString', { alias: '', module: 'builtins' }],
|
10469
10621
|
['ReadOnly', { alias: '', module: 'builtins' }],
|
10470
10622
|
]);
|
10471
|
-
|
10623
|
+
let aliasMapEntry = specialTypes.get(assignedName);
|
10624
|
+
// Support ReadOnly only as an experimental feature.
|
10625
|
+
if (assignedName === 'ReadOnly' &&
|
10626
|
+
!AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures) {
|
10627
|
+
aliasMapEntry = undefined;
|
10628
|
+
}
|
10472
10629
|
if (aliasMapEntry) {
|
10473
10630
|
const cachedType = readTypeCache(node, 0 /* None */);
|
10474
10631
|
if (cachedType) {
|
@@ -10881,10 +11038,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10881
11038
|
// If the base class is partially evaluated, install a callback
|
10882
11039
|
// so we can fix up this class (e.g. compute the MRO) when the
|
10883
11040
|
// dependent class is completed.
|
10884
|
-
|
10885
|
-
dependency: argType,
|
10886
|
-
callback: () => completeClassTypeDeferred(classType, node, node.name),
|
10887
|
-
});
|
11041
|
+
registerDeferredClassCompletion(node, argType);
|
10888
11042
|
}
|
10889
11043
|
if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
|
10890
11044
|
if (!fileInfo.isStubFile &&
|
@@ -11200,8 +11354,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11200
11354
|
(0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
|
11201
11355
|
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
|
11202
11356
|
}
|
11203
|
-
// Run any class
|
11204
|
-
|
11357
|
+
// Run any deferred class completions that depend on this class.
|
11358
|
+
runDeferredClassCompletions(classType);
|
11359
|
+
// If there are any outstanding deferred class completions registered that
|
11360
|
+
// were not removed by the call to runDeferredClassCompletions, assume that
|
11361
|
+
// the current class may depend on them and register for deferred completion.
|
11362
|
+
registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
|
11205
11363
|
// Synthesize TypedDict methods.
|
11206
11364
|
if (types_1.ClassType.isTypedDictClass(classType)) {
|
11207
11365
|
(0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
|
@@ -11434,21 +11592,47 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11434
11592
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarsNotInGenericOrProtocol() + diag.getString(), errorNode);
|
11435
11593
|
}
|
11436
11594
|
}
|
11437
|
-
//
|
11438
|
-
//
|
11439
|
-
//
|
11440
|
-
|
11441
|
-
|
11442
|
-
|
11443
|
-
|
11595
|
+
// Records the fact that the specified class requires "deferred completion" because
|
11596
|
+
// one of its base classes has not yet been fully evaluated. If the caller passes
|
11597
|
+
// undefined for "dependsUpon", then the class is added to all outstanding deferred
|
11598
|
+
// completions.
|
11599
|
+
function registerDeferredClassCompletion(classToComplete, dependsUpon) {
|
11600
|
+
if (dependsUpon) {
|
11601
|
+
// See if there is an existing entry for this dependency.
|
11602
|
+
const entry = deferredClassCompletions.find((e) => types_1.ClassType.isSameGenericClass(e.dependsUpon, dependsUpon));
|
11603
|
+
if (entry) {
|
11604
|
+
entry.classesToComplete.push(classToComplete);
|
11605
|
+
}
|
11606
|
+
else {
|
11607
|
+
deferredClassCompletions.push({ dependsUpon, classesToComplete: [classToComplete] });
|
11608
|
+
}
|
11609
|
+
}
|
11610
|
+
else {
|
11611
|
+
deferredClassCompletions.forEach((e) => {
|
11612
|
+
e.classesToComplete.push(classToComplete);
|
11613
|
+
});
|
11614
|
+
}
|
11615
|
+
}
|
11616
|
+
// Runs any registered "deferred class completions" that depend on the specified
|
11617
|
+
// class type. This allows us to complete any work that requires dependent classes
|
11618
|
+
// to be completed.
|
11619
|
+
function runDeferredClassCompletions(type) {
|
11620
|
+
deferredClassCompletions.forEach((e) => {
|
11621
|
+
if (types_1.ClassType.isSameGenericClass(e.dependsUpon, type)) {
|
11622
|
+
e.classesToComplete.forEach((classNode) => {
|
11623
|
+
const classType = readTypeCache(classNode.name, 0 /* None */);
|
11624
|
+
if (classType) {
|
11625
|
+
completeClassTypeDeferred(classType, classNode.name);
|
11626
|
+
}
|
11627
|
+
});
|
11444
11628
|
}
|
11445
11629
|
});
|
11446
|
-
// Remove any
|
11447
|
-
|
11630
|
+
// Remove any completions that depend on this type.
|
11631
|
+
deferredClassCompletions = deferredClassCompletions.filter((e) => !types_1.ClassType.isSameGenericClass(e.dependsUpon, type));
|
11448
11632
|
}
|
11449
11633
|
// Recomputes the MRO and effective metaclass for the class after dependent
|
11450
11634
|
// classes have been fully constructed.
|
11451
|
-
function completeClassTypeDeferred(type,
|
11635
|
+
function completeClassTypeDeferred(type, errorNode) {
|
11452
11636
|
// Recompute the MRO linearization.
|
11453
11637
|
if (!(0, typeUtils_1.computeMroLinearization)(type)) {
|
11454
11638
|
addError(localize_1.Localizer.Diagnostic.methodOrdering(), errorNode);
|
@@ -12322,9 +12506,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12322
12506
|
}
|
12323
12507
|
return inferredReturnType ? { type: inferredReturnType, isIncomplete } : undefined;
|
12324
12508
|
}
|
12325
|
-
// Determines whether the
|
12326
|
-
// and the exception type raised is a NotImplementedError
|
12327
|
-
// used for abstract methods
|
12509
|
+
// Determines whether the method consists only of a "raise" statement
|
12510
|
+
// and the exception type raised is a NotImplementedError or a subclass
|
12511
|
+
// thereof. This is commonly used for abstract methods.
|
12328
12512
|
function methodAlwaysRaisesNotImplemented(functionDecl) {
|
12329
12513
|
if (!functionDecl ||
|
12330
12514
|
!functionDecl.isMethod ||
|
@@ -12343,7 +12527,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12343
12527
|
: (0, types_1.isClassInstance)(raiseType)
|
12344
12528
|
? raiseType
|
12345
12529
|
: undefined;
|
12346
|
-
if (!classType || !
|
12530
|
+
if (!classType || !(0, typeUtils_1.derivesFromStdlibClass)(classType, 'NotImplementedError')) {
|
12347
12531
|
return false;
|
12348
12532
|
}
|
12349
12533
|
}
|
@@ -13245,18 +13429,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13245
13429
|
case 'Concatenate': {
|
13246
13430
|
return { type: createConcatenateType(errorNode, classType, typeArgs) };
|
13247
13431
|
}
|
13248
|
-
case 'TypeGuard':
|
13249
|
-
case 'StrictTypeGuard': {
|
13432
|
+
case 'TypeGuard': {
|
13250
13433
|
return { type: createTypeGuardType(errorNode, classType, typeArgs, flags) };
|
13251
13434
|
}
|
13252
13435
|
case 'Unpack': {
|
13253
13436
|
return { type: createUnpackType(classType, errorNode, typeArgs, flags) };
|
13254
13437
|
}
|
13255
13438
|
case 'Required':
|
13256
|
-
case 'NotRequired':
|
13257
|
-
case 'ReadOnly': {
|
13439
|
+
case 'NotRequired': {
|
13258
13440
|
return createRequiredOrReadOnlyType(classType, errorNode, typeArgs, flags);
|
13259
13441
|
}
|
13442
|
+
case 'ReadOnly': {
|
13443
|
+
if (AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.enableExperimentalFeatures) {
|
13444
|
+
return createRequiredOrReadOnlyType(classType, errorNode, typeArgs, flags);
|
13445
|
+
}
|
13446
|
+
break;
|
13447
|
+
}
|
13260
13448
|
case 'Self': {
|
13261
13449
|
return { type: createSelfType(classType, errorNode, typeArgs) };
|
13262
13450
|
}
|
@@ -13273,10 +13461,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13273
13461
|
// Handle "type" specially, since it needs to act like "Type"
|
13274
13462
|
// in Python 3.9 and newer.
|
13275
13463
|
if (types_1.ClassType.isBuiltIn(classType, 'type') && typeArgs) {
|
13276
|
-
|
13277
|
-
|
13278
|
-
|
13279
|
-
|
13464
|
+
if (typeArgs.length >= 1) {
|
13465
|
+
// PEP 484 says that type[Any] should be considered
|
13466
|
+
// equivalent to type.
|
13467
|
+
if ((0, types_1.isAnyOrUnknown)(typeArgs[0].type)) {
|
13468
|
+
return { type: classType };
|
13469
|
+
}
|
13470
|
+
// Treat type[function] as illegal.
|
13471
|
+
if ((0, types_1.isFunction)(typeArgs[0].type) || (0, types_1.isOverloadedFunction)(typeArgs[0].type)) {
|
13472
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationWithCallable(), typeArgs[0].node);
|
13473
|
+
return { type: types_1.UnknownType.create() };
|
13474
|
+
}
|
13280
13475
|
}
|
13281
13476
|
const typeClass = getTypingType(errorNode, 'Type');
|
13282
13477
|
if (typeClass && (0, types_1.isInstantiableClass)(typeClass)) {
|
@@ -13528,13 +13723,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13528
13723
|
// used in cases where the argument is expected to be a type
|
13529
13724
|
// and therefore follows the normal rules of types (e.g. they
|
13530
13725
|
// can be forward-declared in stubs, etc.).
|
13531
|
-
function getTypeOfArgumentExpectingType(arg) {
|
13726
|
+
function getTypeOfArgumentExpectingType(arg, options) {
|
13532
13727
|
if (arg.typeResult) {
|
13533
13728
|
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
13534
13729
|
}
|
13535
13730
|
// If there was no defined type provided, there should always
|
13536
13731
|
// be a value expression from which we can retrieve the type.
|
13537
|
-
return getTypeOfExpressionExpectingType(arg.valueExpression);
|
13732
|
+
return getTypeOfExpressionExpectingType(arg.valueExpression, options);
|
13538
13733
|
}
|
13539
13734
|
function getTypeOfExpressionExpectingType(node, options) {
|
13540
13735
|
let flags = 128 /* ExpectingInstantiableType */ |
|
@@ -13565,6 +13760,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13565
13760
|
if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
|
13566
13761
|
flags |= 32 /* DisallowParamSpec */;
|
13567
13762
|
}
|
13763
|
+
if (options === null || options === void 0 ? void 0 : options.enforceTypeAnnotationRules) {
|
13764
|
+
flags |= 256 /* ExpectingTypeAnnotation */;
|
13765
|
+
}
|
13568
13766
|
return getTypeOfExpression(node, flags);
|
13569
13767
|
}
|
13570
13768
|
function getBuiltInType(node, name) {
|
@@ -13695,11 +13893,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13695
13893
|
// types, under the assumption that we're performing speculative evaluations.
|
13696
13894
|
// If speculativeNode is undefined, speculative mode is not used. This is
|
13697
13895
|
// useful in cases where we conditionally want to use speculative mode.
|
13698
|
-
function useSpeculativeMode(speculativeNode, callback,
|
13896
|
+
function useSpeculativeMode(speculativeNode, callback, options) {
|
13699
13897
|
if (!speculativeNode) {
|
13700
13898
|
return callback();
|
13701
13899
|
}
|
13702
|
-
speculativeTypeTracker.enterSpeculativeContext(speculativeNode,
|
13900
|
+
speculativeTypeTracker.enterSpeculativeContext(speculativeNode, options);
|
13703
13901
|
try {
|
13704
13902
|
const result = callback();
|
13705
13903
|
speculativeTypeTracker.leaveSpeculativeContext();
|
@@ -15118,8 +15316,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15118
15316
|
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
15119
15317
|
let isAssignable = true;
|
15120
15318
|
destType.details.fields.forEach((symbol, name) => {
|
15121
|
-
|
15122
|
-
if (!isAssignable || !symbol.isClassMember() || symbol.isIgnoredForProtocolMatch()) {
|
15319
|
+
if (!isAssignable || symbol.isIgnoredForProtocolMatch()) {
|
15123
15320
|
return;
|
15124
15321
|
}
|
15125
15322
|
// Constructor methods are exempt from variance calculations.
|
@@ -15128,34 +15325,42 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15128
15325
|
}
|
15129
15326
|
const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
|
15130
15327
|
(0, debug_1.assert)(memberInfo !== undefined);
|
15131
|
-
let destMemberType = (
|
15132
|
-
|
15133
|
-
|
15134
|
-
|
15135
|
-
|
15136
|
-
|
15137
|
-
|
15138
|
-
|
15139
|
-
|
15140
|
-
|
15141
|
-
|
15142
|
-
isAssignable = false;
|
15143
|
-
}
|
15328
|
+
let destMemberType = getEffectiveTypeOfSymbol(symbol);
|
15329
|
+
const srcMemberType = getTypeOfMember(memberInfo);
|
15330
|
+
destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType);
|
15331
|
+
// Properties require special processing.
|
15332
|
+
if ((0, types_1.isClassInstance)(destMemberType) &&
|
15333
|
+
types_1.ClassType.isPropertyClass(destMemberType) &&
|
15334
|
+
(0, types_1.isClassInstance)(srcMemberType) &&
|
15335
|
+
types_1.ClassType.isPropertyClass(srcMemberType)) {
|
15336
|
+
if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType, diag, typeVarContext,
|
15337
|
+
/* selfTypeVarContext */ undefined, recursionCount)) {
|
15338
|
+
isAssignable = false;
|
15144
15339
|
}
|
15145
|
-
|
15146
|
-
|
15340
|
+
}
|
15341
|
+
else {
|
15342
|
+
const primaryDecl = symbol.getDeclarations()[0];
|
15343
|
+
let flags = 0 /* Default */;
|
15344
|
+
if ((primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* Variable */ &&
|
15345
|
+
!isFinalVariableDeclaration(primaryDecl) &&
|
15346
|
+
!types_1.ClassType.isFrozenDataClass(destType)) {
|
15147
15347
|
// Class and instance variables that are mutable need to
|
15148
|
-
// enforce invariance.
|
15149
|
-
|
15150
|
-
|
15151
|
-
|
15152
|
-
|
15153
|
-
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
15154
|
-
isAssignable = false;
|
15348
|
+
// enforce invariance. We will exempt variables that are
|
15349
|
+
// private or protected, since these are presumably
|
15350
|
+
// not modifiable outside of the class.
|
15351
|
+
if (!(0, symbolNameUtils_1.isPrivateOrProtectedName)(name)) {
|
15352
|
+
flags |= 1 /* EnforceInvariance */;
|
15155
15353
|
}
|
15156
15354
|
}
|
15355
|
+
if (!assignType(destMemberType, srcMemberType, diag, typeVarContext,
|
15356
|
+
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
15357
|
+
isAssignable = false;
|
15358
|
+
}
|
15157
15359
|
}
|
15158
15360
|
});
|
15361
|
+
if (!isAssignable) {
|
15362
|
+
return false;
|
15363
|
+
}
|
15159
15364
|
// Now handle generic base classes.
|
15160
15365
|
destType.details.baseClasses.forEach((baseClass) => {
|
15161
15366
|
if ((0, types_1.isInstantiableClass)(baseClass) &&
|
@@ -15401,63 +15606,50 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15401
15606
|
srcTypeArgs = srcType.typeArguments;
|
15402
15607
|
}
|
15403
15608
|
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 (
|
15609
|
+
srcTypeArgs === null || srcTypeArgs === void 0 ? void 0 : srcTypeArgs.forEach((srcTypeArg, srcArgIndex) => {
|
15610
|
+
// In most cases, the number of type args should match the number
|
15611
|
+
// of type arguments, but there are a few special cases where this
|
15612
|
+
// isn't true (e.g. assigning a Tuple[X, Y, Z] to a tuple[W]).
|
15613
|
+
const destArgIndex = srcArgIndex >= destTypeArgs.length ? destTypeArgs.length - 1 : srcArgIndex;
|
15614
|
+
const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
|
15615
|
+
const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
|
15616
|
+
const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
|
15617
|
+
const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
|
15618
|
+
let effectiveFlags;
|
15619
|
+
let errorSource;
|
15620
|
+
if (variance === 3 /* Covariant */) {
|
15621
|
+
effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
|
15622
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
|
15623
|
+
}
|
15624
|
+
else if (variance === 4 /* Contravariant */) {
|
15625
|
+
effectiveFlags =
|
15626
|
+
(flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */;
|
15627
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant;
|
15628
|
+
}
|
15629
|
+
else {
|
15630
|
+
effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
|
15631
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
|
15632
|
+
}
|
15633
|
+
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)) {
|
15634
|
+
// Don't report errors with type variables in "pseudo-random"
|
15635
|
+
// classes since these type variables are not real.
|
15636
|
+
if (!types_1.ClassType.isPseudoGenericClass(destType)) {
|
15637
|
+
if (diag) {
|
15638
|
+
if (destTypeParam) {
|
15434
15639
|
const childDiag = diag.createAddendum();
|
15435
|
-
childDiag.addMessage(
|
15640
|
+
childDiag.addMessage(errorSource().format({
|
15436
15641
|
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15642
|
+
...printSrcDestTypes(srcTypeArg, destTypeArg),
|
15437
15643
|
}));
|
15438
|
-
childDiag.addAddendum(assignmentDiag);
|
15439
15644
|
}
|
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;
|
15645
|
+
else {
|
15646
|
+
diag.addAddendum(assignmentDiag);
|
15456
15647
|
}
|
15457
15648
|
}
|
15649
|
+
isCompatible = false;
|
15458
15650
|
}
|
15459
15651
|
}
|
15460
|
-
}
|
15652
|
+
});
|
15461
15653
|
return isCompatible;
|
15462
15654
|
}
|
15463
15655
|
// Determines if the source type can be assigned to the dest type.
|
@@ -15647,8 +15839,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15647
15839
|
destType.details.parameters.length <= 2) {
|
15648
15840
|
return true;
|
15649
15841
|
}
|
15650
|
-
|
15651
|
-
|
15842
|
+
if (!(0, types_1.isUnion)(destType)) {
|
15843
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
15844
|
+
return false;
|
15845
|
+
}
|
15652
15846
|
}
|
15653
15847
|
}
|
15654
15848
|
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
@@ -15678,25 +15872,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15678
15872
|
return true;
|
15679
15873
|
}
|
15680
15874
|
if ((0, types_1.isUnion)(destType)) {
|
15875
|
+
// If both the source and dest are unions, use assignFromUnionType which has
|
15876
|
+
// special-case logic to handle this case.
|
15681
15877
|
if ((0, types_1.isUnion)(srcType)) {
|
15682
|
-
|
15683
|
-
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount)
|
15684
|
-
return true;
|
15685
|
-
}
|
15878
|
+
return assignFromUnionType(destType, srcType,
|
15879
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount);
|
15686
15880
|
}
|
15687
|
-
|
15688
|
-
|
15689
|
-
|
15690
|
-
|
15691
|
-
|
15692
|
-
|
15693
|
-
destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
|
15694
|
-
}
|
15695
|
-
if (srcTypeVarContext && clonedSrcTypeVarContext) {
|
15696
|
-
srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
|
15697
|
-
}
|
15698
|
-
return true;
|
15881
|
+
const clonedDestTypeVarContext = destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone();
|
15882
|
+
const clonedSrcTypeVarContext = srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone();
|
15883
|
+
if (assignToUnionType(destType, srcType,
|
15884
|
+
/* diag */ undefined, clonedDestTypeVarContext, clonedSrcTypeVarContext, originalFlags, recursionCount)) {
|
15885
|
+
if (destTypeVarContext && clonedDestTypeVarContext) {
|
15886
|
+
destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
|
15699
15887
|
}
|
15888
|
+
if (srcTypeVarContext && clonedSrcTypeVarContext) {
|
15889
|
+
srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
|
15890
|
+
}
|
15891
|
+
return true;
|
15700
15892
|
}
|
15701
15893
|
}
|
15702
15894
|
const expandedSrcType = makeTopLevelTypeVarsConcrete(srcType);
|
@@ -15795,7 +15987,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15795
15987
|
return !isLiteral;
|
15796
15988
|
}
|
15797
15989
|
}
|
15798
|
-
else if (types_1.ClassType.isBuiltIn(destType,
|
15990
|
+
else if (types_1.ClassType.isBuiltIn(destType, 'TypeGuard')) {
|
15799
15991
|
// All the source to be a "bool".
|
15800
15992
|
if ((originalFlags & 64 /* AllowBoolTypeGuard */) !== 0) {
|
15801
15993
|
if ((0, types_1.isClassInstance)(srcType) && types_1.ClassType.isBuiltIn(srcType, 'bool')) {
|
@@ -16047,6 +16239,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16047
16239
|
// whose primary type matches.
|
16048
16240
|
remainingSrcSubtypes.forEach((srcSubtype) => {
|
16049
16241
|
const destTypeIndex = remainingDestSubtypes.findIndex((destSubtype) => {
|
16242
|
+
if ((0, types_1.isTypeSame)(destSubtype, srcSubtype)) {
|
16243
|
+
return true;
|
16244
|
+
}
|
16050
16245
|
if ((0, types_1.isClass)(srcSubtype) &&
|
16051
16246
|
(0, types_1.isClass)(destSubtype) &&
|
16052
16247
|
types_1.TypeBase.isInstance(srcSubtype) === types_1.TypeBase.isInstance(destSubtype) &&
|
@@ -16071,6 +16266,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16071
16266
|
// If there is are remaining dest subtypes and they're all type variables,
|
16072
16267
|
// attempt to assign the remaining source subtypes to them.
|
16073
16268
|
if (canUseFastPath && (remainingDestSubtypes.length !== 0 || remainingSrcSubtypes.length !== 0)) {
|
16269
|
+
if ((flags & 1 /* EnforceInvariance */) !== 0) {
|
16270
|
+
// If we have no src subtypes remaining but not all dest types have been subsumed
|
16271
|
+
// by other dest types, then the types are not compatible if we're enforcing invariance.
|
16272
|
+
if (remainingSrcSubtypes.length === 0) {
|
16273
|
+
return remainingDestSubtypes.every((destSubtype) => isTypeSubsumedByOtherType(destSubtype, destType.subtypes,
|
16274
|
+
/* allowAnyToSubsume */ true, recursionCount));
|
16275
|
+
}
|
16276
|
+
}
|
16074
16277
|
const isReversed = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
|
16075
16278
|
const effectiveDestSubtypes = isReversed ? remainingSrcSubtypes : remainingDestSubtypes;
|
16076
16279
|
if (effectiveDestSubtypes.length === 0 || effectiveDestSubtypes.some((t) => !(0, types_1.isTypeVar)(t))) {
|
@@ -16122,21 +16325,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16122
16325
|
}
|
16123
16326
|
if (!assignType(destType, subtype,
|
16124
16327
|
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
16125
|
-
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
16126
16328
|
// Determine if the current subtype is subsumed by another subtype
|
16127
16329
|
// 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
|
-
});
|
16330
|
+
const isSubtypeSubsumed = isTypeSubsumedByOtherType(subtype, srcType.subtypes,
|
16331
|
+
/* allowAnyToSubsume */ false, recursionCount);
|
16137
16332
|
// Try again with a concrete version of the subtype.
|
16138
16333
|
if (!isSubtypeSubsumed &&
|
16139
|
-
!assignType(destType,
|
16334
|
+
!assignType(destType, subtype, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
16140
16335
|
isIncompatible = true;
|
16141
16336
|
}
|
16142
16337
|
}
|
@@ -16147,6 +16342,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16147
16342
|
}
|
16148
16343
|
return true;
|
16149
16344
|
}
|
16345
|
+
// Determines whether a type is "subsumed by" (i.e. is a proper subtype of) one
|
16346
|
+
// of the other types in a list.
|
16347
|
+
function isTypeSubsumedByOtherType(type, otherTypes, allowAnyToSubsume, recursionCount = 0) {
|
16348
|
+
const concreteType = makeTopLevelTypeVarsConcrete(type);
|
16349
|
+
for (const otherType of otherTypes) {
|
16350
|
+
if ((0, types_1.isTypeSame)(otherType, type)) {
|
16351
|
+
continue;
|
16352
|
+
}
|
16353
|
+
if ((0, types_1.isAnyOrUnknown)(otherType)) {
|
16354
|
+
if (allowAnyToSubsume) {
|
16355
|
+
return true;
|
16356
|
+
}
|
16357
|
+
}
|
16358
|
+
else if (isProperSubtype(otherType, concreteType, recursionCount)) {
|
16359
|
+
return true;
|
16360
|
+
}
|
16361
|
+
}
|
16362
|
+
return false;
|
16363
|
+
}
|
16150
16364
|
// Determines whether the srcType is a subtype of destType but the converse
|
16151
16365
|
// is not true. It's important that we check both directions to avoid
|
16152
16366
|
// matches for types like `tuple[Any]` and `tuple[int]` from being considered
|
@@ -16914,7 +17128,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16914
17128
|
// Handle the special case where the return type is a TypeGuard[T].
|
16915
17129
|
// This should also act as a bool, since that's its type at runtime.
|
16916
17130
|
if ((0, types_1.isClassInstance)(srcReturnType) &&
|
16917
|
-
types_1.ClassType.isBuiltIn(srcReturnType,
|
17131
|
+
types_1.ClassType.isBuiltIn(srcReturnType, 'TypeGuard') &&
|
16918
17132
|
boolClassType &&
|
16919
17133
|
(0, types_1.isInstantiableClass)(boolClassType)) {
|
16920
17134
|
if (assignType(destReturnType, types_1.ClassType.cloneAsInstance(boolClassType), returnDiag === null || returnDiag === void 0 ? void 0 : returnDiag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
@@ -16964,7 +17178,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16964
17178
|
const typeParam = assignedType.details.typeParameters[index];
|
16965
17179
|
const expectedTypeArgType = typeVarContext.getPrimarySignature().getTypeVarType(typeParam);
|
16966
17180
|
if (expectedTypeArgType) {
|
16967
|
-
if ((0,
|
17181
|
+
if ((0, typeUtils_1.containsAnyRecursive)(expectedTypeArgType) || (0, types_1.isAnyOrUnknown)(typeArg)) {
|
16968
17182
|
replacedTypeArg = true;
|
16969
17183
|
return expectedTypeArgType;
|
16970
17184
|
}
|
@@ -16991,12 +17205,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16991
17205
|
const narrowedType = (0, typeUtils_1.mapSubtypes)(assignedType, (assignedSubtype) => {
|
16992
17206
|
const narrowedSubtype = (0, typeUtils_1.mapSubtypes)(declaredType, (declaredSubtype) => {
|
16993
17207
|
// We can't narrow "Any".
|
16994
|
-
if ((0, types_1.isAnyOrUnknown)(
|
16995
|
-
return
|
17208
|
+
if ((0, types_1.isAnyOrUnknown)(declaredSubtype)) {
|
17209
|
+
return declaredSubtype;
|
16996
17210
|
}
|
16997
17211
|
if (assignType(declaredSubtype, assignedSubtype)) {
|
16998
17212
|
// If the source is generic and has unspecified type arguments,
|
16999
|
-
// see if we can determine
|
17213
|
+
// see if we can determine them based on the declared type.
|
17000
17214
|
if ((0, types_1.isInstantiableClass)(declaredSubtype) && (0, types_1.isInstantiableClass)(assignedSubtype)) {
|
17001
17215
|
const result = replaceTypeArgsWithAny(node, declaredSubtype, assignedSubtype);
|
17002
17216
|
if (result) {
|
@@ -17014,6 +17228,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17014
17228
|
// use the concrete type.
|
17015
17229
|
return declaredSubtype;
|
17016
17230
|
}
|
17231
|
+
// If the assigned subtype is Any, stick with the declared type.
|
17232
|
+
if ((0, types_1.isAny)(assignedSubtype)) {
|
17233
|
+
return declaredSubtype;
|
17234
|
+
}
|
17235
|
+
// If the declared type doesn't contain any `Any` but the assigned
|
17236
|
+
// type does, stick with the declared type.
|
17237
|
+
if ((0, typeUtils_1.containsAnyRecursive)(assignedSubtype) && !(0, typeUtils_1.containsAnyRecursive)(declaredSubtype)) {
|
17238
|
+
return declaredSubtype;
|
17239
|
+
}
|
17017
17240
|
return assignedSubtype;
|
17018
17241
|
}
|
17019
17242
|
return undefined;
|
@@ -17025,16 +17248,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17025
17248
|
}
|
17026
17249
|
return narrowedSubtype;
|
17027
17250
|
});
|
17028
|
-
// If the result of narrowing is Any, stick with the declared (unnarrowed) type.
|
17029
17251
|
// If the result of narrowing is an Unknown that is incomplete, propagate the
|
17030
17252
|
// incomplete type for the benefit of code flow analysis.
|
17031
17253
|
// If the result of narrowing is a complete Unknown, combine the Unknown type
|
17032
17254
|
// with the declared type. In strict mode, this will retain the "unknown type"
|
17033
17255
|
// diagnostics while still providing reasonable completion suggestions.
|
17034
|
-
if ((0,
|
17035
|
-
return declaredType;
|
17036
|
-
}
|
17037
|
-
else if ((0, typeUtils_1.isIncompleteUnknown)(narrowedType)) {
|
17256
|
+
if ((0, typeUtils_1.isIncompleteUnknown)(narrowedType)) {
|
17038
17257
|
return narrowedType;
|
17039
17258
|
}
|
17040
17259
|
else if ((0, types_1.isUnknown)(narrowedType)) {
|