@zzzen/pyright-internal 1.2.0-dev.20230709 → 1.2.0-dev.20230723
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +2 -2
- package/dist/analyzer/backgroundAnalysisProgram.js +3 -3
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/binder.d.ts +1 -0
- package/dist/analyzer/binder.js +19 -2
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +14 -24
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +12 -1
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +42 -36
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +11 -1
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.js +11 -9
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/enums.js +21 -8
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/namedTuples.js +33 -1
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/patternMatching.d.ts +1 -1
- package/dist/analyzer/patternMatching.js +79 -66
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +5 -2
- package/dist/analyzer/program.js +18 -7
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.js +57 -19
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.js +1 -10
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +4 -3
- package/dist/analyzer/sourceFile.js +26 -22
- 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 +829 -601
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +8 -2
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +2 -2
- package/dist/analyzer/typeGuards.js +72 -12
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.d.ts +2 -1
- package/dist/analyzer/typePrinter.js +26 -5
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.js +11 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.js +1 -3
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +10 -3
- package/dist/analyzer/types.js +11 -2
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +5 -5
- package/dist/backgroundAnalysisBase.js +2 -2
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.js +1 -1
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/console.d.ts +4 -1
- package/dist/common/console.js +7 -0
- package/dist/common/console.js.map +1 -1
- package/dist/languageServerBase.d.ts +8 -3
- package/dist/languageServerBase.js +30 -25
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.js +7 -10
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/codeActionProvider.d.ts +1 -0
- package/dist/languageService/codeActionProvider.js +11 -0
- package/dist/languageService/codeActionProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +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 +9 -0
- package/dist/localization/localize.js +29 -3
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +719 -0
- package/dist/localization/package.nls.de.json +719 -1
- package/dist/localization/package.nls.en-us.json +7 -5
- package/dist/localization/package.nls.es.json +719 -1
- package/dist/localization/package.nls.fr.json +719 -1
- package/dist/localization/package.nls.it.json +719 -0
- package/dist/localization/package.nls.ja.json +719 -1
- package/dist/localization/package.nls.ko.json +719 -0
- package/dist/localization/package.nls.pl.json +719 -0
- package/dist/localization/package.nls.pt-br.json +719 -0
- package/dist/localization/package.nls.qps-ploc.json +719 -0
- package/dist/localization/package.nls.ru.json +719 -1
- package/dist/localization/package.nls.tr.json +719 -0
- package/dist/localization/package.nls.zh-cn.json +719 -1
- package/dist/localization/package.nls.zh-tw.json +719 -1
- package/dist/parser/parser.d.ts +3 -0
- package/dist/parser/parser.js +2 -31
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +5 -2
- package/dist/parser/tokenizer.js +16 -4
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/parser/tokenizerTypes.d.ts +2 -2
- package/dist/parser/tokenizerTypes.js.map +1 -1
- package/dist/pprof/profiler.d.ts +36 -0
- package/dist/pprof/profiler.js +64 -0
- package/dist/pprof/profiler.js.map +1 -0
- package/dist/tests/checker.test.js +2 -2
- package/dist/tests/completions.test.js +40 -0
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/config.test.js +12 -0
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js +40 -0
- package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js.map +1 -0
- package/dist/tests/harness/fourslash/testState.d.ts +6 -4
- package/dist/tests/harness/fourslash/testState.js +50 -39
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/vfs/factory.d.ts +1 -0
- package/dist/tests/harness/vfs/factory.js +7 -1
- package/dist/tests/harness/vfs/factory.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.d.ts +2 -2
- package/dist/tests/harness/vfs/filesystem.js +13 -8
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/localizer.test.js +20 -0
- package/dist/tests/localizer.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +21 -1
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +21 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +1 -1
- package/dist/tests/typeEvaluator4.test.js +14 -2
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +4 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/workspaceFactory.js +5 -3
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +10 -8
@@ -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;
|
@@ -566,7 +566,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
566
566
|
}
|
567
567
|
case 31 /* List */:
|
568
568
|
case 45 /* Set */: {
|
569
|
-
typeResult = getTypeOfListOrSet(node, inferenceContext);
|
569
|
+
typeResult = getTypeOfListOrSet(node, flags, inferenceContext);
|
570
570
|
break;
|
571
571
|
}
|
572
572
|
case 46 /* Slice */: {
|
@@ -586,7 +586,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
586
586
|
break;
|
587
587
|
}
|
588
588
|
case 15 /* Dictionary */: {
|
589
|
-
typeResult = getTypeOfDictionary(node, inferenceContext);
|
589
|
+
typeResult = getTypeOfDictionary(node, flags, inferenceContext);
|
590
590
|
break;
|
591
591
|
}
|
592
592
|
case 30 /* Lambda */: {
|
@@ -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') {
|
@@ -1990,10 +1992,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1990
1992
|
if (expectedTypeDiagAddendum) {
|
1991
1993
|
diagAddendum = expectedTypeDiagAddendum;
|
1992
1994
|
}
|
1993
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAssignmentMismatch().format(
|
1994
|
-
|
1995
|
-
destType: printType(declaredType),
|
1996
|
-
}) + diagAddendum.getString(), srcExpression !== null && srcExpression !== void 0 ? srcExpression : nameNode, (_c = (_b = diagAddendum.getEffectiveTextRange()) !== null && _b !== void 0 ? _b : srcExpression) !== null && _c !== void 0 ? _c : nameNode);
|
1995
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAssignmentMismatch().format(printSrcDestTypes(type, declaredType)) +
|
1996
|
+
diagAddendum.getString(), srcExpression !== null && srcExpression !== void 0 ? srcExpression : nameNode, (_c = (_b = diagAddendum.getEffectiveTextRange()) !== null && _b !== void 0 ? _b : srcExpression) !== null && _c !== void 0 ? _c : nameNode);
|
1997
1997
|
// Replace the assigned type with the (unnarrowed) declared type.
|
1998
1998
|
destType = declaredType;
|
1999
1999
|
}
|
@@ -2394,20 +2394,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2394
2394
|
// its bound type and a constrained TypeVar is expanded to its individual
|
2395
2395
|
// constrained types). If conditionFilter is specified, conditions that
|
2396
2396
|
// do not match will be ignored.
|
2397
|
-
function mapSubtypesExpandTypeVars(type, conditionFilter, callback) {
|
2397
|
+
function mapSubtypesExpandTypeVars(type, conditionFilter, callback, recursionCount = 0) {
|
2398
2398
|
const newSubtypes = [];
|
2399
2399
|
let typeChanged = false;
|
2400
|
-
|
2400
|
+
function expandSubtype(unexpandedType, isLastSubtype) {
|
2401
2401
|
let expandedType = (0, types_1.isUnion)(unexpandedType) ? unexpandedType : makeTopLevelTypeVarsConcrete(unexpandedType);
|
2402
2402
|
expandedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedType);
|
2403
|
-
(0, typeUtils_1.doForEachSubtype)(expandedType, (subtype) => {
|
2403
|
+
(0, typeUtils_1.doForEachSubtype)(expandedType, (subtype, index, allSubtypes) => {
|
2404
2404
|
var _a;
|
2405
2405
|
if (conditionFilter) {
|
2406
|
-
|
2406
|
+
const filteredType = applyConditionFilterToType(subtype, conditionFilter, recursionCount);
|
2407
|
+
if (!filteredType) {
|
2407
2408
|
return undefined;
|
2408
2409
|
}
|
2410
|
+
subtype = filteredType;
|
2409
2411
|
}
|
2410
|
-
let transformedType = callback(subtype, unexpandedType);
|
2412
|
+
let transformedType = callback(subtype, unexpandedType, isLastSubtype && index === allSubtypes.length - 1);
|
2411
2413
|
if (transformedType !== unexpandedType) {
|
2412
2414
|
typeChanged = true;
|
2413
2415
|
}
|
@@ -2421,14 +2423,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2421
2423
|
}
|
2422
2424
|
return undefined;
|
2423
2425
|
});
|
2424
|
-
}
|
2426
|
+
}
|
2425
2427
|
if ((0, types_1.isUnion)(type)) {
|
2426
|
-
type.subtypes.forEach((subtype) => {
|
2427
|
-
expandSubtype(subtype);
|
2428
|
+
type.subtypes.forEach((subtype, index) => {
|
2429
|
+
expandSubtype(subtype, index === type.subtypes.length - 1);
|
2428
2430
|
});
|
2429
2431
|
}
|
2430
2432
|
else {
|
2431
|
-
expandSubtype(type);
|
2433
|
+
expandSubtype(type, /* isLastSubtype */ true);
|
2432
2434
|
}
|
2433
2435
|
if (!typeChanged) {
|
2434
2436
|
return type;
|
@@ -2440,6 +2442,40 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2440
2442
|
}
|
2441
2443
|
return newType;
|
2442
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
|
+
}
|
2443
2479
|
function markNamesAccessed(node, names) {
|
2444
2480
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
2445
2481
|
const scope = ScopeUtils.getScopeForNode(node);
|
@@ -2816,7 +2852,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2816
2852
|
// Verify that the name does not refer to a (non type alias) variable.
|
2817
2853
|
if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
|
2818
2854
|
let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
|
2819
|
-
if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
|
2855
|
+
if ((0, types_1.isClass)(type) && !type.includeSubclasses && !symbol.hasTypedDeclarations()) {
|
2820
2856
|
// This check exempts class types that are created by calling
|
2821
2857
|
// NewType, NamedTuple, and by invoking a metaclass directly.
|
2822
2858
|
isAllowedTypeForVariable = true;
|
@@ -2894,13 +2930,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2894
2930
|
function getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType) {
|
2895
2931
|
// This function applies only to variables, parameters, and imports, not to other
|
2896
2932
|
// types of symbols.
|
2897
|
-
|
2898
|
-
|
2899
|
-
.every((decl) => decl.type === 1 /* Variable */ ||
|
2933
|
+
const decls = symbolWithScope.symbol.getDeclarations();
|
2934
|
+
if (!decls.every((decl) => decl.type === 1 /* Variable */ ||
|
2900
2935
|
decl.type === 2 /* Parameter */ ||
|
2901
2936
|
decl.type === 8 /* Alias */)) {
|
2902
2937
|
return undefined;
|
2903
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
|
+
}
|
2904
2946
|
// If the symbol is a variable captured by an inner function
|
2905
2947
|
// or lambda, see if we can infer the type from the outer scope.
|
2906
2948
|
const scopeHierarchy = ScopeUtils.getScopeHierarchy(node, symbolWithScope.scope);
|
@@ -2936,7 +2978,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2936
2978
|
return !codeFlowEngine.isFlowNodeReachable(declCodeFlowNode, innerScopeCodeFlowNode,
|
2937
2979
|
/* ignoreNoReturn */ true);
|
2938
2980
|
})) {
|
2939
|
-
|
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);
|
2940
2986
|
}
|
2941
2987
|
}
|
2942
2988
|
}
|
@@ -3292,7 +3338,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3292
3338
|
baseType = objectType;
|
3293
3339
|
}
|
3294
3340
|
}
|
3295
|
-
|
3341
|
+
function getTypeOfNoneBase(subtype) {
|
3296
3342
|
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
3297
3343
|
if (types_1.TypeBase.isInstance(subtype)) {
|
3298
3344
|
return getTypeOfObjectMember(node.memberName, types_1.ClassType.cloneAsInstance(noneType), memberName, usage, diag);
|
@@ -3302,7 +3348,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3302
3348
|
}
|
3303
3349
|
}
|
3304
3350
|
return undefined;
|
3305
|
-
}
|
3351
|
+
}
|
3306
3352
|
if ((0, types_1.isParamSpec)(baseType) && baseType.paramSpecAccess) {
|
3307
3353
|
baseType = makeTopLevelTypeVarsConcrete(baseType);
|
3308
3354
|
}
|
@@ -3348,11 +3394,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3348
3394
|
if (baseType.details.recursiveTypeAliasName) {
|
3349
3395
|
return { type: types_1.UnknownType.create(/* isIncomplete */ true), isIncomplete: true };
|
3350
3396
|
}
|
3351
|
-
|
3352
|
-
|
3353
|
-
|
3354
|
-
|
3355
|
-
|
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;
|
3356
3405
|
}
|
3357
3406
|
case 7 /* Class */: {
|
3358
3407
|
if (types_1.TypeBase.isInstantiable(baseType)) {
|
@@ -3681,6 +3730,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3681
3730
|
types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
|
3682
3731
|
setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
|
3683
3732
|
}
|
3733
|
+
// Special-case `__init_subclass` and `__class_getitem__` because
|
3734
|
+
// these are always treated as class methods even if they're not
|
3735
|
+
// decorated as such.
|
3736
|
+
if (memberName === '__init_subclass__' || memberName === '__class_getitem__') {
|
3737
|
+
if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isClassMethod(type)) {
|
3738
|
+
type = types_1.FunctionType.cloneWithNewFlags(type, type.details.flags | 2 /* ClassMethod */);
|
3739
|
+
}
|
3740
|
+
}
|
3684
3741
|
}
|
3685
3742
|
const descriptorResult = applyDescriptorAccessMethod(type, memberInfo, classType, bindToType, isAccessedThroughObject, flags, errorNode, memberName, usage, diag);
|
3686
3743
|
if (!descriptorResult) {
|
@@ -3815,7 +3872,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3815
3872
|
type: types_1.ClassType.isClassProperty(lookupClass)
|
3816
3873
|
? baseTypeClass
|
3817
3874
|
: isAccessedThroughObject
|
3818
|
-
? bindToType
|
3875
|
+
? bindToType !== null && bindToType !== void 0 ? bindToType : types_1.ClassType.cloneAsInstance(baseTypeClass)
|
3819
3876
|
: types_1.NoneType.createInstance(),
|
3820
3877
|
},
|
3821
3878
|
},
|
@@ -3964,8 +4021,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3964
4021
|
// If this function is an instance member (e.g. a lambda that was
|
3965
4022
|
// assigned to an instance variable), don't perform any binding.
|
3966
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
|
+
}
|
3967
4036
|
return bindFunctionToClassOrObject(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode,
|
3968
|
-
/* recursionCount */ undefined, treatConstructorAsClassMember,
|
4037
|
+
/* recursionCount */ undefined, treatConstructorAsClassMember, effectiveBindToType);
|
3969
4038
|
}
|
3970
4039
|
}
|
3971
4040
|
if (usage.method === 'set') {
|
@@ -4212,7 +4281,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4212
4281
|
// We limit type narrowing for index expressions to built-in types that are
|
4213
4282
|
// known to have symmetric __getitem__ and __setitem__ methods (i.e. the value
|
4214
4283
|
// passed to __setitem__ is the same type as the value returned by __getitem__).
|
4215
|
-
let baseTypeSupportsIndexNarrowing =
|
4284
|
+
let baseTypeSupportsIndexNarrowing = !(0, types_1.isAny)(baseTypeResult.type);
|
4216
4285
|
mapSubtypesExpandTypeVars(baseTypeResult.type, /* conditionFilter */ undefined, (subtype) => {
|
4217
4286
|
if (!(0, types_1.isClassInstance)(subtype) ||
|
4218
4287
|
!(types_1.ClassType.isBuiltIn(subtype) || types_1.ClassType.isTypedDictClass(subtype))) {
|
@@ -4971,14 +5040,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4971
5040
|
const getTypeArgTypeResult = (expr, argIndex) => {
|
4972
5041
|
let typeResult;
|
4973
5042
|
// If it's a custom __class_getitem__, none of the arguments should be
|
4974
|
-
// treated as types.
|
4975
|
-
|
4976
|
-
|
5043
|
+
// treated as types.
|
5044
|
+
if (options === null || options === void 0 ? void 0 : options.hasCustomClassGetItem) {
|
5045
|
+
adjFlags =
|
5046
|
+
32 /* DisallowParamSpec */ |
|
5047
|
+
64 /* DisallowTypeVarTuple */ |
|
5048
|
+
2 /* DoNotSpecialize */ |
|
5049
|
+
131072 /* DisallowClassVar */;
|
4977
5050
|
typeResult = {
|
4978
|
-
...getTypeOfExpression(expr,
|
5051
|
+
...getTypeOfExpression(expr, adjFlags),
|
5052
|
+
node: expr,
|
5053
|
+
};
|
5054
|
+
}
|
5055
|
+
else if ((options === null || options === void 0 ? void 0 : options.isAnnotatedClass) && argIndex > 0) {
|
5056
|
+
// If it's an Annotated[a, b, c], only the first index should be
|
5057
|
+
// treated as a type.The others can be regular(non - type) objects.
|
5058
|
+
adjFlags =
|
5059
|
+
32 /* DisallowParamSpec */ |
|
4979
5060
|
64 /* DisallowTypeVarTuple */ |
|
4980
5061
|
2 /* DoNotSpecialize */ |
|
4981
|
-
131072 /* DisallowClassVar
|
5062
|
+
131072 /* DisallowClassVar */;
|
5063
|
+
if ((0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(AnalyzerNodeInfo.getFileInfo(node))) {
|
5064
|
+
adjFlags |= 4 /* AllowForwardReferences */;
|
5065
|
+
}
|
5066
|
+
typeResult = {
|
5067
|
+
...getTypeOfExpression(expr, adjFlags),
|
4982
5068
|
node: expr,
|
4983
5069
|
};
|
4984
5070
|
}
|
@@ -5073,6 +5159,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5073
5159
|
return typeResult;
|
5074
5160
|
}
|
5075
5161
|
function getTypeOfTuple(node, flags, inferenceContext) {
|
5162
|
+
var _a;
|
5163
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
|
5164
|
+
((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 1 /* Argument */) {
|
5165
|
+
// This is allowed inside of an index trailer, specifically
|
5166
|
+
// to support Tuple[()], which is the documented way to annotate
|
5167
|
+
// a zero-length tuple.
|
5168
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
5169
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useTupleInstead());
|
5170
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.tupleInAnnotation() + diag.getString(), node);
|
5171
|
+
}
|
5076
5172
|
if ((flags & 128 /* ExpectingInstantiableType */) !== 0 &&
|
5077
5173
|
node.expressions.length === 0 &&
|
5078
5174
|
!inferenceContext) {
|
@@ -5230,12 +5326,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5230
5326
|
function getTypeOfCall(node, flags, inferenceContext) {
|
5231
5327
|
var _a;
|
5232
5328
|
let baseTypeResult;
|
5329
|
+
// Check for the use of `type(x)` within a type annotation. This isn't
|
5330
|
+
// allowed, and it's a common mistake, so we want to emit a diagnostic
|
5331
|
+
// that guides the user to the right solution.
|
5332
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
|
5333
|
+
node.leftExpression.nodeType === 38 /* Name */ &&
|
5334
|
+
node.leftExpression.value === 'type') {
|
5335
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
5336
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useTypeInstead());
|
5337
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeCallNotAllowed() + diag.getString(), node);
|
5338
|
+
}
|
5233
5339
|
// Handle immediate calls of lambdas specially.
|
5234
5340
|
if (node.leftExpression.nodeType === 30 /* Lambda */) {
|
5235
5341
|
baseTypeResult = getTypeOfLambdaForCall(node, inferenceContext);
|
5236
5342
|
}
|
5237
5343
|
else {
|
5238
|
-
baseTypeResult = getTypeOfExpression(node.leftExpression, 2 /* DoNotSpecialize */);
|
5344
|
+
baseTypeResult = getTypeOfExpression(node.leftExpression, 2 /* DoNotSpecialize */ | (flags & 4 /* AllowForwardReferences */));
|
5239
5345
|
}
|
5240
5346
|
const argList = node.arguments.map((arg) => {
|
5241
5347
|
const functionArg = {
|
@@ -5284,20 +5390,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5284
5390
|
}
|
5285
5391
|
}
|
5286
5392
|
else {
|
5287
|
-
// Check for an attempt to invoke an abstract static or class method.
|
5288
|
-
if ((0, types_1.isFunction)(baseTypeResult.type) &&
|
5289
|
-
baseTypeResult.type.boundToType &&
|
5290
|
-
(0, types_1.isInstantiableClass)(baseTypeResult.type.boundToType) &&
|
5291
|
-
!baseTypeResult.type.boundToType.includeSubclasses) {
|
5292
|
-
if (types_1.FunctionType.isAbstractMethod(baseTypeResult.type)) {
|
5293
|
-
if (types_1.FunctionType.isStaticMethod(baseTypeResult.type) ||
|
5294
|
-
types_1.FunctionType.isClassMethod(baseTypeResult.type)) {
|
5295
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
|
5296
|
-
method: baseTypeResult.type.details.name,
|
5297
|
-
}), node.leftExpression);
|
5298
|
-
}
|
5299
|
-
}
|
5300
|
-
}
|
5301
5393
|
const callResult = validateCallArguments(node, argList, baseTypeResult,
|
5302
5394
|
/* typeVarContext */ undefined,
|
5303
5395
|
/* skipUnknownArgCheck */ false, inferenceContext);
|
@@ -5736,7 +5828,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5736
5828
|
// If there were multiple possible matches, evaluate the type as
|
5737
5829
|
// Unknown, but include the "possible types" to allow for completion
|
5738
5830
|
// suggestions.
|
5739
|
-
if (!isDefinitiveMatchFound) {
|
5831
|
+
if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
|
5740
5832
|
possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
|
5741
5833
|
// Did the filtering produce a single result? If so, we're done.
|
5742
5834
|
if (possibleMatchResults.length === 1) {
|
@@ -5944,24 +6036,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5944
6036
|
}
|
5945
6037
|
return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
|
5946
6038
|
}
|
5947
|
-
// Create a helper function that evaluates the overload that
|
5948
|
-
// the arg/param lists.
|
5949
|
-
function
|
5950
|
-
// Find the match with the
|
5951
|
-
//
|
5952
|
-
|
5953
|
-
|
6039
|
+
// Create a helper function that evaluates the overload that best
|
6040
|
+
// matches the arg/param lists.
|
6041
|
+
function evaluateUsingBestMatchingOverload(skipUnknownArgCheck) {
|
6042
|
+
// Find the match with the smallest argument match score. If there
|
6043
|
+
// are more than one with the same score, use the one with the
|
6044
|
+
// largest index. Later overloads tend to be more general.
|
6045
|
+
const bestMatch = filteredMatchResults.reduce((previous, current) => {
|
6046
|
+
if (current.argumentMatchScore === previous.argumentMatchScore) {
|
6047
|
+
return current.overloadIndex > previous.overloadIndex ? current : previous;
|
6048
|
+
}
|
6049
|
+
return current.argumentMatchScore < previous.argumentMatchScore ? current : previous;
|
5954
6050
|
});
|
5955
6051
|
const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
|
5956
|
-
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(
|
6052
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(bestMatch.overload));
|
5957
6053
|
effectiveTypeVarContext.unlock();
|
5958
|
-
return validateFunctionArgumentTypesWithContext(errorNode,
|
6054
|
+
return validateFunctionArgumentTypesWithContext(errorNode, bestMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5959
6055
|
}
|
5960
6056
|
// If there is only one possible arg/param match among the overloads,
|
5961
6057
|
// use the normal type matching mechanism because it is faster and
|
5962
6058
|
// will provide a clearer error message.
|
5963
6059
|
if (filteredMatchResults.length === 1) {
|
5964
|
-
return
|
6060
|
+
return evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ false);
|
5965
6061
|
}
|
5966
6062
|
let expandedArgTypes = [argList.map((arg) => undefined)];
|
5967
6063
|
let isTypeIncomplete = !!typeResult.isIncomplete;
|
@@ -6004,7 +6100,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6004
6100
|
// in speculative mode because it's very expensive, and we're going to
|
6005
6101
|
// suppress the diagnostic anyway.
|
6006
6102
|
if (!isDiagnosticSuppressedForNode(errorNode) && !isTypeIncomplete) {
|
6007
|
-
const result =
|
6103
|
+
const result = evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ true);
|
6008
6104
|
// Replace the result with an unknown type since we don't know
|
6009
6105
|
// what overload should have been used.
|
6010
6106
|
result.returnType = types_1.UnknownType.create();
|
@@ -6080,346 +6176,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6080
6176
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
6081
6177
|
}
|
6082
6178
|
let returnType = mapSubtypesExpandTypeVars(callTypeResult.type,
|
6083
|
-
/* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype) => {
|
6084
|
-
|
6085
|
-
|
6086
|
-
|
6087
|
-
|
6088
|
-
// Touch all of the args so they're marked accessed. Don't bother
|
6089
|
-
// doing this if the call type is incomplete because this will need
|
6090
|
-
// to be done again once it is complete.
|
6091
|
-
if (!callTypeResult.isIncomplete) {
|
6092
|
-
argList.forEach((arg) => {
|
6093
|
-
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6094
|
-
getTypeOfArgument(arg);
|
6095
|
-
}
|
6096
|
-
});
|
6097
|
-
}
|
6098
|
-
return expandedSubtype;
|
6099
|
-
}
|
6100
|
-
case 5 /* Function */: {
|
6101
|
-
if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
|
6102
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
|
6103
|
-
type: printType(expandedSubtype),
|
6104
|
-
}), errorNode);
|
6105
|
-
argumentErrors = true;
|
6106
|
-
return undefined;
|
6107
|
-
}
|
6108
|
-
// The stdlib collections/__init__.pyi stub file defines namedtuple
|
6109
|
-
// as a function rather than a class, so we need to check for it here.
|
6110
|
-
if (expandedSubtype.details.builtInName === 'namedtuple') {
|
6111
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
|
6112
|
-
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
6113
|
-
/* includesTypes */ false);
|
6114
|
-
}
|
6115
|
-
// Handle the NewType specially, replacing the normal return type.
|
6116
|
-
if (expandedSubtype.details.builtInName === 'NewType') {
|
6117
|
-
return createNewType(errorNode, argList);
|
6118
|
-
}
|
6119
|
-
let effectiveTypeVarContext = typeVarContext;
|
6120
|
-
if (!effectiveTypeVarContext) {
|
6121
|
-
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6122
|
-
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
|
6123
|
-
// There are certain cases, such as with super().__new__(cls) calls where
|
6124
|
-
// the call is a constructor but the proper TypeVar scope has been lost.
|
6125
|
-
// We'll add a wildcard TypeVar scope here. This is a bit of a hack and
|
6126
|
-
// we may need to revisit this in the future.
|
6127
|
-
if (types_1.FunctionType.isConstructorMethod(expandedSubtype)) {
|
6128
|
-
effectiveTypeVarContext.addSolveForScope(types_1.WildcardTypeVarScopeId);
|
6129
|
-
}
|
6130
|
-
}
|
6131
|
-
const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6132
|
-
if (functionResult.isTypeIncomplete) {
|
6133
|
-
isTypeIncomplete = true;
|
6134
|
-
}
|
6135
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
|
6136
|
-
if (functionResult.argumentErrors) {
|
6137
|
-
argumentErrors = true;
|
6138
|
-
}
|
6139
|
-
else {
|
6140
|
-
specializedInitSelfType = functionResult.specializedInitSelfType;
|
6141
|
-
// Call the function transform logic to handle special-cased functions.
|
6142
|
-
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
|
6143
|
-
argumentErrors: functionResult.argumentErrors,
|
6144
|
-
returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
|
6145
|
-
isTypeIncomplete,
|
6146
|
-
});
|
6147
|
-
functionResult.returnType = transformed.returnType;
|
6148
|
-
if (transformed.isTypeIncomplete) {
|
6149
|
-
isTypeIncomplete = true;
|
6150
|
-
}
|
6151
|
-
if (transformed.argumentErrors) {
|
6152
|
-
argumentErrors = true;
|
6153
|
-
}
|
6154
|
-
}
|
6155
|
-
if (expandedSubtype.details.builtInName === '__import__') {
|
6156
|
-
// For the special __import__ type, we'll override the return type to be "Any".
|
6157
|
-
// This is required because we don't know what module was imported, and we don't
|
6158
|
-
// want to fail type checks when accessing members of the resulting module type.
|
6159
|
-
return types_1.AnyType.create();
|
6160
|
-
}
|
6161
|
-
return functionResult.returnType;
|
6162
|
-
}
|
6163
|
-
case 6 /* OverloadedFunction */: {
|
6164
|
-
// Handle the 'cast' call as a special case.
|
6165
|
-
if (expandedSubtype.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
|
6166
|
-
// Verify that the cast is necessary.
|
6167
|
-
const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
|
6168
|
-
const castFromType = getTypeOfArgument(argList[1]).type;
|
6169
|
-
if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
|
6170
|
-
if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
|
6171
|
-
ignorePseudoGeneric: true,
|
6172
|
-
})) {
|
6173
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUnnecessaryCast, diagnosticRules_1.DiagnosticRule.reportUnnecessaryCast, localize_1.Localizer.Diagnostic.unnecessaryCast().format({
|
6174
|
-
type: printType(castFromType),
|
6175
|
-
}), errorNode);
|
6176
|
-
}
|
6177
|
-
}
|
6178
|
-
return (0, typeUtils_1.convertToInstance)(castToType);
|
6179
|
-
}
|
6180
|
-
const functionResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6181
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
|
6182
|
-
if (functionResult.isTypeIncomplete) {
|
6183
|
-
isTypeIncomplete = true;
|
6184
|
-
}
|
6185
|
-
if (functionResult.argumentErrors) {
|
6186
|
-
argumentErrors = true;
|
6187
|
-
}
|
6188
|
-
else {
|
6189
|
-
specializedInitSelfType = functionResult.specializedInitSelfType;
|
6190
|
-
// Call the function transform logic to handle special-cased functions.
|
6191
|
-
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
|
6192
|
-
argumentErrors: functionResult.argumentErrors,
|
6193
|
-
returnType: (_b = functionResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
|
6194
|
-
isTypeIncomplete,
|
6195
|
-
});
|
6196
|
-
functionResult.returnType = transformed.returnType;
|
6197
|
-
if (transformed.isTypeIncomplete) {
|
6198
|
-
isTypeIncomplete = true;
|
6199
|
-
}
|
6200
|
-
if (transformed.argumentErrors) {
|
6201
|
-
argumentErrors = true;
|
6202
|
-
}
|
6203
|
-
}
|
6204
|
-
return (_c = functionResult.returnType) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
|
6205
|
-
}
|
6206
|
-
case 7 /* Class */: {
|
6207
|
-
if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
|
6208
|
-
if (expandedSubtype.literalValue !== undefined) {
|
6209
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
|
6210
|
-
argumentErrors = true;
|
6211
|
-
return types_1.UnknownType.create();
|
6212
|
-
}
|
6213
|
-
if (types_1.ClassType.isBuiltIn(expandedSubtype)) {
|
6214
|
-
const className = expandedSubtype.aliasName || expandedSubtype.details.name;
|
6215
|
-
if (className === 'type') {
|
6216
|
-
// Validate the constructor arguments.
|
6217
|
-
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6218
|
-
// Handle the 'type' call specially.
|
6219
|
-
if (argList.length === 1) {
|
6220
|
-
// The one-parameter form of "type" returns the class
|
6221
|
-
// for the specified object.
|
6222
|
-
const argType = getTypeOfArgument(argList[0]).type;
|
6223
|
-
return (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
|
6224
|
-
if ((0, types_1.isClassInstance)(subtype) ||
|
6225
|
-
((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
|
6226
|
-
(0, types_1.isNoneInstance)(subtype)) {
|
6227
|
-
return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
|
6228
|
-
}
|
6229
|
-
else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
|
6230
|
-
return types_1.FunctionType.cloneAsInstantiable(subtype);
|
6231
|
-
}
|
6232
|
-
return types_1.AnyType.create();
|
6233
|
-
});
|
6234
|
-
}
|
6235
|
-
else if (argList.length >= 2) {
|
6236
|
-
// The two-parameter form of "type" returns a new class type
|
6237
|
-
// built from the specified base types.
|
6238
|
-
return createType(errorNode, argList) || types_1.AnyType.create();
|
6239
|
-
}
|
6240
|
-
// If the parameter to type() is not statically known,
|
6241
|
-
// fall back to Any.
|
6242
|
-
return types_1.AnyType.create();
|
6243
|
-
}
|
6244
|
-
if (className === 'TypeVar') {
|
6245
|
-
return createTypeVarType(errorNode, expandedSubtype, argList);
|
6246
|
-
}
|
6247
|
-
if (className === 'TypeVarTuple') {
|
6248
|
-
return createTypeVarTupleType(errorNode, expandedSubtype, argList);
|
6249
|
-
}
|
6250
|
-
if (className === 'ParamSpec') {
|
6251
|
-
return createParamSpecType(errorNode, expandedSubtype, argList);
|
6252
|
-
}
|
6253
|
-
if (className === 'TypeAliasType') {
|
6254
|
-
const newTypeAlias = createTypeAliasType(errorNode, argList);
|
6255
|
-
if (newTypeAlias) {
|
6256
|
-
return newTypeAlias;
|
6257
|
-
}
|
6258
|
-
}
|
6259
|
-
if (className === 'NamedTuple') {
|
6260
|
-
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
6261
|
-
/* includesTypes */ true);
|
6262
|
-
}
|
6263
|
-
if (className === 'NewType') {
|
6264
|
-
return createNewType(errorNode, argList);
|
6265
|
-
}
|
6266
|
-
if (className === 'Protocol' ||
|
6267
|
-
className === 'Generic' ||
|
6268
|
-
className === 'Callable' ||
|
6269
|
-
className === 'Concatenate' ||
|
6270
|
-
className === 'Type') {
|
6271
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
6272
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
|
6273
|
-
return types_1.AnyType.create();
|
6274
|
-
}
|
6275
|
-
if ((0, types_1.isClass)(unexpandedSubtype) && (0, enums_1.isKnownEnumType)(className)) {
|
6276
|
-
return ((_d = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedSubtype, argList)) !== null && _d !== void 0 ? _d : types_1.UnknownType.create());
|
6277
|
-
}
|
6278
|
-
if (className === 'TypedDict') {
|
6279
|
-
return (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedSubtype, argList);
|
6280
|
-
}
|
6281
|
-
if (className === 'auto' && argList.length === 0) {
|
6282
|
-
return (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode);
|
6283
|
-
}
|
6284
|
-
}
|
6285
|
-
if (types_1.ClassType.supportsAbstractMethods(expandedSubtype)) {
|
6286
|
-
const abstractMethods = getAbstractMethods(expandedSubtype);
|
6287
|
-
if (abstractMethods.length > 0 &&
|
6288
|
-
!expandedSubtype.includeSubclasses &&
|
6289
|
-
!(0, types_1.isTypeVar)(unexpandedSubtype)) {
|
6290
|
-
// If the class is abstract, it can't be instantiated.
|
6291
|
-
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
6292
|
-
const errorsToDisplay = 2;
|
6293
|
-
abstractMethods.forEach((abstractMethod, index) => {
|
6294
|
-
if (index === errorsToDisplay) {
|
6295
|
-
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
|
6296
|
-
count: abstractMethods.length - errorsToDisplay,
|
6297
|
-
}));
|
6298
|
-
}
|
6299
|
-
else if (index < errorsToDisplay) {
|
6300
|
-
if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
|
6301
|
-
const className = abstractMethod.classType.details.name;
|
6302
|
-
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
|
6303
|
-
type: className,
|
6304
|
-
name: abstractMethod.symbolName,
|
6305
|
-
}));
|
6306
|
-
}
|
6307
|
-
}
|
6308
|
-
});
|
6309
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
|
6310
|
-
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
|
6311
|
-
type: expandedSubtype.details.name,
|
6312
|
-
}) + diagAddendum.getString(), errorNode);
|
6313
|
-
}
|
6314
|
-
}
|
6315
|
-
if (types_1.ClassType.isProtocolClass(expandedSubtype) && !expandedSubtype.includeSubclasses) {
|
6316
|
-
// If the class is a protocol, it can't be instantiated.
|
6317
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
|
6318
|
-
type: expandedSubtype.details.name,
|
6319
|
-
}), errorNode);
|
6320
|
-
}
|
6321
|
-
// Assume this is a call to the constructor.
|
6322
|
-
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6323
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, constructorResult.overloadsUsedForCall);
|
6324
|
-
if (constructorResult.argumentErrors) {
|
6325
|
-
argumentErrors = true;
|
6326
|
-
}
|
6327
|
-
if (constructorResult.isTypeIncomplete) {
|
6328
|
-
isTypeIncomplete = true;
|
6329
|
-
}
|
6330
|
-
let returnType = constructorResult.returnType;
|
6331
|
-
// If the expandedSubtype originated from a TypeVar, convert
|
6332
|
-
// the constructed type back to the TypeVar. For example, if
|
6333
|
-
// we have `cls: Type[_T]` followed by `_T()`.
|
6334
|
-
if ((0, types_1.isTypeVar)(unexpandedSubtype)) {
|
6335
|
-
returnType = (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
|
6336
|
-
}
|
6337
|
-
// If we instantiated a type, transform it into a class.
|
6338
|
-
// This can happen if someone directly instantiates a metaclass
|
6339
|
-
// deriving from type.
|
6340
|
-
if (returnType &&
|
6341
|
-
(0, types_1.isClassInstance)(returnType) &&
|
6342
|
-
returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
|
6343
|
-
let newClassName = '__class_' + returnType.details.name;
|
6344
|
-
if (argList.length === 3) {
|
6345
|
-
const firstArgType = getTypeOfArgument(argList[0]).type;
|
6346
|
-
if ((0, types_1.isClassInstance)(firstArgType) &&
|
6347
|
-
types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
|
6348
|
-
typeof firstArgType.literalValue === 'string') {
|
6349
|
-
newClassName = firstArgType.literalValue;
|
6350
|
-
}
|
6351
|
-
}
|
6352
|
-
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));
|
6353
|
-
newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
|
6354
|
-
newClassType.details.effectiveMetaclass = expandedSubtype;
|
6355
|
-
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
6356
|
-
return newClassType;
|
6357
|
-
}
|
6358
|
-
return returnType;
|
6359
|
-
}
|
6360
|
-
else {
|
6361
|
-
const memberType = (_e = getTypeOfObjectMember(errorNode, expandedSubtype, '__call__',
|
6362
|
-
/* usage */ undefined,
|
6363
|
-
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _e === void 0 ? void 0 : _e.type;
|
6364
|
-
if (memberType) {
|
6365
|
-
const functionResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6366
|
-
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
|
6367
|
-
if (functionResult.argumentErrors) {
|
6368
|
-
argumentErrors = true;
|
6369
|
-
}
|
6370
|
-
if ((0, types_1.isTypeVar)(unexpandedSubtype) &&
|
6371
|
-
types_1.TypeBase.isInstantiable(unexpandedSubtype) &&
|
6372
|
-
(0, types_1.isClass)(expandedSubtype) &&
|
6373
|
-
types_1.ClassType.isBuiltIn(expandedSubtype, 'type')) {
|
6374
|
-
// Handle the case where a Type[T] is being called. We presume this
|
6375
|
-
// will instantiate an object of type T.
|
6376
|
-
return (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
|
6377
|
-
}
|
6378
|
-
return (_f = functionResult.returnType) !== null && _f !== void 0 ? _f : types_1.UnknownType.create();
|
6379
|
-
}
|
6380
|
-
if (!memberType || !(0, types_1.isAnyOrUnknown)(memberType)) {
|
6381
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6382
|
-
type: printType(expandedSubtype),
|
6383
|
-
}), errorNode);
|
6384
|
-
}
|
6385
|
-
return types_1.UnknownType.create();
|
6386
|
-
}
|
6179
|
+
/* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
|
6180
|
+
return useSpeculativeMode(isLastIteration ? undefined : errorNode, () => {
|
6181
|
+
const callResult = validateCallArgumentsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6182
|
+
if (callResult.argumentErrors) {
|
6183
|
+
argumentErrors = true;
|
6387
6184
|
}
|
6388
|
-
|
6389
|
-
|
6390
|
-
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
6391
|
-
const functionResult = validateCallArguments(errorNode, argList, { type: noneType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6392
|
-
if (functionResult.isTypeIncomplete) {
|
6393
|
-
isTypeIncomplete = true;
|
6394
|
-
}
|
6395
|
-
if (functionResult.argumentErrors) {
|
6396
|
-
argumentErrors = true;
|
6397
|
-
}
|
6398
|
-
}
|
6399
|
-
return types_1.NoneType.createInstance();
|
6400
|
-
}
|
6401
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
|
6402
|
-
return undefined;
|
6185
|
+
if (callResult.isTypeIncomplete) {
|
6186
|
+
isTypeIncomplete = true;
|
6403
6187
|
}
|
6404
|
-
|
6405
|
-
// but we still need to handle the case of Type[T] where
|
6406
|
-
// T is a constrained type that contains a union. We also
|
6407
|
-
// need to handle recursive type aliases.
|
6408
|
-
case 10 /* TypeVar */: {
|
6409
|
-
expandedSubtype = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedSubtype);
|
6410
|
-
const callResult = validateCallArguments(errorNode, argList, { type: expandedSubtype }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6188
|
+
if (callResult.overloadsUsedForCall) {
|
6411
6189
|
(0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
|
6412
|
-
if (callResult.argumentErrors) {
|
6413
|
-
argumentErrors = true;
|
6414
|
-
}
|
6415
|
-
return (_g = callResult.returnType) !== null && _g !== void 0 ? _g : types_1.UnknownType.create();
|
6416
6190
|
}
|
6417
|
-
|
6418
|
-
|
6419
|
-
|
6420
|
-
|
6421
|
-
}
|
6422
|
-
return undefined;
|
6191
|
+
specializedInitSelfType = callResult.specializedInitSelfType;
|
6192
|
+
return callResult.returnType;
|
6193
|
+
}, {
|
6194
|
+
allowDiagnostics: true,
|
6195
|
+
});
|
6423
6196
|
});
|
6424
6197
|
// If we ended up with a "Never" type because all code paths returned
|
6425
6198
|
// undefined due to argument errors, transform the result into an Unknown
|
@@ -6435,6 +6208,362 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6435
6208
|
overloadsUsedForCall,
|
6436
6209
|
};
|
6437
6210
|
}
|
6211
|
+
function validateCallArgumentsForSubtype(errorNode, argList, expandedCallType, unexpandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6212
|
+
switch (expandedCallType.category) {
|
6213
|
+
case 4 /* Never */:
|
6214
|
+
case 1 /* Unknown */:
|
6215
|
+
case 2 /* Any */: {
|
6216
|
+
// Touch all of the args so they're marked accessed. Don't bother
|
6217
|
+
// doing this if the call type is incomplete because this will need
|
6218
|
+
// to be done again once it is complete.
|
6219
|
+
if (!isCallTypeIncomplete) {
|
6220
|
+
argList.forEach((arg) => {
|
6221
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6222
|
+
getTypeOfArgument(arg);
|
6223
|
+
}
|
6224
|
+
});
|
6225
|
+
}
|
6226
|
+
return { returnType: expandedCallType };
|
6227
|
+
}
|
6228
|
+
case 5 /* Function */: {
|
6229
|
+
return validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6230
|
+
}
|
6231
|
+
case 6 /* OverloadedFunction */: {
|
6232
|
+
return validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6233
|
+
}
|
6234
|
+
case 7 /* Class */: {
|
6235
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6236
|
+
return validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext);
|
6237
|
+
}
|
6238
|
+
return validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6239
|
+
}
|
6240
|
+
case 3 /* None */: {
|
6241
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6242
|
+
if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
|
6243
|
+
const callResult = validateCallForInstantiableClass(errorNode, argList, noneType, noneType, skipUnknownArgCheck, inferenceContext);
|
6244
|
+
return { ...callResult, returnType: types_1.NoneType.createInstance() };
|
6245
|
+
}
|
6246
|
+
return { returnType: types_1.NoneType.createInstance() };
|
6247
|
+
}
|
6248
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
|
6249
|
+
return { argumentErrors: true };
|
6250
|
+
}
|
6251
|
+
// TypeVars should have been expanded in most cases,
|
6252
|
+
// but we still need to handle the case of Type[T] where
|
6253
|
+
// T is a constrained type that contains a union. We also
|
6254
|
+
// need to handle recursive type aliases.
|
6255
|
+
case 10 /* TypeVar */: {
|
6256
|
+
return validateCallArguments(errorNode, argList, { type: (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedCallType), isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6257
|
+
}
|
6258
|
+
case 8 /* Module */: {
|
6259
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
|
6260
|
+
return { argumentErrors: true };
|
6261
|
+
}
|
6262
|
+
}
|
6263
|
+
return { argumentErrors: true };
|
6264
|
+
}
|
6265
|
+
function validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
6266
|
+
var _a;
|
6267
|
+
if (types_1.TypeBase.isInstantiable(expandedCallType)) {
|
6268
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
|
6269
|
+
type: printType(expandedCallType),
|
6270
|
+
}), errorNode);
|
6271
|
+
return { returnType: undefined, argumentErrors: true };
|
6272
|
+
}
|
6273
|
+
// Check for an attempt to invoke an abstract static or class method.
|
6274
|
+
if (expandedCallType.boundToType &&
|
6275
|
+
(0, types_1.isInstantiableClass)(expandedCallType.boundToType) &&
|
6276
|
+
!expandedCallType.boundToType.includeSubclasses) {
|
6277
|
+
if (types_1.FunctionType.isAbstractMethod(expandedCallType)) {
|
6278
|
+
if (types_1.FunctionType.isStaticMethod(expandedCallType) || types_1.FunctionType.isClassMethod(expandedCallType)) {
|
6279
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
|
6280
|
+
method: expandedCallType.details.name,
|
6281
|
+
}), errorNode.nodeType === 9 /* Call */ ? errorNode.leftExpression : errorNode);
|
6282
|
+
}
|
6283
|
+
}
|
6284
|
+
}
|
6285
|
+
// The stdlib collections/__init__.pyi stub file defines namedtuple
|
6286
|
+
// as a function rather than a class, so we need to check for it here.
|
6287
|
+
if (expandedCallType.details.builtInName === 'namedtuple') {
|
6288
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
|
6289
|
+
return {
|
6290
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ false),
|
6291
|
+
};
|
6292
|
+
}
|
6293
|
+
// Handle the NewType specially, replacing the normal return type.
|
6294
|
+
if (expandedCallType.details.builtInName === 'NewType') {
|
6295
|
+
return { returnType: createNewType(errorNode, argList) };
|
6296
|
+
}
|
6297
|
+
let effectiveTypeVarContext = typeVarContext;
|
6298
|
+
if (!effectiveTypeVarContext) {
|
6299
|
+
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6300
|
+
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
|
6301
|
+
}
|
6302
|
+
const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6303
|
+
let isTypeIncomplete = !!functionResult.isTypeIncomplete;
|
6304
|
+
let returnType = functionResult.returnType;
|
6305
|
+
let argumentErrors = !!functionResult.argumentErrors;
|
6306
|
+
if (!argumentErrors) {
|
6307
|
+
// Call the function transform logic to handle special-cased functions.
|
6308
|
+
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
6309
|
+
argumentErrors: !!functionResult.argumentErrors,
|
6310
|
+
returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
|
6311
|
+
isTypeIncomplete,
|
6312
|
+
});
|
6313
|
+
returnType = transformed.returnType;
|
6314
|
+
if (transformed.isTypeIncomplete) {
|
6315
|
+
isTypeIncomplete = true;
|
6316
|
+
}
|
6317
|
+
if (transformed.argumentErrors) {
|
6318
|
+
argumentErrors = true;
|
6319
|
+
}
|
6320
|
+
}
|
6321
|
+
if (expandedCallType.details.builtInName === '__import__') {
|
6322
|
+
// For the special __import__ type, we'll override the return type to be "Any".
|
6323
|
+
// This is required because we don't know what module was imported, and we don't
|
6324
|
+
// want to fail type checks when accessing members of the resulting module type.
|
6325
|
+
returnType = types_1.AnyType.create();
|
6326
|
+
}
|
6327
|
+
return {
|
6328
|
+
returnType,
|
6329
|
+
isTypeIncomplete,
|
6330
|
+
argumentErrors,
|
6331
|
+
overloadsUsedForCall: functionResult.overloadsUsedForCall,
|
6332
|
+
specializedInitSelfType: functionResult.specializedInitSelfType,
|
6333
|
+
};
|
6334
|
+
}
|
6335
|
+
function validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
6336
|
+
var _a, _b;
|
6337
|
+
// Handle the 'cast' call as a special case.
|
6338
|
+
if (expandedCallType.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
|
6339
|
+
return { returnType: evaluateCastCall(argList, errorNode) };
|
6340
|
+
}
|
6341
|
+
const callResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6342
|
+
let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
|
6343
|
+
let isTypeIncomplete = !!callResult.isTypeIncomplete;
|
6344
|
+
let argumentErrors = !!callResult.argumentErrors;
|
6345
|
+
if (!argumentErrors) {
|
6346
|
+
// Call the function transform logic to handle special-cased functions.
|
6347
|
+
const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
|
6348
|
+
argumentErrors: !!callResult.argumentErrors,
|
6349
|
+
returnType: (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
|
6350
|
+
isTypeIncomplete,
|
6351
|
+
});
|
6352
|
+
returnType = transformed.returnType;
|
6353
|
+
if (transformed.isTypeIncomplete) {
|
6354
|
+
isTypeIncomplete = true;
|
6355
|
+
}
|
6356
|
+
if (transformed.argumentErrors) {
|
6357
|
+
argumentErrors = true;
|
6358
|
+
}
|
6359
|
+
}
|
6360
|
+
return {
|
6361
|
+
returnType,
|
6362
|
+
isTypeIncomplete,
|
6363
|
+
argumentErrors,
|
6364
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
6365
|
+
specializedInitSelfType: callResult.specializedInitSelfType,
|
6366
|
+
};
|
6367
|
+
}
|
6368
|
+
function validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext) {
|
6369
|
+
var _a;
|
6370
|
+
if (expandedCallType.literalValue !== undefined) {
|
6371
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
|
6372
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6373
|
+
}
|
6374
|
+
if (types_1.ClassType.isBuiltIn(expandedCallType)) {
|
6375
|
+
const className = expandedCallType.aliasName || expandedCallType.details.name;
|
6376
|
+
if (className === 'type') {
|
6377
|
+
// Validate the constructor arguments.
|
6378
|
+
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
|
6379
|
+
// Handle the 'type' call specially.
|
6380
|
+
if (argList.length === 1) {
|
6381
|
+
// The one-parameter form of "type" returns the class
|
6382
|
+
// for the specified object.
|
6383
|
+
const argType = getTypeOfArgument(argList[0]).type;
|
6384
|
+
const returnType = (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
|
6385
|
+
if ((0, types_1.isClassInstance)(subtype) ||
|
6386
|
+
((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
|
6387
|
+
(0, types_1.isNoneInstance)(subtype)) {
|
6388
|
+
return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
|
6389
|
+
}
|
6390
|
+
else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
|
6391
|
+
return types_1.FunctionType.cloneAsInstantiable(subtype);
|
6392
|
+
}
|
6393
|
+
return types_1.AnyType.create();
|
6394
|
+
});
|
6395
|
+
return { returnType };
|
6396
|
+
}
|
6397
|
+
if (argList.length >= 2) {
|
6398
|
+
// The two-parameter form of "type" returns a new class type
|
6399
|
+
// built from the specified base types.
|
6400
|
+
return { returnType: createType(errorNode, argList) || types_1.AnyType.create() };
|
6401
|
+
}
|
6402
|
+
// If the parameter to type() is not statically known,
|
6403
|
+
// fall back to Any.
|
6404
|
+
return { returnType: types_1.AnyType.create() };
|
6405
|
+
}
|
6406
|
+
if (className === 'TypeVar') {
|
6407
|
+
return {
|
6408
|
+
returnType: createTypeVarType(errorNode, expandedCallType, argList),
|
6409
|
+
};
|
6410
|
+
}
|
6411
|
+
if (className === 'TypeVarTuple') {
|
6412
|
+
return {
|
6413
|
+
returnType: createTypeVarTupleType(errorNode, expandedCallType, argList),
|
6414
|
+
};
|
6415
|
+
}
|
6416
|
+
if (className === 'ParamSpec') {
|
6417
|
+
return {
|
6418
|
+
returnType: createParamSpecType(errorNode, expandedCallType, argList),
|
6419
|
+
};
|
6420
|
+
}
|
6421
|
+
if (className === 'TypeAliasType') {
|
6422
|
+
const newTypeAlias = createTypeAliasType(errorNode, argList);
|
6423
|
+
if (newTypeAlias) {
|
6424
|
+
return { returnType: newTypeAlias };
|
6425
|
+
}
|
6426
|
+
}
|
6427
|
+
if (className === 'NamedTuple') {
|
6428
|
+
return {
|
6429
|
+
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
|
6430
|
+
};
|
6431
|
+
}
|
6432
|
+
if (className === 'NewType') {
|
6433
|
+
return { returnType: createNewType(errorNode, argList) };
|
6434
|
+
}
|
6435
|
+
if (className === 'Protocol' ||
|
6436
|
+
className === 'Generic' ||
|
6437
|
+
className === 'Callable' ||
|
6438
|
+
className === 'Concatenate' ||
|
6439
|
+
className === 'Type') {
|
6440
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
6441
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
|
6442
|
+
return { returnType: types_1.AnyType.create() };
|
6443
|
+
}
|
6444
|
+
if ((0, types_1.isClass)(unexpandedCallType) && (0, enums_1.isKnownEnumType)(className)) {
|
6445
|
+
return {
|
6446
|
+
returnType: (_a = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedCallType, argList)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(),
|
6447
|
+
};
|
6448
|
+
}
|
6449
|
+
if (className === 'TypedDict') {
|
6450
|
+
return { returnType: (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedCallType, argList) };
|
6451
|
+
}
|
6452
|
+
if (className === 'auto' && argList.length === 0) {
|
6453
|
+
return { returnType: (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode) };
|
6454
|
+
}
|
6455
|
+
}
|
6456
|
+
if (types_1.ClassType.supportsAbstractMethods(expandedCallType)) {
|
6457
|
+
const abstractMethods = getAbstractMethods(expandedCallType);
|
6458
|
+
if (abstractMethods.length > 0 && !expandedCallType.includeSubclasses && !(0, types_1.isTypeVar)(unexpandedCallType)) {
|
6459
|
+
// If the class is abstract, it can't be instantiated.
|
6460
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
6461
|
+
const errorsToDisplay = 2;
|
6462
|
+
abstractMethods.forEach((abstractMethod, index) => {
|
6463
|
+
if (index === errorsToDisplay) {
|
6464
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
|
6465
|
+
count: abstractMethods.length - errorsToDisplay,
|
6466
|
+
}));
|
6467
|
+
}
|
6468
|
+
else if (index < errorsToDisplay) {
|
6469
|
+
if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
|
6470
|
+
const className = abstractMethod.classType.details.name;
|
6471
|
+
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
|
6472
|
+
type: className,
|
6473
|
+
name: abstractMethod.symbolName,
|
6474
|
+
}));
|
6475
|
+
}
|
6476
|
+
}
|
6477
|
+
});
|
6478
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
|
6479
|
+
type: expandedCallType.details.name,
|
6480
|
+
}) + diagAddendum.getString(), errorNode);
|
6481
|
+
}
|
6482
|
+
}
|
6483
|
+
if (types_1.ClassType.isProtocolClass(expandedCallType) && !expandedCallType.includeSubclasses) {
|
6484
|
+
// If the class is a protocol, it can't be instantiated.
|
6485
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
|
6486
|
+
type: expandedCallType.details.name,
|
6487
|
+
}), errorNode);
|
6488
|
+
}
|
6489
|
+
// Assume this is a call to the constructor.
|
6490
|
+
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
|
6491
|
+
const overloadsUsedForCall = constructorResult.overloadsUsedForCall;
|
6492
|
+
const argumentErrors = constructorResult.argumentErrors;
|
6493
|
+
const isTypeIncomplete = constructorResult.isTypeIncomplete;
|
6494
|
+
let returnType = constructorResult.returnType;
|
6495
|
+
// If the expandedCallType originated from a TypeVar, convert
|
6496
|
+
// the constructed type back to the TypeVar. For example, if
|
6497
|
+
// we have `cls: Type[_T]` followed by `_T()`.
|
6498
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType)) {
|
6499
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
6500
|
+
}
|
6501
|
+
// If we instantiated a type, transform it into a class.
|
6502
|
+
// This can happen if someone directly instantiates a metaclass
|
6503
|
+
// deriving from type.
|
6504
|
+
if (returnType &&
|
6505
|
+
(0, types_1.isClassInstance)(returnType) &&
|
6506
|
+
returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
|
6507
|
+
let newClassName = '__class_' + returnType.details.name;
|
6508
|
+
if (argList.length === 3) {
|
6509
|
+
const firstArgType = getTypeOfArgument(argList[0]).type;
|
6510
|
+
if ((0, types_1.isClassInstance)(firstArgType) &&
|
6511
|
+
types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
|
6512
|
+
typeof firstArgType.literalValue === 'string') {
|
6513
|
+
newClassName = firstArgType.literalValue;
|
6514
|
+
}
|
6515
|
+
}
|
6516
|
+
const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '', AnalyzerNodeInfo.getFileInfo(errorNode).filePath, 0 /* None */, ParseTreeUtils.getTypeSourceId(errorNode), types_1.ClassType.cloneAsInstantiable(returnType), types_1.ClassType.cloneAsInstantiable(returnType));
|
6517
|
+
newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
|
6518
|
+
newClassType.details.effectiveMetaclass = expandedCallType;
|
6519
|
+
(0, typeUtils_1.computeMroLinearization)(newClassType);
|
6520
|
+
returnType = newClassType;
|
6521
|
+
}
|
6522
|
+
return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
|
6523
|
+
}
|
6524
|
+
function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6525
|
+
var _a, _b;
|
6526
|
+
const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
|
6527
|
+
/* usage */ undefined,
|
6528
|
+
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
6529
|
+
if (!memberType) {
|
6530
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6531
|
+
type: printType(expandedCallType),
|
6532
|
+
}), errorNode);
|
6533
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6534
|
+
}
|
6535
|
+
const callResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6536
|
+
let returnType = (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
|
6537
|
+
if ((0, types_1.isTypeVar)(unexpandedCallType) &&
|
6538
|
+
types_1.TypeBase.isInstantiable(unexpandedCallType) &&
|
6539
|
+
(0, types_1.isClass)(expandedCallType) &&
|
6540
|
+
types_1.ClassType.isBuiltIn(expandedCallType, 'type')) {
|
6541
|
+
// Handle the case where a Type[T] is being called. We presume this
|
6542
|
+
// will instantiate an object of type T.
|
6543
|
+
returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
|
6544
|
+
}
|
6545
|
+
return {
|
6546
|
+
returnType,
|
6547
|
+
argumentErrors: callResult.argumentErrors,
|
6548
|
+
overloadsUsedForCall: callResult.overloadsUsedForCall,
|
6549
|
+
};
|
6550
|
+
}
|
6551
|
+
// Evaluates the type of the "cast" call.
|
6552
|
+
function evaluateCastCall(argList, errorNode) {
|
6553
|
+
// Verify that the cast is necessary.
|
6554
|
+
const castToType = getTypeOfArgumentExpectingType(argList[0], { enforceTypeAnnotationRules: true }).type;
|
6555
|
+
const castFromType = getTypeOfArgument(argList[1]).type;
|
6556
|
+
if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
|
6557
|
+
if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
|
6558
|
+
ignorePseudoGeneric: true,
|
6559
|
+
})) {
|
6560
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUnnecessaryCast, diagnosticRules_1.DiagnosticRule.reportUnnecessaryCast, localize_1.Localizer.Diagnostic.unnecessaryCast().format({
|
6561
|
+
type: printType(castFromType),
|
6562
|
+
}), errorNode);
|
6563
|
+
}
|
6564
|
+
}
|
6565
|
+
return (0, typeUtils_1.convertToInstance)(castToType);
|
6566
|
+
}
|
6438
6567
|
// Expands any unpacked tuples within an argument list.
|
6439
6568
|
function expandArgList(argList) {
|
6440
6569
|
var _a;
|
@@ -6530,8 +6659,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6530
6659
|
// Does this function define the param spec, or is it an inner
|
6531
6660
|
// function nested within another function that defines the param
|
6532
6661
|
// spec? We need to handle these two cases differently.
|
6533
|
-
|
6534
|
-
|
6662
|
+
const paramSpecScopeId = varArgListParam.type.scopeId;
|
6663
|
+
if (paramSpecScopeId === typeResult.type.details.typeVarScopeId ||
|
6664
|
+
paramSpecScopeId === typeResult.type.details.constructorTypeVarScopeId) {
|
6535
6665
|
paramSpecArgList = [];
|
6536
6666
|
paramSpecTarget = types_1.TypeVarType.cloneForParamSpecAccess(varArgListParam.type, /* access */ undefined);
|
6537
6667
|
}
|
@@ -6540,6 +6670,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6540
6670
|
}
|
6541
6671
|
}
|
6542
6672
|
}
|
6673
|
+
else if (typeResult.type.details.paramSpec) {
|
6674
|
+
const paramSpecScopeId = typeResult.type.details.paramSpec.scopeId;
|
6675
|
+
if (paramSpecScopeId === typeResult.type.details.typeVarScopeId ||
|
6676
|
+
paramSpecScopeId === typeResult.type.details.constructorTypeVarScopeId) {
|
6677
|
+
hasParamSpecArgsKwargs = true;
|
6678
|
+
paramSpecArgList = [];
|
6679
|
+
paramSpecTarget = types_1.TypeVarType.cloneForParamSpecAccess(typeResult.type.details.paramSpec,
|
6680
|
+
/* access */ undefined);
|
6681
|
+
}
|
6682
|
+
}
|
6543
6683
|
// If there are keyword arguments present after a *args argument,
|
6544
6684
|
// the keyword arguments may target one or more parameters that are positional.
|
6545
6685
|
// In this case, we will limit the number of positional parameters so the
|
@@ -7028,27 +7168,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7028
7168
|
trySetActive(argList[argIndex], paramDetails.params[paramInfoIndex].param);
|
7029
7169
|
}
|
7030
7170
|
}
|
7171
|
+
else if (paramSpecArgList) {
|
7172
|
+
paramSpecArgList.push(argList[argIndex]);
|
7173
|
+
}
|
7031
7174
|
else if (paramDetails.kwargsIndex !== undefined) {
|
7032
|
-
|
7033
|
-
|
7034
|
-
|
7035
|
-
|
7036
|
-
|
7037
|
-
|
7038
|
-
|
7039
|
-
|
7040
|
-
|
7041
|
-
|
7042
|
-
|
7043
|
-
|
7044
|
-
|
7045
|
-
|
7046
|
-
|
7047
|
-
argsNeeded: 1,
|
7048
|
-
argsReceived: 1,
|
7049
|
-
isPositionalOnly: false,
|
7050
|
-
});
|
7051
|
-
}
|
7175
|
+
const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
|
7176
|
+
validateArgTypeParams.push({
|
7177
|
+
paramCategory: 2 /* KwargsDict */,
|
7178
|
+
paramType,
|
7179
|
+
requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
|
7180
|
+
argument: argList[argIndex],
|
7181
|
+
errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
|
7182
|
+
paramName: paramNameValue,
|
7183
|
+
});
|
7184
|
+
// Remember that this parameter has already received a value.
|
7185
|
+
paramMap.set(paramNameValue, {
|
7186
|
+
argsNeeded: 1,
|
7187
|
+
argsReceived: 1,
|
7188
|
+
isPositionalOnly: false,
|
7189
|
+
});
|
7052
7190
|
(0, debug_1.assert)(paramDetails.params[paramDetails.kwargsIndex], 'paramDetails.kwargsIndex params entry is undefined');
|
7053
7191
|
trySetActive(argList[argIndex], paramDetails.params[paramDetails.kwargsIndex].param);
|
7054
7192
|
}
|
@@ -7058,15 +7196,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7058
7196
|
}
|
7059
7197
|
}
|
7060
7198
|
else if (argList[argIndex].argumentCategory === 0 /* Simple */) {
|
7061
|
-
if (
|
7062
|
-
|
7063
|
-
|
7064
|
-
|
7065
|
-
|
7066
|
-
|
7067
|
-
|
7199
|
+
if (paramSpecArgList) {
|
7200
|
+
paramSpecArgList.push(argList[argIndex]);
|
7201
|
+
}
|
7202
|
+
else {
|
7203
|
+
if (!isDiagnosticSuppressedForNode(errorNode)) {
|
7204
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
7205
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, positionParamLimitIndex === 1
|
7206
|
+
? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
|
7207
|
+
: localize_1.Localizer.Diagnostic.argPositionalExpectedCount().format({
|
7208
|
+
expected: positionParamLimitIndex,
|
7209
|
+
}), argList[argIndex].valueExpression || errorNode);
|
7210
|
+
}
|
7211
|
+
reportedArgError = true;
|
7068
7212
|
}
|
7069
|
-
reportedArgError = true;
|
7070
7213
|
}
|
7071
7214
|
else if (argList[argIndex].argumentCategory === 1 /* UnpackedList */) {
|
7072
7215
|
// Handle the case where a *args: P.args is passed as an argument to
|
@@ -7270,6 +7413,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7270
7413
|
paramSpecArgList,
|
7271
7414
|
activeParam,
|
7272
7415
|
relevance,
|
7416
|
+
argumentMatchScore: 0,
|
7273
7417
|
};
|
7274
7418
|
}
|
7275
7419
|
// After having matched arguments with parameters, this function evaluates the
|
@@ -7345,7 +7489,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7345
7489
|
const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
|
7346
7490
|
/* typeArguments */ undefined,
|
7347
7491
|
/* isTypeArgumentExplicit */ false);
|
7348
|
-
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext
|
7492
|
+
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext, {
|
7493
|
+
unknownIfNotFound: true,
|
7494
|
+
});
|
7349
7495
|
}
|
7350
7496
|
}
|
7351
7497
|
else if ((0, types_1.isFunction)(effectiveReturnType)) {
|
@@ -7368,6 +7514,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7368
7514
|
const type = matchResults.overload;
|
7369
7515
|
let isTypeIncomplete = matchResults.isTypeIncomplete;
|
7370
7516
|
let argumentErrors = false;
|
7517
|
+
let argumentMatchScore = 0;
|
7371
7518
|
let specializedInitSelfType;
|
7372
7519
|
let anyOrUnknownArgument;
|
7373
7520
|
const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
|
@@ -7469,7 +7616,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7469
7616
|
let sawParamSpecKwargs = false;
|
7470
7617
|
let condition = [];
|
7471
7618
|
const argResults = [];
|
7472
|
-
matchResults.argParams.forEach((argParam) => {
|
7619
|
+
matchResults.argParams.forEach((argParam, argParamIndex) => {
|
7473
7620
|
var _a;
|
7474
7621
|
const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
|
7475
7622
|
skipUnknownArgCheck,
|
@@ -7478,6 +7625,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7478
7625
|
argResults.push(argResult);
|
7479
7626
|
if (!argResult.isCompatible) {
|
7480
7627
|
argumentErrors = true;
|
7628
|
+
// Add the inverse index so earlier parameters represent larger errors.
|
7629
|
+
// This will help the heuristics in the overload error paths to pick the
|
7630
|
+
// most likely intended overload if none of them match.
|
7631
|
+
argumentMatchScore += 1 + (matchResults.argParams.length - argParamIndex);
|
7481
7632
|
}
|
7482
7633
|
if (argResult.isTypeIncomplete) {
|
7483
7634
|
isTypeIncomplete = true;
|
@@ -7507,6 +7658,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7507
7658
|
if (matchResults.paramSpecArgList && matchResults.paramSpecTarget) {
|
7508
7659
|
if (!validateFunctionArgumentsForParamSpec(errorNode, matchResults.paramSpecArgList, matchResults.paramSpecTarget, typeVarContext, typeCondition)) {
|
7509
7660
|
argumentErrors = true;
|
7661
|
+
argumentMatchScore += 1;
|
7510
7662
|
}
|
7511
7663
|
}
|
7512
7664
|
else if (type.details.paramSpec) {
|
@@ -7515,6 +7667,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7515
7667
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecArgsMissing().format({ type: printType(type.details.paramSpec) }), errorNode);
|
7516
7668
|
}
|
7517
7669
|
argumentErrors = true;
|
7670
|
+
argumentMatchScore += 1;
|
7518
7671
|
}
|
7519
7672
|
}
|
7520
7673
|
// Calculate the return type.
|
@@ -7596,6 +7749,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7596
7749
|
if (specializedInitSelfType) {
|
7597
7750
|
specializedInitSelfType = (0, typeUtils_1.applySolvedTypeVars)(specializedInitSelfType, typeVarContext);
|
7598
7751
|
}
|
7752
|
+
matchResults.argumentMatchScore = argumentMatchScore;
|
7599
7753
|
return {
|
7600
7754
|
argumentErrors,
|
7601
7755
|
argResults,
|
@@ -7640,7 +7794,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7640
7794
|
// specific use case. We may need to make this more sophisticated in
|
7641
7795
|
// the future.
|
7642
7796
|
if ((0, types_1.isFunction)(returnType) && !returnType.details.name) {
|
7643
|
-
|
7797
|
+
const typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgumentsRecursive)(returnType);
|
7798
|
+
// If there are no unsolved type variables, we're done. If there are
|
7799
|
+
// unsolved type parameters, treat them as though they are rescoped
|
7800
|
+
// to the callable.
|
7801
|
+
if (typeVarsInReturnType.length > 0) {
|
7802
|
+
return types_1.FunctionType.cloneWithNewTypeVarScopeId(returnType, types_1.WildcardTypeVarScopeId, typeVarsInReturnType);
|
7803
|
+
}
|
7644
7804
|
}
|
7645
7805
|
return returnType;
|
7646
7806
|
}
|
@@ -7700,7 +7860,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7700
7860
|
return false;
|
7701
7861
|
}
|
7702
7862
|
const liveTypeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
|
7703
|
-
const srcTypeVarContext = new typeVarContext_1.TypeVarContext(
|
7863
|
+
const srcTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(paramSpecType));
|
7704
7864
|
let reportedArgError = false;
|
7705
7865
|
// Build a map of all named parameters.
|
7706
7866
|
const paramMap = new Map();
|
@@ -8663,7 +8823,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8663
8823
|
}
|
8664
8824
|
return returnType;
|
8665
8825
|
}
|
8666
|
-
function getTypeOfDictionary(node, inferenceContext) {
|
8826
|
+
function getTypeOfDictionary(node, flags, inferenceContext) {
|
8827
|
+
var _a;
|
8828
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
|
8829
|
+
((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 1 /* Argument */) {
|
8830
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
8831
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useDictInstead());
|
8832
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dictInAnnotation() + diag.getString(), node);
|
8833
|
+
}
|
8667
8834
|
// If the expected type is a union, analyze for each of the subtypes
|
8668
8835
|
// to find one that matches.
|
8669
8836
|
let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
|
@@ -8751,9 +8918,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8751
8918
|
// Dict and MutableMapping types have invariant value types, so they
|
8752
8919
|
// cannot be narrowed further. Other super-types like Mapping, Collection,
|
8753
8920
|
// and Iterable use covariant value types, so they can be narrowed.
|
8754
|
-
|
8755
|
-
|
8756
|
-
|
8921
|
+
let isValueTypeInvariant = false;
|
8922
|
+
if ((0, types_1.isClassInstance)(inferenceContext.expectedType)) {
|
8923
|
+
if (inferenceContext.expectedType.details.typeParameters.length >= 2) {
|
8924
|
+
const valueTypeParam = inferenceContext.expectedType.details.typeParameters[1];
|
8925
|
+
if (types_1.TypeVarType.getVariance(valueTypeParam) === 2 /* Invariant */) {
|
8926
|
+
isValueTypeInvariant = true;
|
8927
|
+
}
|
8928
|
+
}
|
8929
|
+
}
|
8757
8930
|
// Infer the key and value types if possible.
|
8758
8931
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8759
8932
|
/* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
@@ -8823,7 +8996,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8823
8996
|
let isIncomplete = false;
|
8824
8997
|
// Infer the key and value types if possible.
|
8825
8998
|
node.entries.forEach((entryNode, index) => {
|
8826
|
-
var _a
|
8999
|
+
var _a;
|
8827
9000
|
let addUnknown = true;
|
8828
9001
|
if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
|
8829
9002
|
const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
|
@@ -8857,8 +9030,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8857
9030
|
/* flags */ undefined, entryInferenceContext);
|
8858
9031
|
}
|
8859
9032
|
if (entryInferenceContext && !valueTypeResult.typeErrors) {
|
8860
|
-
valueTypeResult.type
|
8861
|
-
|
9033
|
+
const fromExpectedType = inferTypeArgFromExpectedEntryType(entryInferenceContext, [valueTypeResult.type], !isValueTypeInvariant);
|
9034
|
+
if (fromExpectedType) {
|
9035
|
+
valueTypeResult = { ...valueTypeResult, type: fromExpectedType };
|
9036
|
+
}
|
8862
9037
|
}
|
8863
9038
|
if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
|
8864
9039
|
expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
|
@@ -8882,11 +9057,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8882
9057
|
}
|
8883
9058
|
}
|
8884
9059
|
const entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(expectedType);
|
8885
|
-
|
9060
|
+
let unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
|
8886
9061
|
/* flags */ undefined, entryInferenceContext);
|
8887
9062
|
if (entryInferenceContext && !unexpandedTypeResult.typeErrors) {
|
8888
|
-
unexpandedTypeResult.type
|
8889
|
-
|
9063
|
+
const fromExpectedType = inferTypeArgFromExpectedEntryType(entryInferenceContext, [unexpandedTypeResult.type], !isValueTypeInvariant);
|
9064
|
+
if (fromExpectedType) {
|
9065
|
+
unexpandedTypeResult = { ...unexpandedTypeResult, type: fromExpectedType };
|
9066
|
+
}
|
8890
9067
|
}
|
8891
9068
|
if (unexpandedTypeResult.isIncomplete) {
|
8892
9069
|
isIncomplete = true;
|
@@ -8942,7 +9119,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8942
9119
|
}
|
8943
9120
|
// The result should be a tuple.
|
8944
9121
|
if ((0, types_1.isClassInstance)(dictEntryType) && (0, typeUtils_1.isTupleClass)(dictEntryType)) {
|
8945
|
-
const typeArgs = (
|
9122
|
+
const typeArgs = (_a = dictEntryType.tupleTypeArguments) === null || _a === void 0 ? void 0 : _a.map((t) => t.type);
|
8946
9123
|
if (typeArgs && typeArgs.length === 2) {
|
8947
9124
|
if (forceStrictInference || index < maxEntriesToUseForInference) {
|
8948
9125
|
keyTypes.push({ node: entryNode, type: typeArgs[0] });
|
@@ -8961,7 +9138,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8961
9138
|
});
|
8962
9139
|
return isIncomplete;
|
8963
9140
|
}
|
8964
|
-
function getTypeOfListOrSet(node, inferenceContext) {
|
9141
|
+
function getTypeOfListOrSet(node, flags, inferenceContext) {
|
9142
|
+
var _a;
|
9143
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
|
9144
|
+
node.nodeType === 31 /* List */ &&
|
9145
|
+
((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 1 /* Argument */) {
|
9146
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
9147
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useListInstead());
|
9148
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.listInAnnotation() + diag.getString(), node);
|
9149
|
+
}
|
8965
9150
|
// If the expected type is a union, recursively call for each of the subtypes
|
8966
9151
|
// to find one that matches.
|
8967
9152
|
let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
|
@@ -9339,7 +9524,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9339
9524
|
if (returnTypeResult.isIncomplete) {
|
9340
9525
|
isIncomplete = true;
|
9341
9526
|
}
|
9342
|
-
},
|
9527
|
+
}, {
|
9528
|
+
dependentType: inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType,
|
9529
|
+
});
|
9343
9530
|
// Mark the function type as no longer being evaluated.
|
9344
9531
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
9345
9532
|
return { type: functionType, isIncomplete };
|
@@ -9565,13 +9752,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9565
9752
|
}
|
9566
9753
|
return true;
|
9567
9754
|
}
|
9568
|
-
//
|
9569
|
-
//
|
9570
|
-
//
|
9571
|
-
// present, should specify the return type.
|
9755
|
+
// Evaluates the type arguments for a Callable type. It should have zero
|
9756
|
+
// to two arguments.The first argument, if present, should be an ellipsis,
|
9757
|
+
// a ParamSpec, a Concatenate, or a list of positional parameter types.
|
9758
|
+
// The second argument, if present, should specify the return type.
|
9572
9759
|
function createCallableType(typeArgs, errorNode) {
|
9573
|
-
// Create a new function that is marked as "static" so there is later
|
9574
|
-
// no attempt to bind it as though it's an instance or class method.
|
9575
9760
|
const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
|
9576
9761
|
types_1.TypeBase.setSpecialForm(functionType);
|
9577
9762
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
@@ -10265,12 +10450,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10265
10450
|
// Determine if there are any generic type parameters associated
|
10266
10451
|
// with this type alias.
|
10267
10452
|
typeParameters = [];
|
10268
|
-
|
10269
|
-
|
10270
|
-
|
10271
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10272
|
-
});
|
10273
|
-
}
|
10453
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
10454
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10455
|
+
});
|
10274
10456
|
// Don't include any synthesized type variables.
|
10275
10457
|
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
10276
10458
|
}
|
@@ -10804,10 +10986,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10804
10986
|
// If the base class is partially evaluated, install a callback
|
10805
10987
|
// so we can fix up this class (e.g. compute the MRO) when the
|
10806
10988
|
// dependent class is completed.
|
10807
|
-
|
10808
|
-
dependency: argType,
|
10809
|
-
callback: () => completeClassTypeDeferred(classType, node, node.name),
|
10810
|
-
});
|
10989
|
+
registerDeferredClassCompletion(node, argType);
|
10811
10990
|
}
|
10812
10991
|
if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
|
10813
10992
|
if (!fileInfo.isStubFile &&
|
@@ -11123,8 +11302,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11123
11302
|
(0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
|
11124
11303
|
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
|
11125
11304
|
}
|
11126
|
-
// Run any class
|
11127
|
-
|
11305
|
+
// Run any deferred class completions that depend on this class.
|
11306
|
+
runDeferredClassCompletions(classType);
|
11307
|
+
// If there are any outstanding deferred class completions registered that
|
11308
|
+
// were not removed by the call to runDeferredClassCompletions, assume that
|
11309
|
+
// the current class may depend on them and register for deferred completion.
|
11310
|
+
registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
|
11128
11311
|
// Synthesize TypedDict methods.
|
11129
11312
|
if (types_1.ClassType.isTypedDictClass(classType)) {
|
11130
11313
|
(0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
|
@@ -11357,21 +11540,47 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11357
11540
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarsNotInGenericOrProtocol() + diag.getString(), errorNode);
|
11358
11541
|
}
|
11359
11542
|
}
|
11360
|
-
//
|
11361
|
-
//
|
11362
|
-
//
|
11363
|
-
|
11364
|
-
|
11365
|
-
|
11366
|
-
|
11543
|
+
// Records the fact that the specified class requires "deferred completion" because
|
11544
|
+
// one of its base classes has not yet been fully evaluated. If the caller passes
|
11545
|
+
// undefined for "dependsUpon", then the class is added to all outstanding deferred
|
11546
|
+
// completions.
|
11547
|
+
function registerDeferredClassCompletion(classToComplete, dependsUpon) {
|
11548
|
+
if (dependsUpon) {
|
11549
|
+
// See if there is an existing entry for this dependency.
|
11550
|
+
const entry = deferredClassCompletions.find((e) => types_1.ClassType.isSameGenericClass(e.dependsUpon, dependsUpon));
|
11551
|
+
if (entry) {
|
11552
|
+
entry.classesToComplete.push(classToComplete);
|
11553
|
+
}
|
11554
|
+
else {
|
11555
|
+
deferredClassCompletions.push({ dependsUpon, classesToComplete: [classToComplete] });
|
11556
|
+
}
|
11557
|
+
}
|
11558
|
+
else {
|
11559
|
+
deferredClassCompletions.forEach((e) => {
|
11560
|
+
e.classesToComplete.push(classToComplete);
|
11561
|
+
});
|
11562
|
+
}
|
11563
|
+
}
|
11564
|
+
// Runs any registered "deferred class completions" that depend on the specified
|
11565
|
+
// class type. This allows us to complete any work that requires dependent classes
|
11566
|
+
// to be completed.
|
11567
|
+
function runDeferredClassCompletions(type) {
|
11568
|
+
deferredClassCompletions.forEach((e) => {
|
11569
|
+
if (types_1.ClassType.isSameGenericClass(e.dependsUpon, type)) {
|
11570
|
+
e.classesToComplete.forEach((classNode) => {
|
11571
|
+
const classType = readTypeCache(classNode.name, 0 /* None */);
|
11572
|
+
if (classType) {
|
11573
|
+
completeClassTypeDeferred(classType, classNode.name);
|
11574
|
+
}
|
11575
|
+
});
|
11367
11576
|
}
|
11368
11577
|
});
|
11369
|
-
// Remove any
|
11370
|
-
|
11578
|
+
// Remove any completions that depend on this type.
|
11579
|
+
deferredClassCompletions = deferredClassCompletions.filter((e) => !types_1.ClassType.isSameGenericClass(e.dependsUpon, type));
|
11371
11580
|
}
|
11372
11581
|
// Recomputes the MRO and effective metaclass for the class after dependent
|
11373
11582
|
// classes have been fully constructed.
|
11374
|
-
function completeClassTypeDeferred(type,
|
11583
|
+
function completeClassTypeDeferred(type, errorNode) {
|
11375
11584
|
// Recompute the MRO linearization.
|
11376
11585
|
if (!(0, typeUtils_1.computeMroLinearization)(type)) {
|
11377
11586
|
addError(localize_1.Localizer.Diagnostic.methodOrdering(), errorNode);
|
@@ -12039,6 +12248,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12039
12248
|
}
|
12040
12249
|
// Note that the inferred type, once lazily computed, needs to wrap the
|
12041
12250
|
// resulting type in an awaitable.
|
12251
|
+
functionType.details.flags |= 1024 /* WrapReturnTypeInAwait */;
|
12042
12252
|
awaitableFunctionType.details.flags |= 1024 /* WrapReturnTypeInAwait */;
|
12043
12253
|
return awaitableFunctionType;
|
12044
12254
|
}
|
@@ -12525,18 +12735,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12525
12735
|
/* isPositiveTest */ false);
|
12526
12736
|
}
|
12527
12737
|
}
|
12528
|
-
|
12529
|
-
|
12530
|
-
(0, typeUtils_1.doForEachSubtype)(makeTopLevelTypeVarsConcrete(subjectType), (subtype) => {
|
12531
|
-
if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'object')) {
|
12532
|
-
subjectIsObject = true;
|
12533
|
-
}
|
12534
|
-
});
|
12535
|
-
// Apply positive narrowing for the current case statement.
|
12536
|
-
subjectType = (0, patternMatching_1.narrowTypeBasedOnPattern)(evaluatorInterface, subjectType, node.pattern,
|
12537
|
-
/* isPositiveTest */ true);
|
12538
|
-
(0, patternMatching_1.assignTypeToPatternTargets)(evaluatorInterface, subjectType, !!subjectTypeResult.isIncomplete, subjectIsObject, node.pattern);
|
12539
|
-
writeTypeCache(node, { type: subjectType, isIncomplete: !!subjectTypeResult.isIncomplete }, 0 /* None */);
|
12738
|
+
const narrowedSubjectType = (0, patternMatching_1.assignTypeToPatternTargets)(evaluatorInterface, subjectType, !!subjectTypeResult.isIncomplete, node.pattern);
|
12739
|
+
writeTypeCache(node, { type: narrowedSubjectType, isIncomplete: !!subjectTypeResult.isIncomplete }, 0 /* None */);
|
12540
12740
|
}
|
12541
12741
|
function evaluateTypesForImportFrom(node) {
|
12542
12742
|
if (isTypeCached(node)) {
|
@@ -13205,10 +13405,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13205
13405
|
// Handle "type" specially, since it needs to act like "Type"
|
13206
13406
|
// in Python 3.9 and newer.
|
13207
13407
|
if (types_1.ClassType.isBuiltIn(classType, 'type') && typeArgs) {
|
13208
|
-
|
13209
|
-
|
13210
|
-
|
13211
|
-
|
13408
|
+
if (typeArgs.length >= 1) {
|
13409
|
+
// PEP 484 says that type[Any] should be considered
|
13410
|
+
// equivalent to type.
|
13411
|
+
if ((0, types_1.isAnyOrUnknown)(typeArgs[0].type)) {
|
13412
|
+
return { type: classType };
|
13413
|
+
}
|
13414
|
+
// Treat type[function] as illegal.
|
13415
|
+
if ((0, types_1.isFunction)(typeArgs[0].type) || (0, types_1.isOverloadedFunction)(typeArgs[0].type)) {
|
13416
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationWithCallable(), typeArgs[0].node);
|
13417
|
+
return { type: types_1.UnknownType.create() };
|
13418
|
+
}
|
13212
13419
|
}
|
13213
13420
|
const typeClass = getTypingType(errorNode, 'Type');
|
13214
13421
|
if (typeClass && (0, types_1.isInstantiableClass)(typeClass)) {
|
@@ -13460,13 +13667,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13460
13667
|
// used in cases where the argument is expected to be a type
|
13461
13668
|
// and therefore follows the normal rules of types (e.g. they
|
13462
13669
|
// can be forward-declared in stubs, etc.).
|
13463
|
-
function getTypeOfArgumentExpectingType(arg) {
|
13670
|
+
function getTypeOfArgumentExpectingType(arg, options) {
|
13464
13671
|
if (arg.typeResult) {
|
13465
13672
|
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
13466
13673
|
}
|
13467
13674
|
// If there was no defined type provided, there should always
|
13468
13675
|
// be a value expression from which we can retrieve the type.
|
13469
|
-
return getTypeOfExpressionExpectingType(arg.valueExpression);
|
13676
|
+
return getTypeOfExpressionExpectingType(arg.valueExpression, options);
|
13470
13677
|
}
|
13471
13678
|
function getTypeOfExpressionExpectingType(node, options) {
|
13472
13679
|
let flags = 128 /* ExpectingInstantiableType */ |
|
@@ -13497,6 +13704,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13497
13704
|
if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
|
13498
13705
|
flags |= 32 /* DisallowParamSpec */;
|
13499
13706
|
}
|
13707
|
+
if (options === null || options === void 0 ? void 0 : options.enforceTypeAnnotationRules) {
|
13708
|
+
flags |= 256 /* ExpectingTypeAnnotation */;
|
13709
|
+
}
|
13500
13710
|
return getTypeOfExpression(node, flags);
|
13501
13711
|
}
|
13502
13712
|
function getBuiltInType(node, name) {
|
@@ -13627,11 +13837,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13627
13837
|
// types, under the assumption that we're performing speculative evaluations.
|
13628
13838
|
// If speculativeNode is undefined, speculative mode is not used. This is
|
13629
13839
|
// useful in cases where we conditionally want to use speculative mode.
|
13630
|
-
function useSpeculativeMode(speculativeNode, callback,
|
13840
|
+
function useSpeculativeMode(speculativeNode, callback, options) {
|
13631
13841
|
if (!speculativeNode) {
|
13632
13842
|
return callback();
|
13633
13843
|
}
|
13634
|
-
speculativeTypeTracker.enterSpeculativeContext(speculativeNode,
|
13844
|
+
speculativeTypeTracker.enterSpeculativeContext(speculativeNode, options);
|
13635
13845
|
try {
|
13636
13846
|
const result = callback();
|
13637
13847
|
speculativeTypeTracker.leaveSpeculativeContext();
|
@@ -14601,6 +14811,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14601
14811
|
}
|
14602
14812
|
let typedDecls = symbol.getTypedDeclarations();
|
14603
14813
|
if (typedDecls.length === 0) {
|
14814
|
+
// If the symbol has no type declaration but is assigned many times,
|
14815
|
+
// treat it as though it has an explicit type annotation of "Unknown".
|
14816
|
+
// This will avoid a pathological performance condition for unannotated
|
14817
|
+
// code that reassigns the same variable hundreds of times. If the symbol
|
14818
|
+
// effectively has an "Any" annotation, it won't be narrowed.
|
14819
|
+
if (symbol.getDeclarations().length > maxDeclarationsToUseForInference) {
|
14820
|
+
return { type: types_1.UnknownType.create() };
|
14821
|
+
}
|
14604
14822
|
// There was no declaration with a defined type.
|
14605
14823
|
return { type: undefined };
|
14606
14824
|
}
|
@@ -15080,6 +15298,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15080
15298
|
}
|
15081
15299
|
}
|
15082
15300
|
});
|
15301
|
+
if (!isAssignable) {
|
15302
|
+
return false;
|
15303
|
+
}
|
15083
15304
|
// Now handle generic base classes.
|
15084
15305
|
destType.details.baseClasses.forEach((baseClass) => {
|
15085
15306
|
if ((0, types_1.isInstantiableClass)(baseClass) &&
|
@@ -15325,63 +15546,50 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15325
15546
|
srcTypeArgs = srcType.typeArguments;
|
15326
15547
|
}
|
15327
15548
|
let isCompatible = true;
|
15328
|
-
|
15329
|
-
|
15330
|
-
|
15331
|
-
|
15332
|
-
|
15333
|
-
|
15334
|
-
|
15335
|
-
|
15336
|
-
|
15337
|
-
|
15338
|
-
|
15339
|
-
|
15340
|
-
|
15341
|
-
|
15342
|
-
|
15343
|
-
|
15344
|
-
|
15345
|
-
|
15346
|
-
|
15347
|
-
|
15348
|
-
|
15349
|
-
|
15350
|
-
|
15351
|
-
|
15352
|
-
|
15353
|
-
|
15354
|
-
|
15355
|
-
|
15356
|
-
if (
|
15357
|
-
if (
|
15549
|
+
srcTypeArgs === null || srcTypeArgs === void 0 ? void 0 : srcTypeArgs.forEach((srcTypeArg, srcArgIndex) => {
|
15550
|
+
// In most cases, the number of type args should match the number
|
15551
|
+
// of type arguments, but there are a few special cases where this
|
15552
|
+
// isn't true (e.g. assigning a Tuple[X, Y, Z] to a tuple[W]).
|
15553
|
+
const destArgIndex = srcArgIndex >= destTypeArgs.length ? destTypeArgs.length - 1 : srcArgIndex;
|
15554
|
+
const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
|
15555
|
+
const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
|
15556
|
+
const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
|
15557
|
+
const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
|
15558
|
+
let effectiveFlags;
|
15559
|
+
let errorSource;
|
15560
|
+
if (variance === 3 /* Covariant */) {
|
15561
|
+
effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
|
15562
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
|
15563
|
+
}
|
15564
|
+
else if (variance === 4 /* Contravariant */) {
|
15565
|
+
effectiveFlags =
|
15566
|
+
(flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */;
|
15567
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant;
|
15568
|
+
}
|
15569
|
+
else {
|
15570
|
+
effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
|
15571
|
+
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
|
15572
|
+
}
|
15573
|
+
if (!assignType(variance === 4 /* Contravariant */ ? srcTypeArg : destTypeArg, variance === 4 /* Contravariant */ ? destTypeArg : srcTypeArg, assignmentDiag, variance === 4 /* Contravariant */ ? srcTypeVarContext : destTypeVarContext, variance === 4 /* Contravariant */ ? destTypeVarContext : srcTypeVarContext, effectiveFlags, recursionCount)) {
|
15574
|
+
// Don't report errors with type variables in "pseudo-random"
|
15575
|
+
// classes since these type variables are not real.
|
15576
|
+
if (!types_1.ClassType.isPseudoGenericClass(destType)) {
|
15577
|
+
if (diag) {
|
15578
|
+
if (destTypeParam) {
|
15358
15579
|
const childDiag = diag.createAddendum();
|
15359
|
-
childDiag.addMessage(
|
15580
|
+
childDiag.addMessage(errorSource().format({
|
15360
15581
|
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15582
|
+
...printSrcDestTypes(srcTypeArg, destTypeArg),
|
15361
15583
|
}));
|
15362
|
-
childDiag.addAddendum(assignmentDiag);
|
15363
15584
|
}
|
15364
|
-
|
15365
|
-
|
15366
|
-
}
|
15367
|
-
else {
|
15368
|
-
if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
15369
|
-
// Don't report errors with type variables in "pseudo-random"
|
15370
|
-
// classes since these type variables are not real.
|
15371
|
-
if (!types_1.ClassType.isPseudoGenericClass(destType)) {
|
15372
|
-
if (diag) {
|
15373
|
-
const childDiag = diag.createAddendum();
|
15374
|
-
childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant().format({
|
15375
|
-
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15376
|
-
}));
|
15377
|
-
childDiag.addAddendum(assignmentDiag);
|
15378
|
-
}
|
15379
|
-
isCompatible = false;
|
15585
|
+
else {
|
15586
|
+
diag.addAddendum(assignmentDiag);
|
15380
15587
|
}
|
15381
15588
|
}
|
15589
|
+
isCompatible = false;
|
15382
15590
|
}
|
15383
15591
|
}
|
15384
|
-
}
|
15592
|
+
});
|
15385
15593
|
return isCompatible;
|
15386
15594
|
}
|
15387
15595
|
// Determines if the source type can be assigned to the dest type.
|
@@ -15571,11 +15779,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15571
15779
|
destType.details.parameters.length <= 2) {
|
15572
15780
|
return true;
|
15573
15781
|
}
|
15574
|
-
|
15575
|
-
|
15576
|
-
|
15577
|
-
}
|
15578
|
-
return false;
|
15782
|
+
if (!(0, types_1.isUnion)(destType)) {
|
15783
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
15784
|
+
return false;
|
15785
|
+
}
|
15579
15786
|
}
|
15580
15787
|
}
|
15581
15788
|
if ((0, types_1.isAnyOrUnknown)(destType)) {
|
@@ -15605,25 +15812,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15605
15812
|
return true;
|
15606
15813
|
}
|
15607
15814
|
if ((0, types_1.isUnion)(destType)) {
|
15815
|
+
// If both the source and dest are unions, use assignFromUnionType which has
|
15816
|
+
// special-case logic to handle this case.
|
15608
15817
|
if ((0, types_1.isUnion)(srcType)) {
|
15609
|
-
|
15610
|
-
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount)
|
15611
|
-
return true;
|
15612
|
-
}
|
15818
|
+
return assignFromUnionType(destType, srcType,
|
15819
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount);
|
15613
15820
|
}
|
15614
|
-
|
15615
|
-
|
15616
|
-
|
15617
|
-
|
15618
|
-
|
15619
|
-
|
15620
|
-
|
15621
|
-
|
15622
|
-
|
15623
|
-
srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
|
15624
|
-
}
|
15625
|
-
return true;
|
15821
|
+
const clonedDestTypeVarContext = destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone();
|
15822
|
+
const clonedSrcTypeVarContext = srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone();
|
15823
|
+
if (assignToUnionType(destType, srcType,
|
15824
|
+
/* diag */ undefined, clonedDestTypeVarContext, clonedSrcTypeVarContext, originalFlags, recursionCount)) {
|
15825
|
+
if (destTypeVarContext && clonedDestTypeVarContext) {
|
15826
|
+
destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
|
15827
|
+
}
|
15828
|
+
if (srcTypeVarContext && clonedSrcTypeVarContext) {
|
15829
|
+
srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
|
15626
15830
|
}
|
15831
|
+
return true;
|
15627
15832
|
}
|
15628
15833
|
}
|
15629
15834
|
const expandedSrcType = makeTopLevelTypeVarsConcrete(srcType);
|
@@ -15673,10 +15878,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15673
15878
|
if (assignType(destType, instantiableType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
15674
15879
|
return true;
|
15675
15880
|
}
|
15676
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(
|
15677
|
-
sourceType: printType(srcType),
|
15678
|
-
destType: printType(destType),
|
15679
|
-
}));
|
15881
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
15680
15882
|
return false;
|
15681
15883
|
}
|
15682
15884
|
}
|
@@ -15700,10 +15902,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15700
15902
|
/* reportErrorsUsingObjType */ false)) {
|
15701
15903
|
return true;
|
15702
15904
|
}
|
15703
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(
|
15704
|
-
sourceType: printType(srcType),
|
15705
|
-
destType: printType(destType),
|
15706
|
-
}));
|
15905
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
15707
15906
|
return false;
|
15708
15907
|
}
|
15709
15908
|
}
|
@@ -15933,10 +16132,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15933
16132
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.assignToNone());
|
15934
16133
|
return false;
|
15935
16134
|
}
|
15936
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(
|
15937
|
-
sourceType: printType(srcType),
|
15938
|
-
destType: printType(destType),
|
15939
|
-
}));
|
16135
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
15940
16136
|
return false;
|
15941
16137
|
}
|
15942
16138
|
function assignFromUnionType(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
|
@@ -15983,6 +16179,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15983
16179
|
// whose primary type matches.
|
15984
16180
|
remainingSrcSubtypes.forEach((srcSubtype) => {
|
15985
16181
|
const destTypeIndex = remainingDestSubtypes.findIndex((destSubtype) => {
|
16182
|
+
if ((0, types_1.isTypeSame)(destSubtype, srcSubtype)) {
|
16183
|
+
return true;
|
16184
|
+
}
|
15986
16185
|
if ((0, types_1.isClass)(srcSubtype) &&
|
15987
16186
|
(0, types_1.isClass)(destSubtype) &&
|
15988
16187
|
types_1.TypeBase.isInstance(srcSubtype) === types_1.TypeBase.isInstance(destSubtype) &&
|
@@ -16007,6 +16206,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16007
16206
|
// If there is are remaining dest subtypes and they're all type variables,
|
16008
16207
|
// attempt to assign the remaining source subtypes to them.
|
16009
16208
|
if (canUseFastPath && (remainingDestSubtypes.length !== 0 || remainingSrcSubtypes.length !== 0)) {
|
16209
|
+
if ((flags & 1 /* EnforceInvariance */) !== 0) {
|
16210
|
+
// If we have no src subtypes remaining but not all dest types have been subsumed
|
16211
|
+
// by other dest types, then the types are not compatible if we're enforcing invariance.
|
16212
|
+
if (remainingSrcSubtypes.length === 0) {
|
16213
|
+
return remainingDestSubtypes.every((destSubtype) => isTypeSubsumedByOtherType(destSubtype, destType.subtypes,
|
16214
|
+
/* allowAnyToSubsume */ true, recursionCount));
|
16215
|
+
}
|
16216
|
+
}
|
16010
16217
|
const isReversed = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
|
16011
16218
|
const effectiveDestSubtypes = isReversed ? remainingSrcSubtypes : remainingDestSubtypes;
|
16012
16219
|
if (effectiveDestSubtypes.length === 0 || effectiveDestSubtypes.some((t) => !(0, types_1.isTypeVar)(t))) {
|
@@ -16058,34 +16265,42 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16058
16265
|
}
|
16059
16266
|
if (!assignType(destType, subtype,
|
16060
16267
|
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
16061
|
-
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
16062
16268
|
// Determine if the current subtype is subsumed by another subtype
|
16063
16269
|
// in the same union. If so, we can ignore this.
|
16064
|
-
|
16065
|
-
|
16066
|
-
if (!isSubtypeSubsumed &&
|
16067
|
-
!(0, types_1.isTypeSame)(innerSubtype, subtype) &&
|
16068
|
-
!(0, types_1.isAnyOrUnknown)(innerSubtype) &&
|
16069
|
-
isProperSubtype(innerSubtype, concreteSubtype, recursionCount)) {
|
16070
|
-
isSubtypeSubsumed = true;
|
16071
|
-
}
|
16072
|
-
});
|
16270
|
+
const isSubtypeSubsumed = isTypeSubsumedByOtherType(subtype, srcType.subtypes,
|
16271
|
+
/* allowAnyToSubsume */ false, recursionCount);
|
16073
16272
|
// Try again with a concrete version of the subtype.
|
16074
16273
|
if (!isSubtypeSubsumed &&
|
16075
|
-
!assignType(destType,
|
16274
|
+
!assignType(destType, subtype, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
16076
16275
|
isIncompatible = true;
|
16077
16276
|
}
|
16078
16277
|
}
|
16079
16278
|
}, /* sortSubtypes */ true);
|
16080
16279
|
if (isIncompatible) {
|
16081
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(
|
16082
|
-
sourceType: printType(srcType),
|
16083
|
-
destType: printType(destType),
|
16084
|
-
}));
|
16280
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
16085
16281
|
return false;
|
16086
16282
|
}
|
16087
16283
|
return true;
|
16088
16284
|
}
|
16285
|
+
// Determines whether a type is "subsumed by" (i.e. is a proper subtype of) one
|
16286
|
+
// of the other types in a list.
|
16287
|
+
function isTypeSubsumedByOtherType(type, otherTypes, allowAnyToSubsume, recursionCount = 0) {
|
16288
|
+
const concreteType = makeTopLevelTypeVarsConcrete(type);
|
16289
|
+
for (const otherType of otherTypes) {
|
16290
|
+
if ((0, types_1.isTypeSame)(otherType, type)) {
|
16291
|
+
continue;
|
16292
|
+
}
|
16293
|
+
if ((0, types_1.isAnyOrUnknown)(otherType)) {
|
16294
|
+
if (allowAnyToSubsume) {
|
16295
|
+
return true;
|
16296
|
+
}
|
16297
|
+
}
|
16298
|
+
else if (isProperSubtype(otherType, concreteType, recursionCount)) {
|
16299
|
+
return true;
|
16300
|
+
}
|
16301
|
+
}
|
16302
|
+
return false;
|
16303
|
+
}
|
16089
16304
|
// Determines whether the srcType is a subtype of destType but the converse
|
16090
16305
|
// is not true. It's important that we check both directions to avoid
|
16091
16306
|
// matches for types like `tuple[Any]` and `tuple[int]` from being considered
|
@@ -16146,10 +16361,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16146
16361
|
}
|
16147
16362
|
});
|
16148
16363
|
if (isIncompatible) {
|
16149
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(
|
16150
|
-
sourceType: printType(srcType),
|
16151
|
-
destType: printType(destType),
|
16152
|
-
}));
|
16364
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
16153
16365
|
return false;
|
16154
16366
|
}
|
16155
16367
|
return true;
|
@@ -16229,10 +16441,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16229
16441
|
}
|
16230
16442
|
if (!foundMatch) {
|
16231
16443
|
if (diag && diagAddendum) {
|
16232
|
-
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(
|
16233
|
-
sourceType: printType(srcType),
|
16234
|
-
destType: printType(destType),
|
16235
|
-
}));
|
16444
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
|
16236
16445
|
diag.addAddendum(diagAddendum);
|
16237
16446
|
}
|
16238
16447
|
return false;
|
@@ -17663,6 +17872,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17663
17872
|
const flags = extraFlags ? evaluatorOptions.printTypeFlags | extraFlags : evaluatorOptions.printTypeFlags;
|
17664
17873
|
return TypePrinter.printFunctionParts(type, flags, getFunctionEffectiveReturnType);
|
17665
17874
|
}
|
17875
|
+
// Prints two types and determines whether they need to be output in
|
17876
|
+
// fully-qualified form for disambiguation.
|
17877
|
+
function printSrcDestTypes(srcType, destType) {
|
17878
|
+
const simpleSrcType = printType(srcType);
|
17879
|
+
const simpleDestType = printType(destType);
|
17880
|
+
if (simpleSrcType !== simpleDestType) {
|
17881
|
+
return { sourceType: simpleSrcType, destType: simpleDestType };
|
17882
|
+
}
|
17883
|
+
const fullSrcType = printType(srcType, { useFullyQualifiedNames: true });
|
17884
|
+
const fullDestType = printType(destType, { useFullyQualifiedNames: true });
|
17885
|
+
if (fullSrcType !== fullDestType) {
|
17886
|
+
return { sourceType: fullSrcType, destType: fullDestType };
|
17887
|
+
}
|
17888
|
+
return { sourceType: simpleSrcType, destType: simpleDestType };
|
17889
|
+
}
|
17666
17890
|
function printType(type, options) {
|
17667
17891
|
let flags = evaluatorOptions.printTypeFlags;
|
17668
17892
|
if (options === null || options === void 0 ? void 0 : options.expandTypeAlias) {
|
@@ -17683,6 +17907,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17683
17907
|
if (options === null || options === void 0 ? void 0 : options.omitTypeArgumentsIfUnknown) {
|
17684
17908
|
flags |= 2 /* OmitTypeArgumentsIfUnknown */;
|
17685
17909
|
}
|
17910
|
+
if (options === null || options === void 0 ? void 0 : options.useFullyQualifiedNames) {
|
17911
|
+
flags |= 4096 /* UseFullyQualifiedNames */;
|
17912
|
+
}
|
17686
17913
|
return TypePrinter.printType(type, flags, getFunctionEffectiveReturnType);
|
17687
17914
|
}
|
17688
17915
|
// Calls back into the parser to parse the contents of a string literal.
|
@@ -17838,6 +18065,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17838
18065
|
addDiagnostic,
|
17839
18066
|
addDiagnosticForTextRange,
|
17840
18067
|
printType,
|
18068
|
+
printSrcDestTypes,
|
17841
18069
|
printFunctionParts,
|
17842
18070
|
getTypeCacheEntryCount,
|
17843
18071
|
disposeEvaluator,
|