@zzzen/pyright-internal 1.2.0-dev.20230430 → 1.2.0-dev.20230507
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 +3 -0
- package/dist/analyzer/backgroundAnalysisProgram.js +12 -0
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +52 -4
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +6 -0
- package/dist/analyzer/constructors.js +456 -0
- package/dist/analyzer/constructors.js.map +1 -0
- package/dist/analyzer/dataClasses.js +84 -0
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/enums.js +54 -8
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +2 -2
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/namedTuples.js +1 -1
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.d.ts +16 -0
- package/dist/analyzer/operations.js +749 -0
- package/dist/analyzer/operations.js.map +1 -0
- package/dist/analyzer/parseTreeUtils.d.ts +4 -2
- package/dist/analyzer/parseTreeUtils.js +32 -1
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +16 -0
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +5 -17
- package/dist/analyzer/program.js +46 -493
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -11
- package/dist/analyzer/service.js +16 -12
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +10 -33
- package/dist/analyzer/sourceFile.js +225 -181
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.d.ts +3 -9
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +100 -1285
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +38 -7
- package/dist/analyzer/typeEvaluatorTypes.js +33 -1
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +2 -8
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +2 -0
- package/dist/analyzer/typeUtils.js +33 -3
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +5 -5
- package/dist/analyzer/typeVarContext.js +7 -0
- package/dist/analyzer/typeVarContext.js.map +1 -1
- package/dist/analyzer/typedDicts.js +2 -2
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -2
- package/dist/analyzer/types.js +7 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/extensibility.d.ts +2 -1
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/pathUtils.d.ts +11 -11
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/workspaceEditUtils.d.ts +5 -5
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +1 -2
- package/dist/languageServerBase.js +8 -13
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.d.ts +1 -1
- package/dist/languageService/callHierarchyProvider.js +5 -5
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +10 -13
- package/dist/languageService/completionProvider.js +21 -10
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/documentHighlightProvider.js +1 -1
- package/dist/languageService/documentHighlightProvider.js.map +1 -1
- package/dist/languageService/documentSymbolCollector.d.ts +6 -7
- package/dist/languageService/documentSymbolCollector.js +17 -8
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +4 -3
- package/dist/languageService/hoverProvider.js +29 -35
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.d.ts +7 -12
- package/dist/languageService/referencesProvider.js +25 -17
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameProvider.d.ts +17 -0
- package/dist/languageService/renameProvider.js +143 -0
- package/dist/languageService/renameProvider.js.map +1 -0
- package/dist/localization/localize.d.ts +17 -14
- package/dist/localization/localize.js +4 -6
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +5 -6
- package/dist/tests/documentSymbolCollector.test.js +3 -3
- package/dist/tests/documentSymbolCollector.test.js.map +1 -1
- package/dist/tests/fourslash/fourslash.d.ts +4 -4
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js +1 -1
- package/dist/tests/fourslash/missingTypeStub.codeAction.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.d.ts +3 -3
- package/dist/tests/harness/fourslash/testState.js +14 -14
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/sourceFile.test.js +1 -1
- package/dist/tests/sourceFile.test.js.map +1 -1
- package/dist/tests/testStateUtils.d.ts +2 -2
- package/dist/tests/testStateUtils.js +38 -8
- package/dist/tests/testStateUtils.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +1 -1
- package/dist/tests/typeEvaluator3.test.js +1 -1
- package/dist/tests/typeEvaluator4.test.js +9 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +4 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/workspaceEditUtils.test.js +84 -0
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/package.json +4 -4
- package/dist/languageService/indentationUtils.d.ts +0 -16
- package/dist/languageService/indentationUtils.js +0 -727
- package/dist/languageService/indentationUtils.js.map +0 -1
- package/dist/languageService/insertionPointUtils.d.ts +0 -9
- package/dist/languageService/insertionPointUtils.js +0 -132
- package/dist/languageService/insertionPointUtils.js.map +0 -1
- package/dist/languageService/renameModuleProvider.d.ts +0 -65
- package/dist/languageService/renameModuleProvider.js +0 -939
- package/dist/languageService/renameModuleProvider.js.map +0 -1
- package/dist/tests/indentationUtils.ptvs.test.d.ts +0 -1
- package/dist/tests/indentationUtils.ptvs.test.js +0 -324
- package/dist/tests/indentationUtils.ptvs.test.js.map +0 -1
- package/dist/tests/indentationUtils.reindent.test.d.ts +0 -1
- package/dist/tests/indentationUtils.reindent.test.js +0 -372
- package/dist/tests/indentationUtils.reindent.test.js.map +0 -1
- package/dist/tests/indentationUtils.test.d.ts +0 -1
- package/dist/tests/indentationUtils.test.js +0 -502
- package/dist/tests/indentationUtils.test.js.map +0 -1
- package/dist/tests/insertionPointUtils.test.d.ts +0 -1
- package/dist/tests/insertionPointUtils.test.js +0 -154
- package/dist/tests/insertionPointUtils.test.js.map +0 -1
- package/dist/tests/moveSymbol.importAdder.test.d.ts +0 -1
- package/dist/tests/moveSymbol.importAdder.test.js +0 -298
- package/dist/tests/moveSymbol.importAdder.test.js.map +0 -1
- package/dist/tests/moveSymbol.insertion.test.d.ts +0 -1
- package/dist/tests/moveSymbol.insertion.test.js +0 -537
- package/dist/tests/moveSymbol.insertion.test.js.map +0 -1
- package/dist/tests/moveSymbol.misc.test.d.ts +0 -1
- package/dist/tests/moveSymbol.misc.test.js +0 -169
- package/dist/tests/moveSymbol.misc.test.js.map +0 -1
- package/dist/tests/moveSymbol.updateReference.test.d.ts +0 -1
- package/dist/tests/moveSymbol.updateReference.test.js +0 -1071
- package/dist/tests/moveSymbol.updateReference.test.js.map +0 -1
- package/dist/tests/renameModule.folder.test.d.ts +0 -1
- package/dist/tests/renameModule.folder.test.js +0 -229
- package/dist/tests/renameModule.folder.test.js.map +0 -1
- package/dist/tests/renameModule.fromImports.test.d.ts +0 -1
- package/dist/tests/renameModule.fromImports.test.js +0 -790
- package/dist/tests/renameModule.fromImports.test.js.map +0 -1
- package/dist/tests/renameModule.imports.test.d.ts +0 -1
- package/dist/tests/renameModule.imports.test.js +0 -380
- package/dist/tests/renameModule.imports.test.js.map +0 -1
- package/dist/tests/renameModule.misc.test.d.ts +0 -1
- package/dist/tests/renameModule.misc.test.js +0 -615
- package/dist/tests/renameModule.misc.test.js.map +0 -1
- package/dist/tests/renameModule.relativePath.test.d.ts +0 -1
- package/dist/tests/renameModule.relativePath.test.js +0 -231
- package/dist/tests/renameModule.relativePath.test.js.map +0 -1
- package/dist/tests/renameModuleTestUtils.d.ts +0 -4
- package/dist/tests/renameModuleTestUtils.js +0 -76
- package/dist/tests/renameModuleTestUtils.js.map +0 -1
@@ -51,12 +51,13 @@ const AnalyzerNodeInfo = __importStar(require("./analyzerNodeInfo"));
|
|
51
51
|
const codeFlowEngine_1 = require("./codeFlowEngine");
|
52
52
|
const codeFlowTypes_1 = require("./codeFlowTypes");
|
53
53
|
const constraintSolver_1 = require("./constraintSolver");
|
54
|
-
const
|
54
|
+
const constructors_1 = require("./constructors");
|
55
55
|
const dataClasses_1 = require("./dataClasses");
|
56
56
|
const declarationUtils_1 = require("./declarationUtils");
|
57
57
|
const enums_1 = require("./enums");
|
58
58
|
const functionTransform_1 = require("./functionTransform");
|
59
59
|
const namedTuples_1 = require("./namedTuples");
|
60
|
+
const operations_1 = require("./operations");
|
60
61
|
const parameterUtils_1 = require("./parameterUtils");
|
61
62
|
const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
|
62
63
|
const patternMatching_1 = require("./patternMatching");
|
@@ -68,75 +69,12 @@ const symbol_1 = require("./symbol");
|
|
68
69
|
const symbolNameUtils_1 = require("./symbolNameUtils");
|
69
70
|
const symbolUtils_1 = require("./symbolUtils");
|
70
71
|
const typeCacheUtils_1 = require("./typeCacheUtils");
|
71
|
-
const typedDicts_1 = require("./typedDicts");
|
72
72
|
const typeEvaluatorTypes_1 = require("./typeEvaluatorTypes");
|
73
73
|
const TypePrinter = __importStar(require("./typePrinter"));
|
74
|
-
const types_1 = require("./types");
|
75
74
|
const typeUtils_1 = require("./typeUtils");
|
76
75
|
const typeVarContext_1 = require("./typeVarContext");
|
77
|
-
|
78
|
-
|
79
|
-
MemberAccessFlags[MemberAccessFlags["None"] = 0] = "None";
|
80
|
-
// By default, member accesses are assumed to access the attributes
|
81
|
-
// of a class instance. By setting this flag, only attributes of
|
82
|
-
// the class are considered.
|
83
|
-
MemberAccessFlags[MemberAccessFlags["AccessClassMembersOnly"] = 1] = "AccessClassMembersOnly";
|
84
|
-
// By default, members of base classes are also searched.
|
85
|
-
// Set this flag to consider only the specified class' members.
|
86
|
-
MemberAccessFlags[MemberAccessFlags["SkipBaseClasses"] = 2] = "SkipBaseClasses";
|
87
|
-
// Do not include the "object" base class in the search.
|
88
|
-
MemberAccessFlags[MemberAccessFlags["SkipObjectBaseClass"] = 4] = "SkipObjectBaseClass";
|
89
|
-
// Consider writes to symbols flagged as ClassVars as an error.
|
90
|
-
MemberAccessFlags[MemberAccessFlags["DisallowClassVarWrites"] = 8] = "DisallowClassVarWrites";
|
91
|
-
// Normally __new__ is treated as a static method, but when
|
92
|
-
// it is invoked implicitly through a constructor call, it
|
93
|
-
// acts like a class method instead.
|
94
|
-
MemberAccessFlags[MemberAccessFlags["TreatConstructorAsClassMethod"] = 16] = "TreatConstructorAsClassMethod";
|
95
|
-
// By default, class member lookups start with the class itself
|
96
|
-
// and fall back on the metaclass if it's not found. This option
|
97
|
-
// skips the first check.
|
98
|
-
MemberAccessFlags[MemberAccessFlags["ConsiderMetaclassOnly"] = 32] = "ConsiderMetaclassOnly";
|
99
|
-
// If an attribute cannot be found when looking for instance
|
100
|
-
// members, normally an attribute access override method
|
101
|
-
// (__getattr__, etc.) may provide the missing attribute type.
|
102
|
-
// This disables this check.
|
103
|
-
MemberAccessFlags[MemberAccessFlags["SkipAttributeAccessOverride"] = 64] = "SkipAttributeAccessOverride";
|
104
|
-
// Do not include the class itself, only base classes.
|
105
|
-
MemberAccessFlags[MemberAccessFlags["SkipOriginalClass"] = 128] = "SkipOriginalClass";
|
106
|
-
// Do not include the "type" base class in the search.
|
107
|
-
MemberAccessFlags[MemberAccessFlags["SkipTypeBaseClass"] = 256] = "SkipTypeBaseClass";
|
108
|
-
})(MemberAccessFlags || (MemberAccessFlags = {}));
|
109
|
-
// Maps binary operators to the magic methods that implement them.
|
110
|
-
const binaryOperatorMap = {
|
111
|
-
[0 /* Add */]: ['__add__', '__radd__'],
|
112
|
-
[33 /* Subtract */]: ['__sub__', '__rsub__'],
|
113
|
-
[26 /* Multiply */]: ['__mul__', '__rmul__'],
|
114
|
-
[13 /* FloorDivide */]: ['__floordiv__', '__rfloordiv__'],
|
115
|
-
[10 /* Divide */]: ['__truediv__', '__rtruediv__'],
|
116
|
-
[24 /* Mod */]: ['__mod__', '__rmod__'],
|
117
|
-
[29 /* Power */]: ['__pow__', '__rpow__'],
|
118
|
-
[22 /* MatrixMultiply */]: ['__matmul__', '__rmatmul__'],
|
119
|
-
[3 /* BitwiseAnd */]: ['__and__', '__rand__'],
|
120
|
-
[6 /* BitwiseOr */]: ['__or__', '__ror__'],
|
121
|
-
[8 /* BitwiseXor */]: ['__xor__', '__rxor__'],
|
122
|
-
[17 /* LeftShift */]: ['__lshift__', '__rlshift__'],
|
123
|
-
[31 /* RightShift */]: ['__rshift__', '__rrshift__'],
|
124
|
-
[12 /* Equals */]: ['__eq__', '__eq__'],
|
125
|
-
[28 /* NotEquals */]: ['__ne__', '__ne__'],
|
126
|
-
[20 /* LessThan */]: ['__lt__', '__gt__'],
|
127
|
-
[21 /* LessThanOrEqual */]: ['__le__', '__ge__'],
|
128
|
-
[15 /* GreaterThan */]: ['__gt__', '__lt__'],
|
129
|
-
[16 /* GreaterThanOrEqual */]: ['__ge__', '__le__'],
|
130
|
-
};
|
131
|
-
// Map of operators that always return a bool result.
|
132
|
-
const booleanOperatorMap = {
|
133
|
-
[36 /* And */]: true,
|
134
|
-
[37 /* Or */]: true,
|
135
|
-
[39 /* Is */]: true,
|
136
|
-
[40 /* IsNot */]: true,
|
137
|
-
[41 /* In */]: true,
|
138
|
-
[42 /* NotIn */]: true,
|
139
|
-
};
|
76
|
+
const typedDicts_1 = require("./typedDicts");
|
77
|
+
const types_1 = require("./types");
|
140
78
|
// This table contains the names of several built-in types that
|
141
79
|
// are not subscriptable at runtime on older versions of Python.
|
142
80
|
// It lists the first version of Python where subscripting is
|
@@ -221,9 +159,6 @@ const maxRecursiveTypeAliasRecursionCount = 10;
|
|
221
159
|
const verifyTypeCacheEvaluatorFlags = false;
|
222
160
|
// This debugging option prints each expression and its evaluated type.
|
223
161
|
const printExpressionTypes = false;
|
224
|
-
// If the number of subtypes starts to explode when applying "literal math",
|
225
|
-
// cut off the literal union and fall back to the non-literal supertype.
|
226
|
-
const maxLiteralMathSubtypeCount = 64;
|
227
162
|
// The following number is chosen somewhat arbitrarily. We need to cut
|
228
163
|
// off code flow analysis at some point for code flow graphs that are too
|
229
164
|
// complex. Otherwise we risk overflowing the stack or incurring extremely
|
@@ -243,7 +178,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
243
178
|
let cancellationToken;
|
244
179
|
let isBasicTypesInitialized = false;
|
245
180
|
let noneType;
|
246
|
-
let unionType;
|
247
181
|
let objectType;
|
248
182
|
let typeClassType;
|
249
183
|
let functionObj;
|
@@ -352,7 +286,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
352
286
|
// If the entry is located within a part of the parse tree that is currently being
|
353
287
|
// "speculatively" evaluated, track it so we delete the cached entry when we leave
|
354
288
|
// this speculative context.
|
355
|
-
if (
|
289
|
+
if (isSpeculativeModeInUse(node)) {
|
356
290
|
speculativeTypeTracker.trackEntry(typeCacheToUse, node.id);
|
357
291
|
if (allowSpeculativeCaching) {
|
358
292
|
speculativeTypeTracker.addSpeculativeType(node, typeResult, incompleteGenerationCount, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType);
|
@@ -363,7 +297,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
363
297
|
writeTypeCache(node, { type }, flags);
|
364
298
|
}
|
365
299
|
function setAsymmetricDescriptorAssignment(node) {
|
366
|
-
if (
|
300
|
+
if (isSpeculativeModeInUse(/* node */ undefined)) {
|
367
301
|
return;
|
368
302
|
}
|
369
303
|
asymmetricDescriptorAssignmentCache.add(node.id);
|
@@ -596,15 +530,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
596
530
|
break;
|
597
531
|
}
|
598
532
|
case 55 /* UnaryOperation */: {
|
599
|
-
typeResult = getTypeOfUnaryOperation(node, inferenceContext);
|
533
|
+
typeResult = (0, operations_1.getTypeOfUnaryOperation)(evaluatorInterface, node, inferenceContext);
|
600
534
|
break;
|
601
535
|
}
|
602
536
|
case 7 /* BinaryOperation */: {
|
603
|
-
typeResult = getTypeOfBinaryOperation(node, inferenceContext, flags);
|
537
|
+
typeResult = (0, operations_1.getTypeOfBinaryOperation)(evaluatorInterface, node, inferenceContext, flags);
|
604
538
|
break;
|
605
539
|
}
|
606
540
|
case 5 /* AugmentedAssignment */: {
|
607
|
-
typeResult = getTypeOfAugmentedAssignment(node, inferenceContext);
|
541
|
+
typeResult = (0, operations_1.getTypeOfAugmentedAssignment)(evaluatorInterface, node, inferenceContext);
|
608
542
|
break;
|
609
543
|
}
|
610
544
|
case 31 /* List */:
|
@@ -621,7 +555,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
621
555
|
break;
|
622
556
|
}
|
623
557
|
case 51 /* Ternary */: {
|
624
|
-
typeResult =
|
558
|
+
typeResult = (0, operations_1.getTypeOfTernaryOperation)(evaluatorInterface, node, flags, inferenceContext);
|
625
559
|
break;
|
626
560
|
}
|
627
561
|
case 32 /* ListComprehension */: {
|
@@ -1996,7 +1930,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1996
1930
|
}
|
1997
1931
|
function isDiagnosticSuppressedForNode(node) {
|
1998
1932
|
return (suppressedNodeStack.some((suppressedNode) => ParseTreeUtils.isNodeContainedWithin(node, suppressedNode)) ||
|
1999
|
-
|
1933
|
+
isSpeculativeModeInUse(node));
|
2000
1934
|
}
|
2001
1935
|
function addDiagnostic(diagLevel, rule, message, node, range) {
|
2002
1936
|
if (diagLevel === 'none') {
|
@@ -2658,7 +2592,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2658
2592
|
else {
|
2659
2593
|
let callResult;
|
2660
2594
|
suppressDiagnostics(node.typeExpression, () => {
|
2661
|
-
callResult = validateConstructorArguments(node.typeExpression, [], concreteSubtype,
|
2595
|
+
callResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, node.typeExpression, [], concreteSubtype,
|
2662
2596
|
/* skipUnknownArgCheck */ false,
|
2663
2597
|
/* inferenceContext */ undefined);
|
2664
2598
|
});
|
@@ -2736,7 +2670,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2736
2670
|
}
|
2737
2671
|
}
|
2738
2672
|
function setSymbolAccessed(fileInfo, symbol, node) {
|
2739
|
-
if (!
|
2673
|
+
if (!isSpeculativeModeInUse(node)) {
|
2740
2674
|
fileInfo.accessedSymbolSet.add(symbol.id);
|
2741
2675
|
}
|
2742
2676
|
}
|
@@ -3095,7 +3029,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3095
3029
|
container: enclosingScope.name.value,
|
3096
3030
|
}), node);
|
3097
3031
|
}
|
3098
|
-
type = types_1.TypeVarType.cloneForScopeId(type, getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
|
3032
|
+
type = types_1.TypeVarType.cloneForScopeId(type, ParseTreeUtils.getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
|
3099
3033
|
? 1 /* Function */
|
3100
3034
|
: 0 /* Class */);
|
3101
3035
|
}
|
@@ -3186,35 +3120,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3186
3120
|
}
|
3187
3121
|
return type;
|
3188
3122
|
}
|
3189
|
-
// Creates an ID that identifies this parse node in a way that will
|
3190
|
-
// not change each time the file is parsed (unless, of course, the
|
3191
|
-
// file contents change).
|
3192
|
-
function getScopeIdForNode(node) {
|
3193
|
-
let name = '';
|
3194
|
-
if (node.nodeType === 10 /* Class */) {
|
3195
|
-
name = node.name.value;
|
3196
|
-
}
|
3197
|
-
else if (node.nodeType === 28 /* Function */) {
|
3198
|
-
name = node.name.value;
|
3199
|
-
}
|
3200
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
3201
|
-
return `${fileInfo.filePath}.${node.start.toString()}-${name}`;
|
3202
|
-
}
|
3203
|
-
// Walks up the parse tree and finds all scopes that can provide
|
3204
|
-
// a context for a TypeVar and returns the scope ID for each.
|
3205
|
-
function getTypeVarScopesForNode(node) {
|
3206
|
-
const scopeIds = [];
|
3207
|
-
let curNode = node;
|
3208
|
-
while (curNode) {
|
3209
|
-
curNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
|
3210
|
-
if (!curNode) {
|
3211
|
-
break;
|
3212
|
-
}
|
3213
|
-
scopeIds.push(getScopeIdForNode(curNode));
|
3214
|
-
curNode = curNode.parent;
|
3215
|
-
}
|
3216
|
-
return scopeIds;
|
3217
|
-
}
|
3218
3123
|
// Walks up the parse tree to find a function, class, or type alias
|
3219
3124
|
// declaration that provides the context for a type variable.
|
3220
3125
|
function findScopedTypeVar(node, type) {
|
@@ -5205,7 +5110,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5205
5110
|
}
|
5206
5111
|
else {
|
5207
5112
|
const tupleTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(tupleClassType));
|
5208
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), inferenceContext.expectedType, tupleTypeVarContext, getTypeVarScopesForNode(node))) {
|
5113
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), inferenceContext.expectedType, tupleTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
|
5209
5114
|
return undefined;
|
5210
5115
|
}
|
5211
5116
|
const specializedTuple = (0, typeUtils_1.applySolvedTypeVars)(tupleClassType, tupleTypeVarContext);
|
@@ -5364,7 +5269,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5364
5269
|
}
|
5365
5270
|
// Don't bother evaluating the arguments if we're speculatively evaluating the call
|
5366
5271
|
// or the base type is incomplete.
|
5367
|
-
if (!
|
5272
|
+
if (!isSpeculativeModeInUse(node) && !baseTypeResult.isIncomplete) {
|
5368
5273
|
// Touch all of the args so they're marked accessed even if there were errors.
|
5369
5274
|
// We skip this if it's a TypeVar() call in the typing.pyi module because
|
5370
5275
|
// this results in a cyclical type resolution problem whereby we try to
|
@@ -5432,7 +5337,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5432
5337
|
// If one or more of the arguments are incomplete, use speculative mode
|
5433
5338
|
// for the lambda evaluation because it may need to be reevaluated once
|
5434
5339
|
// the arg types are complete.
|
5435
|
-
let typeResult = isArgTypeIncomplete ||
|
5340
|
+
let typeResult = isArgTypeIncomplete || isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete)
|
5436
5341
|
? useSpeculativeMode(node.leftExpression, getLambdaType)
|
5437
5342
|
: getLambdaType();
|
5438
5343
|
// If bidirectional type inference failed, use normal type inference instead.
|
@@ -5740,10 +5645,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5740
5645
|
? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
|
5741
5646
|
: typeVarContext;
|
5742
5647
|
const effectiveTypeVarContext = (_a = typeVarContextToClone === null || typeVarContextToClone === void 0 ? void 0 : typeVarContextToClone.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
|
5743
|
-
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.
|
5744
|
-
if (overload.details.constructorTypeVarScopeId) {
|
5745
|
-
effectiveTypeVarContext.addSolveForScope(overload.details.constructorTypeVarScopeId);
|
5746
|
-
}
|
5648
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
|
5747
5649
|
effectiveTypeVarContext.unlock();
|
5748
5650
|
// Use speculative mode so we don't output any diagnostics or
|
5749
5651
|
// record any final types in the type cache.
|
@@ -5793,15 +5695,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5793
5695
|
else {
|
5794
5696
|
// Eliminate any return types that are subsumed by other return types.
|
5795
5697
|
let dedupedMatchResults = [];
|
5698
|
+
let dedupedResultsIncludeAny = false;
|
5796
5699
|
possibleMatchResults.forEach((result) => {
|
5797
5700
|
let isSubtypeSubsumed = false;
|
5798
5701
|
for (let dedupedIndex = 0; dedupedIndex < dedupedMatchResults.length; dedupedIndex++) {
|
5799
5702
|
if (assignType(dedupedMatchResults[dedupedIndex], result.returnType)) {
|
5800
|
-
|
5703
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(dedupedMatchResults[dedupedIndex])) {
|
5704
|
+
isSubtypeSubsumed = true;
|
5705
|
+
}
|
5706
|
+
else if (!(0, typeUtils_1.containsUnknown)(dedupedMatchResults[dedupedIndex])) {
|
5707
|
+
dedupedResultsIncludeAny = true;
|
5708
|
+
}
|
5801
5709
|
break;
|
5802
5710
|
}
|
5803
5711
|
else if (assignType(result.returnType, dedupedMatchResults[dedupedIndex])) {
|
5804
|
-
|
5712
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(result.returnType)) {
|
5713
|
+
dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
|
5714
|
+
}
|
5715
|
+
else if (!(0, typeUtils_1.containsUnknown)(dedupedMatchResults[dedupedIndex])) {
|
5716
|
+
dedupedResultsIncludeAny = true;
|
5717
|
+
}
|
5805
5718
|
break;
|
5806
5719
|
}
|
5807
5720
|
}
|
@@ -5811,9 +5724,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5811
5724
|
});
|
5812
5725
|
dedupedMatchResults = dedupedMatchResults.filter((t) => !(0, types_1.isNever)(t));
|
5813
5726
|
const combinedTypes = (0, types_1.combineTypes)(dedupedMatchResults);
|
5814
|
-
|
5815
|
-
|
5816
|
-
|
5727
|
+
let effectiveReturnType = combinedTypes;
|
5728
|
+
if (dedupedMatchResults.length > 1) {
|
5729
|
+
// If one or more of the deduped types is Any or contains Any,
|
5730
|
+
// we will assume that the person who defined the overload really
|
5731
|
+
// wanted Any rather than Unknown. In cases where the deduped types
|
5732
|
+
// simply contains conflicting results without an Any, we'll use
|
5733
|
+
// an UnknownType.
|
5734
|
+
if (dedupedResultsIncludeAny) {
|
5735
|
+
effectiveReturnType = types_1.AnyType.create();
|
5736
|
+
}
|
5737
|
+
else {
|
5738
|
+
effectiveReturnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
5739
|
+
}
|
5740
|
+
}
|
5741
|
+
returnTypes.push(effectiveReturnType);
|
5817
5742
|
}
|
5818
5743
|
}
|
5819
5744
|
if (!matchedOverload) {
|
@@ -5955,10 +5880,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5955
5880
|
return current.overloadIndex > previous.overloadIndex ? current : previous;
|
5956
5881
|
});
|
5957
5882
|
const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
|
5958
|
-
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.
|
5959
|
-
if (lastMatch.overload.details.constructorTypeVarScopeId) {
|
5960
|
-
effectiveTypeVarContext.addSolveForScope(lastMatch.overload.details.constructorTypeVarScopeId);
|
5961
|
-
}
|
5883
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(lastMatch.overload));
|
5962
5884
|
effectiveTypeVarContext.unlock();
|
5963
5885
|
return validateFunctionArgumentTypesWithContext(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5964
5886
|
};
|
@@ -6063,331 +5985,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6063
5985
|
});
|
6064
5986
|
return newExpandedArgTypes;
|
6065
5987
|
}
|
6066
|
-
// Tries to match the arguments of a call to the constructor for a class.
|
6067
|
-
// If successful, it returns the resulting (specialized) object type that
|
6068
|
-
// is allocated by the constructor. If unsuccessful, it records diagnostic
|
6069
|
-
// information and returns undefined.
|
6070
|
-
function validateConstructorArguments(errorNode, argList, type, skipUnknownArgCheck, inferenceContext) {
|
6071
|
-
var _a;
|
6072
|
-
let validatedTypes = false;
|
6073
|
-
let returnType;
|
6074
|
-
let reportedErrors = false;
|
6075
|
-
let isTypeIncomplete = false;
|
6076
|
-
let usedMetaclassCallMethod = false;
|
6077
|
-
const overloadsUsedForCall = [];
|
6078
|
-
// Create a helper function that determines whether we should skip argument
|
6079
|
-
// validation for either __init__ or __new__. This is required for certain
|
6080
|
-
// synthesized constructor types, namely NamedTuples.
|
6081
|
-
const skipConstructorCheck = (type) => {
|
6082
|
-
return (0, types_1.isFunction)(type) && types_1.FunctionType.isSkipConstructorCheck(type);
|
6083
|
-
};
|
6084
|
-
// Validate __init__
|
6085
|
-
// We validate __init__ before __new__ because the former typically has
|
6086
|
-
// more specific type annotations, and we want to evaluate the arguments
|
6087
|
-
// in the context of these types. The __new__ method often uses generic
|
6088
|
-
// vargs and kwargs.
|
6089
|
-
const initMethodType = (_a = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(type), '__init__', { method: 'get' },
|
6090
|
-
/* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
6091
|
-
if (initMethodType && !skipConstructorCheck(initMethodType)) {
|
6092
|
-
// If there is an expected type, analyze the constructor call
|
6093
|
-
// for each of the subtypes that comprise the expected type. If
|
6094
|
-
// one or more analyzes with no errors, use those results.
|
6095
|
-
if (inferenceContext) {
|
6096
|
-
const expectedCallResult = validateConstructorMethodWithContext(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, initMethodType);
|
6097
|
-
if (expectedCallResult && !expectedCallResult.argumentErrors) {
|
6098
|
-
returnType = expectedCallResult.returnType;
|
6099
|
-
if (expectedCallResult.isTypeIncomplete) {
|
6100
|
-
isTypeIncomplete = true;
|
6101
|
-
}
|
6102
|
-
}
|
6103
|
-
}
|
6104
|
-
if (!returnType) {
|
6105
|
-
const typeVarContext = type.typeArguments
|
6106
|
-
? (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(type, /* makeConcrete */ false)
|
6107
|
-
: new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
|
6108
|
-
typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(initMethodType));
|
6109
|
-
const callResult = validateCallArguments(errorNode, argList, { type: initMethodType }, typeVarContext, skipUnknownArgCheck);
|
6110
|
-
let adjustedClassType = type;
|
6111
|
-
if (callResult.specializedInitSelfType &&
|
6112
|
-
(0, types_1.isClassInstance)(callResult.specializedInitSelfType) &&
|
6113
|
-
types_1.ClassType.isSameGenericClass(callResult.specializedInitSelfType, type)) {
|
6114
|
-
adjustedClassType = types_1.ClassType.cloneAsInstantiable(callResult.specializedInitSelfType);
|
6115
|
-
}
|
6116
|
-
returnType = applyExpectedTypeForConstructor(adjustedClassType,
|
6117
|
-
/* inferenceContext */ undefined, typeVarContext);
|
6118
|
-
if (callResult.isTypeIncomplete) {
|
6119
|
-
isTypeIncomplete = true;
|
6120
|
-
}
|
6121
|
-
if (!callResult.argumentErrors) {
|
6122
|
-
overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
|
6123
|
-
}
|
6124
|
-
else {
|
6125
|
-
reportedErrors = true;
|
6126
|
-
}
|
6127
|
-
}
|
6128
|
-
validatedTypes = true;
|
6129
|
-
skipUnknownArgCheck = true;
|
6130
|
-
}
|
6131
|
-
// Validate __new__
|
6132
|
-
// Don't report errors for __new__ if __init__ already generated errors. They're
|
6133
|
-
// probably going to be entirely redundant anyway.
|
6134
|
-
if (!reportedErrors) {
|
6135
|
-
const metaclass = type.details.effectiveMetaclass;
|
6136
|
-
let constructorMethodInfo;
|
6137
|
-
// See if there's a custom `__call__` method on the metaclass. If so, we'll
|
6138
|
-
// use that rather than the `__new__` method on the class.
|
6139
|
-
if (metaclass && (0, types_1.isInstantiableClass)(metaclass) && !types_1.ClassType.isSameGenericClass(metaclass, type)) {
|
6140
|
-
constructorMethodInfo = getTypeOfClassMemberName(errorNode, metaclass,
|
6141
|
-
/* isAccessedThroughObject */ true, '__call__', { method: 'get' },
|
6142
|
-
/* diag */ undefined, 32 /* ConsiderMetaclassOnly */ |
|
6143
|
-
256 /* SkipTypeBaseClass */ |
|
6144
|
-
64 /* SkipAttributeAccessOverride */, type);
|
6145
|
-
if (constructorMethodInfo) {
|
6146
|
-
usedMetaclassCallMethod = true;
|
6147
|
-
}
|
6148
|
-
}
|
6149
|
-
if (!constructorMethodInfo) {
|
6150
|
-
constructorMethodInfo = getTypeOfClassMemberName(errorNode, type,
|
6151
|
-
/* isAccessedThroughObject */ false, '__new__', { method: 'get' },
|
6152
|
-
/* diag */ undefined, 1 /* AccessClassMembersOnly */ |
|
6153
|
-
4 /* SkipObjectBaseClass */ |
|
6154
|
-
16 /* TreatConstructorAsClassMethod */, type);
|
6155
|
-
}
|
6156
|
-
if (constructorMethodInfo && !skipConstructorCheck(constructorMethodInfo.type)) {
|
6157
|
-
const constructorMethodType = constructorMethodInfo.type;
|
6158
|
-
let newReturnType;
|
6159
|
-
// If there is an expected type that was not applied above when
|
6160
|
-
// handling the __init__ method, try to apply it with the __new__ method.
|
6161
|
-
if (inferenceContext && !returnType) {
|
6162
|
-
const expectedCallResult = validateConstructorMethodWithContext(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, constructorMethodType);
|
6163
|
-
if (expectedCallResult && !expectedCallResult.argumentErrors) {
|
6164
|
-
newReturnType = expectedCallResult.returnType;
|
6165
|
-
returnType = newReturnType;
|
6166
|
-
if (expectedCallResult.isTypeIncomplete) {
|
6167
|
-
isTypeIncomplete = true;
|
6168
|
-
}
|
6169
|
-
}
|
6170
|
-
}
|
6171
|
-
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
|
6172
|
-
if (type.typeAliasInfo) {
|
6173
|
-
typeVarContext.addSolveForScope(type.typeAliasInfo.typeVarScopeId);
|
6174
|
-
}
|
6175
|
-
typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(constructorMethodType));
|
6176
|
-
// Skip the unknown argument check if we've already checked for __init__.
|
6177
|
-
let callResult;
|
6178
|
-
if ((0, constructorTransform_1.hasConstructorTransform)(type)) {
|
6179
|
-
// Use speculative mode if we're going to later apply
|
6180
|
-
// a constructor transform. This allows us to use bidirectional
|
6181
|
-
// type inference for arguments in the transform.
|
6182
|
-
callResult = useSpeculativeMode(errorNode, () => {
|
6183
|
-
return validateCallArguments(errorNode, argList, constructorMethodInfo, typeVarContext, skipUnknownArgCheck);
|
6184
|
-
});
|
6185
|
-
}
|
6186
|
-
else {
|
6187
|
-
callResult = validateCallArguments(errorNode, argList, constructorMethodInfo, typeVarContext, skipUnknownArgCheck);
|
6188
|
-
}
|
6189
|
-
if (callResult.isTypeIncomplete) {
|
6190
|
-
isTypeIncomplete = true;
|
6191
|
-
}
|
6192
|
-
if (callResult.argumentErrors) {
|
6193
|
-
reportedErrors = true;
|
6194
|
-
}
|
6195
|
-
else if (!newReturnType) {
|
6196
|
-
newReturnType = callResult.returnType;
|
6197
|
-
if (overloadsUsedForCall.length === 0) {
|
6198
|
-
overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
|
6199
|
-
}
|
6200
|
-
// If the constructor returned an object whose type matches the class of
|
6201
|
-
// the original type being constructed, use the return type in case it was
|
6202
|
-
// specialized. If it doesn't match, we'll fall back on the assumption that
|
6203
|
-
// the constructed type is an instance of the class type. We need to do this
|
6204
|
-
// in cases where we're inferring the return type based on a call to
|
6205
|
-
// super().__new__().
|
6206
|
-
if (newReturnType) {
|
6207
|
-
if ((0, types_1.isClassInstance)(newReturnType) && types_1.ClassType.isSameGenericClass(newReturnType, type)) {
|
6208
|
-
// If the specialized return type derived from the __init__
|
6209
|
-
// method is "better" than the return type provided by the
|
6210
|
-
// __new__ method (where "better" means that the type arguments
|
6211
|
-
// are all known), stick with the __init__ result.
|
6212
|
-
if ((!(0, typeUtils_1.isPartlyUnknown)(newReturnType) && !(0, typeUtils_1.requiresSpecialization)(newReturnType)) ||
|
6213
|
-
returnType === undefined) {
|
6214
|
-
// Special-case the 'tuple' type specialization to use
|
6215
|
-
// the homogenous arbitrary-length form.
|
6216
|
-
if ((0, types_1.isClassInstance)(newReturnType) &&
|
6217
|
-
types_1.ClassType.isTupleClass(newReturnType) &&
|
6218
|
-
!newReturnType.tupleTypeArguments &&
|
6219
|
-
newReturnType.typeArguments &&
|
6220
|
-
newReturnType.typeArguments.length === 1) {
|
6221
|
-
newReturnType = (0, typeUtils_1.specializeTupleClass)(newReturnType, [
|
6222
|
-
{ type: newReturnType.typeArguments[0], isUnbounded: true },
|
6223
|
-
]);
|
6224
|
-
}
|
6225
|
-
returnType = newReturnType;
|
6226
|
-
}
|
6227
|
-
}
|
6228
|
-
else if (!returnType && !(0, types_1.isUnknown)(newReturnType)) {
|
6229
|
-
returnType = newReturnType;
|
6230
|
-
}
|
6231
|
-
}
|
6232
|
-
}
|
6233
|
-
if (!returnType) {
|
6234
|
-
returnType = applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext);
|
6235
|
-
}
|
6236
|
-
else if ((0, types_1.isClassInstance)(returnType) && (0, typeUtils_1.isTupleClass)(returnType) && !returnType.tupleTypeArguments) {
|
6237
|
-
returnType = applyExpectedTypeForTupleConstructor(returnType, inferenceContext);
|
6238
|
-
}
|
6239
|
-
validatedTypes = true;
|
6240
|
-
}
|
6241
|
-
}
|
6242
|
-
// If we weren't able to validate the args, analyze the expressions
|
6243
|
-
// here to mark symbols as referenced and report expression-level errors.
|
6244
|
-
if (!validatedTypes) {
|
6245
|
-
argList.forEach((arg) => {
|
6246
|
-
if (arg.valueExpression && !speculativeTypeTracker.isSpeculative(arg.valueExpression)) {
|
6247
|
-
getTypeOfExpression(arg.valueExpression);
|
6248
|
-
}
|
6249
|
-
});
|
6250
|
-
}
|
6251
|
-
if (!validatedTypes && argList.some((arg) => arg.argumentCategory === 0 /* Simple */)) {
|
6252
|
-
// Suppress this error if the class was instantiated from a custom
|
6253
|
-
// metaclass because it's likely that it's a false positive. Also
|
6254
|
-
// suppress the error if the class's metaclass has a __call__ method.
|
6255
|
-
const isCustomMetaclass = !!type.details.effectiveMetaclass &&
|
6256
|
-
(0, types_1.isInstantiableClass)(type.details.effectiveMetaclass) &&
|
6257
|
-
!types_1.ClassType.isBuiltIn(type.details.effectiveMetaclass);
|
6258
|
-
if (!isCustomMetaclass && !usedMetaclassCallMethod) {
|
6259
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
6260
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.constructorNoArgs().format({ type: type.aliasName || type.details.name }), errorNode);
|
6261
|
-
}
|
6262
|
-
}
|
6263
|
-
if (!returnType) {
|
6264
|
-
// There was no __init__ or __new__ method or we couldn't match the provided
|
6265
|
-
// arguments to them.
|
6266
|
-
if (!inferenceContext && type.typeArguments) {
|
6267
|
-
// If there was no expected type but the type was already specialized,
|
6268
|
-
// assume that we're constructing an instance of the specialized type.
|
6269
|
-
returnType = (0, typeUtils_1.convertToInstance)(type);
|
6270
|
-
}
|
6271
|
-
else {
|
6272
|
-
// Do our best to specialize the instantiated class based on the expected
|
6273
|
-
// type if provided.
|
6274
|
-
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
|
6275
|
-
if (inferenceContext) {
|
6276
|
-
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(errorNode));
|
6277
|
-
}
|
6278
|
-
returnType = applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext);
|
6279
|
-
}
|
6280
|
-
}
|
6281
|
-
if (!reportedErrors) {
|
6282
|
-
const transformed = (0, constructorTransform_1.applyConstructorTransform)(evaluatorInterface, errorNode, argList, type, {
|
6283
|
-
argumentErrors: reportedErrors,
|
6284
|
-
returnType,
|
6285
|
-
isTypeIncomplete,
|
6286
|
-
});
|
6287
|
-
returnType = transformed.returnType;
|
6288
|
-
if (transformed.isTypeIncomplete) {
|
6289
|
-
isTypeIncomplete = true;
|
6290
|
-
}
|
6291
|
-
if (transformed.argumentErrors) {
|
6292
|
-
reportedErrors = true;
|
6293
|
-
}
|
6294
|
-
}
|
6295
|
-
const result = {
|
6296
|
-
argumentErrors: reportedErrors,
|
6297
|
-
returnType,
|
6298
|
-
isTypeIncomplete,
|
6299
|
-
overloadsUsedForCall,
|
6300
|
-
};
|
6301
|
-
return result;
|
6302
|
-
}
|
6303
|
-
// For a constructor call that targets a generic class and an "expected type"
|
6304
|
-
// (i.e. bidirectional inference), this function attempts to infer the correct
|
6305
|
-
// specialized return type for the constructor.
|
6306
|
-
function validateConstructorMethodWithContext(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, constructorMethodType) {
|
6307
|
-
let isTypeIncomplete = false;
|
6308
|
-
let argumentErrors = false;
|
6309
|
-
const overloadsUsedForCall = [];
|
6310
|
-
const returnType = (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (expectedSubType) => {
|
6311
|
-
expectedSubType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedSubType);
|
6312
|
-
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
|
6313
|
-
typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(constructorMethodType));
|
6314
|
-
if ((0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), expectedSubType, typeVarContext, getTypeVarScopesForNode(errorNode))) {
|
6315
|
-
const specializedConstructor = (0, typeUtils_1.applySolvedTypeVars)(constructorMethodType, typeVarContext);
|
6316
|
-
let callResult;
|
6317
|
-
useSpeculativeMode(errorNode, () => {
|
6318
|
-
callResult = validateCallArguments(errorNode, argList, { type: specializedConstructor }, typeVarContext.clone(), skipUnknownArgCheck);
|
6319
|
-
});
|
6320
|
-
if (!callResult.argumentErrors) {
|
6321
|
-
// Call validateCallArguments again, this time without speculative
|
6322
|
-
// mode, so any errors are reported.
|
6323
|
-
callResult = validateCallArguments(errorNode, argList, { type: specializedConstructor }, typeVarContext, skipUnknownArgCheck);
|
6324
|
-
if (callResult.isTypeIncomplete) {
|
6325
|
-
isTypeIncomplete = true;
|
6326
|
-
}
|
6327
|
-
if (callResult.argumentErrors) {
|
6328
|
-
argumentErrors = true;
|
6329
|
-
}
|
6330
|
-
overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
|
6331
|
-
return applyExpectedSubtypeForConstructor(type, expectedSubType, inferenceContext, typeVarContext);
|
6332
|
-
}
|
6333
|
-
}
|
6334
|
-
return undefined;
|
6335
|
-
});
|
6336
|
-
if ((0, types_1.isNever)(returnType)) {
|
6337
|
-
return undefined;
|
6338
|
-
}
|
6339
|
-
return { returnType, isTypeIncomplete, argumentErrors, overloadsUsedForCall };
|
6340
|
-
}
|
6341
|
-
function applyExpectedSubtypeForConstructor(type, expectedSubtype, inferenceContext, typeVarContext) {
|
6342
|
-
var _a;
|
6343
|
-
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstance(type), typeVarContext);
|
6344
|
-
if (!assignType(expectedSubtype, specializedType,
|
6345
|
-
/* diag */ undefined,
|
6346
|
-
/* destTypeVarContext */ (_a = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext) === null || _a === void 0 ? void 0 : _a.clone(),
|
6347
|
-
/* srcTypeVarContext */ undefined)) {
|
6348
|
-
return undefined;
|
6349
|
-
}
|
6350
|
-
// If the expected type is "Any", transform it to an Any.
|
6351
|
-
if ((0, types_1.isAny)(expectedSubtype)) {
|
6352
|
-
return expectedSubtype;
|
6353
|
-
}
|
6354
|
-
return specializedType;
|
6355
|
-
}
|
6356
|
-
// Handles the case where a constructor is a generic type and the type
|
6357
|
-
// arguments are not specified but can be provided by the expected type.
|
6358
|
-
function applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext) {
|
6359
|
-
let unsolvedTypeVarsAreUnknown = true;
|
6360
|
-
if (inferenceContext) {
|
6361
|
-
const specializedExpectedType = (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (expectedSubtype) => {
|
6362
|
-
return applyExpectedSubtypeForConstructor(type, expectedSubtype, inferenceContext, typeVarContext);
|
6363
|
-
});
|
6364
|
-
if (!(0, types_1.isNever)(specializedExpectedType)) {
|
6365
|
-
return specializedExpectedType;
|
6366
|
-
}
|
6367
|
-
// If the expected type didn't provide TypeVar values, remaining
|
6368
|
-
// unsolved TypeVars should be considered Unknown unless they were
|
6369
|
-
// provided explicitly in the constructor call.
|
6370
|
-
if (type.typeArguments) {
|
6371
|
-
unsolvedTypeVarsAreUnknown = false;
|
6372
|
-
}
|
6373
|
-
}
|
6374
|
-
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(type, typeVarContext, {
|
6375
|
-
unknownIfNotFound: unsolvedTypeVarsAreUnknown,
|
6376
|
-
});
|
6377
|
-
return types_1.ClassType.cloneAsInstance(specializedType);
|
6378
|
-
}
|
6379
|
-
// Similar to applyExpectedTypeForConstructor, this function handles the
|
6380
|
-
// special case of the tuple class.
|
6381
|
-
function applyExpectedTypeForTupleConstructor(type, inferenceContext) {
|
6382
|
-
let specializedType = type;
|
6383
|
-
if (inferenceContext &&
|
6384
|
-
(0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
6385
|
-
(0, typeUtils_1.isTupleClass)(inferenceContext.expectedType) &&
|
6386
|
-
inferenceContext.expectedType.tupleTypeArguments) {
|
6387
|
-
specializedType = (0, typeUtils_1.specializeTupleClass)(type, inferenceContext.expectedType.tupleTypeArguments);
|
6388
|
-
}
|
6389
|
-
return specializedType;
|
6390
|
-
}
|
6391
5988
|
// Validates that the arguments can be assigned to the call's parameter
|
6392
5989
|
// list, specializes the call based on arg types, and returns the
|
6393
5990
|
// specialized type of the return value. If it detects an error along
|
@@ -6420,7 +6017,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6420
6017
|
// to be done again once it is complete.
|
6421
6018
|
if (!callTypeResult.isIncomplete) {
|
6422
6019
|
argList.forEach((arg) => {
|
6423
|
-
if (arg.valueExpression && !
|
6020
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6424
6021
|
getTypeOfArgument(arg);
|
6425
6022
|
}
|
6426
6023
|
});
|
@@ -6449,7 +6046,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6449
6046
|
let effectiveTypeVarContext = typeVarContext;
|
6450
6047
|
if (!effectiveTypeVarContext) {
|
6451
6048
|
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6452
|
-
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.
|
6049
|
+
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
|
6453
6050
|
// There are certain cases, such as with super().__new__(cls) calls where
|
6454
6051
|
// the call is a constructor but the proper TypeVar scope has been lost.
|
6455
6052
|
// We'll add a wildcard TypeVar scope here. This is a bit of a hack and
|
@@ -6544,7 +6141,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6544
6141
|
const className = expandedSubtype.aliasName || expandedSubtype.details.name;
|
6545
6142
|
if (className === 'type') {
|
6546
6143
|
// Validate the constructor arguments.
|
6547
|
-
validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6144
|
+
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6548
6145
|
// Handle the 'type' call specially.
|
6549
6146
|
if (argList.length === 1) {
|
6550
6147
|
// The one-parameter form of "type" returns the class
|
@@ -6643,7 +6240,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6643
6240
|
}), errorNode);
|
6644
6241
|
}
|
6645
6242
|
// Assume this is a call to the constructor.
|
6646
|
-
const constructorResult = validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6243
|
+
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6647
6244
|
overloadsUsedForCall.push(...constructorResult.overloadsUsedForCall);
|
6648
6245
|
if (constructorResult.argumentErrors) {
|
6649
6246
|
argumentErrors = true;
|
@@ -7485,7 +7082,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7485
7082
|
// If we're in speculative mode and an arg/param mismatch has already been reported, don't
|
7486
7083
|
// bother doing the extra work here. This occurs frequently when attempting to find the
|
7487
7084
|
// correct overload.
|
7488
|
-
if (!reportedArgError || !
|
7085
|
+
if (!reportedArgError || !isSpeculativeModeInUse(undefined)) {
|
7489
7086
|
// If there are arguments that map to a variadic *args parameter that hasn't
|
7490
7087
|
// already been matched, see if the type of that *args parameter is a variadic
|
7491
7088
|
// type variable. If so, we'll preprocess those arguments and combine them
|
@@ -7625,7 +7222,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7625
7222
|
(0, types_1.isClassInstance)(effectiveExpectedType) &&
|
7626
7223
|
!types_1.ClassType.isSameGenericClass(effectiveReturnType, effectiveExpectedType)) {
|
7627
7224
|
const tempTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(effectiveReturnType));
|
7628
|
-
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, effectiveReturnType, effectiveExpectedType, tempTypeVarContext, getTypeVarScopesForNode(errorNode));
|
7225
|
+
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, effectiveReturnType, effectiveExpectedType, tempTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(errorNode));
|
7629
7226
|
const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
|
7630
7227
|
/* typeArguments */ undefined,
|
7631
7228
|
/* isTypeArgumentExplicit */ false);
|
@@ -7820,7 +7417,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7820
7417
|
if (!typeVarScopeNode) {
|
7821
7418
|
break;
|
7822
7419
|
}
|
7823
|
-
const typeVarScopeId = getScopeIdForNode(typeVarScopeNode);
|
7420
|
+
const typeVarScopeId = ParseTreeUtils.getScopeIdForNode(typeVarScopeNode);
|
7824
7421
|
if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
|
7825
7422
|
eliminateUnsolvedInUnions = false;
|
7826
7423
|
}
|
@@ -7843,7 +7440,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7843
7440
|
let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
|
7844
7441
|
// We'll also leave TypeVars unsolved if the call is a recursive
|
7845
7442
|
// call to a generic function.
|
7846
|
-
const typeVarScopes = getTypeVarScopesForNode(errorNode);
|
7443
|
+
const typeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
|
7847
7444
|
if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
|
7848
7445
|
unknownIfNotFound = false;
|
7849
7446
|
}
|
@@ -7919,7 +7516,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7919
7516
|
// Evaluate types of all args. This will ensure that referenced symbols are
|
7920
7517
|
// not reported as unaccessed.
|
7921
7518
|
argList.forEach((arg) => {
|
7922
|
-
if (arg.valueExpression && !
|
7519
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
7923
7520
|
getTypeOfExpression(arg.valueExpression);
|
7924
7521
|
}
|
7925
7522
|
});
|
@@ -8120,9 +7717,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8120
7717
|
}
|
8121
7718
|
expectedTypeDiag = exprTypeResult.expectedTypeDiagAddendum;
|
8122
7719
|
}
|
8123
|
-
if (argParam.argument &&
|
8124
|
-
argParam.argument.name &&
|
8125
|
-
!speculativeTypeTracker.isSpeculative(argParam.errorNode)) {
|
7720
|
+
if (argParam.argument && argParam.argument.name && !isSpeculativeModeInUse(argParam.errorNode)) {
|
8126
7721
|
writeTypeCache(argParam.argument.name, { type: expectedType !== null && expectedType !== void 0 ? expectedType : argType, isIncomplete: isTypeIncomplete }, 0 /* None */);
|
8127
7722
|
}
|
8128
7723
|
}
|
@@ -8188,7 +7783,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8188
7783
|
const concreteParamType = makeTopLevelTypeVarsConcrete(argParam.paramType);
|
8189
7784
|
if ((0, types_1.isFunction)(concreteParamType) || (0, types_1.isOverloadedFunction)(concreteParamType)) {
|
8190
7785
|
if ((0, types_1.isInstantiableClass)(argType)) {
|
8191
|
-
const constructor = createFunctionFromConstructor(argType);
|
7786
|
+
const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, argType);
|
8192
7787
|
if (constructor && (0, types_1.isOverloadedFunction)(constructor)) {
|
8193
7788
|
return { isCompatible, argType, isTypeIncomplete, skippedOverloadArg: true, condition };
|
8194
7789
|
}
|
@@ -8695,652 +8290,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8695
8290
|
}
|
8696
8291
|
return { type };
|
8697
8292
|
}
|
8698
|
-
function getTypeOfUnaryOperation(node, inferenceContext) {
|
8699
|
-
const exprTypeResult = getTypeOfExpression(node.expression);
|
8700
|
-
let exprType = makeTopLevelTypeVarsConcrete(exprTypeResult.type);
|
8701
|
-
const isIncomplete = exprTypeResult.isIncomplete;
|
8702
|
-
if ((0, types_1.isNever)(exprType)) {
|
8703
|
-
return { type: types_1.NeverType.createNever(), isIncomplete };
|
8704
|
-
}
|
8705
|
-
// Map unary operators to magic functions. Note that the bitwise
|
8706
|
-
// invert has two magic functions that are aliases of each other.
|
8707
|
-
const unaryOperatorMap = {
|
8708
|
-
[0 /* Add */]: '__pos__',
|
8709
|
-
[33 /* Subtract */]: '__neg__',
|
8710
|
-
[5 /* BitwiseInvert */]: '__invert__',
|
8711
|
-
};
|
8712
|
-
let type;
|
8713
|
-
if (node.operator !== 38 /* Not */) {
|
8714
|
-
if ((0, typeUtils_1.isOptionalType)(exprType)) {
|
8715
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportOptionalOperand, diagnosticRules_1.DiagnosticRule.reportOptionalOperand, localize_1.Localizer.Diagnostic.noneOperator().format({
|
8716
|
-
operator: ParseTreeUtils.printOperator(node.operator),
|
8717
|
-
}), node.expression);
|
8718
|
-
exprType = (0, types_1.removeNoneFromUnion)(exprType);
|
8719
|
-
}
|
8720
|
-
}
|
8721
|
-
// Handle certain operations on certain literal types
|
8722
|
-
// using special-case math. Do not apply this if the input type
|
8723
|
-
// is incomplete because we may be evaluating an expression within
|
8724
|
-
// a loop, so the literal value may change each time.
|
8725
|
-
if (!exprTypeResult.isIncomplete) {
|
8726
|
-
const literalClassName = (0, typeUtils_1.getLiteralTypeClassName)(exprType);
|
8727
|
-
if (literalClassName === 'int') {
|
8728
|
-
if (node.operator === 0 /* Add */) {
|
8729
|
-
type = exprType;
|
8730
|
-
}
|
8731
|
-
else if (node.operator === 33 /* Subtract */) {
|
8732
|
-
type = (0, typeUtils_1.mapSubtypes)(exprType, (subtype) => {
|
8733
|
-
const classSubtype = subtype;
|
8734
|
-
return types_1.ClassType.cloneWithLiteral(classSubtype, -classSubtype.literalValue);
|
8735
|
-
});
|
8736
|
-
}
|
8737
|
-
}
|
8738
|
-
else if (literalClassName === 'bool') {
|
8739
|
-
if (node.operator === 38 /* Not */) {
|
8740
|
-
type = (0, typeUtils_1.mapSubtypes)(exprType, (subtype) => {
|
8741
|
-
const classSubtype = subtype;
|
8742
|
-
return types_1.ClassType.cloneWithLiteral(classSubtype, !classSubtype.literalValue);
|
8743
|
-
});
|
8744
|
-
}
|
8745
|
-
}
|
8746
|
-
}
|
8747
|
-
if (!type) {
|
8748
|
-
// __not__ always returns a boolean.
|
8749
|
-
if (node.operator === 38 /* Not */) {
|
8750
|
-
type = getBuiltInObject(node, 'bool');
|
8751
|
-
if (!type) {
|
8752
|
-
type = types_1.UnknownType.create();
|
8753
|
-
}
|
8754
|
-
}
|
8755
|
-
else {
|
8756
|
-
if ((0, types_1.isAnyOrUnknown)(exprType)) {
|
8757
|
-
type = exprType;
|
8758
|
-
}
|
8759
|
-
else {
|
8760
|
-
const magicMethodName = unaryOperatorMap[node.operator];
|
8761
|
-
type = getTypeOfMagicMethodReturn(exprType, [], magicMethodName, node, inferenceContext);
|
8762
|
-
}
|
8763
|
-
if (!type) {
|
8764
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
8765
|
-
if (inferenceContext) {
|
8766
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportUnaryOperatorBidirectional().format({
|
8767
|
-
operator: ParseTreeUtils.printOperator(node.operator),
|
8768
|
-
type: printType(exprType),
|
8769
|
-
expectedType: printType(inferenceContext.expectedType),
|
8770
|
-
}), node);
|
8771
|
-
}
|
8772
|
-
else {
|
8773
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportUnaryOperator().format({
|
8774
|
-
operator: ParseTreeUtils.printOperator(node.operator),
|
8775
|
-
type: printType(exprType),
|
8776
|
-
}), node);
|
8777
|
-
}
|
8778
|
-
type = types_1.UnknownType.create();
|
8779
|
-
}
|
8780
|
-
}
|
8781
|
-
}
|
8782
|
-
return { type, isIncomplete };
|
8783
|
-
}
|
8784
|
-
function getTypeOfBinaryOperation(node, inferenceContext, flags) {
|
8785
|
-
const leftExpression = node.leftExpression;
|
8786
|
-
let rightExpression = node.rightExpression;
|
8787
|
-
let isIncomplete = false;
|
8788
|
-
let typeErrors = false;
|
8789
|
-
// If this is a comparison and the left expression is also a comparison,
|
8790
|
-
// we need to change the behavior to accommodate python's "chained
|
8791
|
-
// comparisons" feature.
|
8792
|
-
if (ParseTreeUtils.operatorSupportsChaining(node.operator)) {
|
8793
|
-
if (rightExpression.nodeType === 7 /* BinaryOperation */ &&
|
8794
|
-
!rightExpression.parenthesized &&
|
8795
|
-
ParseTreeUtils.operatorSupportsChaining(rightExpression.operator)) {
|
8796
|
-
// Evaluate the right expression so it is type checked.
|
8797
|
-
getTypeOfBinaryOperation(rightExpression, inferenceContext, flags);
|
8798
|
-
// Use the left side of the right expression for comparison purposes.
|
8799
|
-
rightExpression = rightExpression.leftExpression;
|
8800
|
-
}
|
8801
|
-
}
|
8802
|
-
// For most binary operations, the "expected type" is applied to the output
|
8803
|
-
// of the magic method for that operation. However, the "or" and "and" operators
|
8804
|
-
// have no magic method, so we apply the expected type directly to both operands.
|
8805
|
-
let expectedOperandType = node.operator === 37 /* Or */ || node.operator === 36 /* And */
|
8806
|
-
? inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType
|
8807
|
-
: undefined;
|
8808
|
-
// Handle the very special case where the expected type is a list
|
8809
|
-
// and the operator is a multiply. This comes up in the common case
|
8810
|
-
// of "x: List[Optional[X]] = [None] * y" where y is an integer literal.
|
8811
|
-
let expectedLeftOperandType;
|
8812
|
-
if (node.operator === 26 /* Multiply */ &&
|
8813
|
-
inferenceContext &&
|
8814
|
-
(0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
8815
|
-
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'list') &&
|
8816
|
-
inferenceContext.expectedType.typeArguments &&
|
8817
|
-
inferenceContext.expectedType.typeArguments.length >= 1 &&
|
8818
|
-
node.leftExpression.nodeType === 31 /* List */) {
|
8819
|
-
expectedLeftOperandType = inferenceContext.expectedType;
|
8820
|
-
}
|
8821
|
-
const effectiveExpectedType = expectedOperandType !== null && expectedOperandType !== void 0 ? expectedOperandType : expectedLeftOperandType;
|
8822
|
-
const leftTypeResult = getTypeOfExpression(leftExpression, flags, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType));
|
8823
|
-
let leftType = leftTypeResult.type;
|
8824
|
-
if (!expectedOperandType) {
|
8825
|
-
if (node.operator === 37 /* Or */ || node.operator === 36 /* And */) {
|
8826
|
-
// For "or" and "and", use the type of the left operand. This allows us to
|
8827
|
-
// infer a better type for expressions like `x or []`.
|
8828
|
-
expectedOperandType = leftType;
|
8829
|
-
}
|
8830
|
-
else if (node.operator === 0 /* Add */ && node.rightExpression.nodeType === 31 /* List */) {
|
8831
|
-
// For the "+" operator , use this technique only if the right operand is
|
8832
|
-
// a list expression. This heuristic handles the common case of `my_list + [0]`.
|
8833
|
-
expectedOperandType = leftType;
|
8834
|
-
}
|
8835
|
-
else if (node.operator === 6 /* BitwiseOr */) {
|
8836
|
-
// If this is a bitwise or ("|"), use the type of the left operand. This allows
|
8837
|
-
// us to support the case where a TypedDict is being updated with a dict expression.
|
8838
|
-
if ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isTypedDictClass(leftType)) {
|
8839
|
-
expectedOperandType = leftType;
|
8840
|
-
}
|
8841
|
-
}
|
8842
|
-
}
|
8843
|
-
const rightTypeResult = getTypeOfExpression(rightExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedOperandType));
|
8844
|
-
let rightType = rightTypeResult.type;
|
8845
|
-
if (leftTypeResult.isIncomplete || rightTypeResult.isIncomplete) {
|
8846
|
-
isIncomplete = true;
|
8847
|
-
}
|
8848
|
-
// Is this a "|" operator used in a context where it is supposed to be
|
8849
|
-
// interpreted as a union operator?
|
8850
|
-
if (node.operator === 6 /* BitwiseOr */ &&
|
8851
|
-
!customMetaclassSupportsMethod(leftType, '__or__') &&
|
8852
|
-
!customMetaclassSupportsMethod(rightType, '__ror__')) {
|
8853
|
-
let adjustedRightType = rightType;
|
8854
|
-
let adjustedLeftType = leftType;
|
8855
|
-
if (!(0, types_1.isNoneInstance)(leftType) && (0, types_1.isNoneInstance)(rightType)) {
|
8856
|
-
// Handle the special case where "None" is being added to the union
|
8857
|
-
// with something else. Even though "None" will normally be interpreted
|
8858
|
-
// as the None singleton object in contexts where a type annotation isn't
|
8859
|
-
// assumed, we'll allow it here.
|
8860
|
-
adjustedRightType = types_1.NoneType.createType();
|
8861
|
-
}
|
8862
|
-
else if (!(0, types_1.isNoneInstance)(rightType) && (0, types_1.isNoneInstance)(leftType)) {
|
8863
|
-
adjustedLeftType = types_1.NoneType.createType();
|
8864
|
-
}
|
8865
|
-
if ((0, typeUtils_1.isUnionableType)([adjustedLeftType, adjustedRightType])) {
|
8866
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
8867
|
-
const unionNotationSupported = fileInfo.isStubFile ||
|
8868
|
-
(flags & 4 /* AllowForwardReferences */) !== 0 ||
|
8869
|
-
fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_10;
|
8870
|
-
if (!unionNotationSupported) {
|
8871
|
-
// If the left type is Any, we can't say for sure whether this
|
8872
|
-
// is an illegal syntax or a valid application of the "|" operator.
|
8873
|
-
if (!(0, types_1.isAnyOrUnknown)(adjustedLeftType)) {
|
8874
|
-
addError(localize_1.Localizer.Diagnostic.unionSyntaxIllegal(), node, node.operatorToken);
|
8875
|
-
}
|
8876
|
-
}
|
8877
|
-
if (!validateTypeArg({ ...leftTypeResult, node: leftExpression }, { allowVariadicTypeVar: true, allowUnpackedTuples: true }) ||
|
8878
|
-
!validateTypeArg({ ...rightTypeResult, node: rightExpression }, { allowVariadicTypeVar: true, allowUnpackedTuples: true })) {
|
8879
|
-
return { type: types_1.UnknownType.create() };
|
8880
|
-
}
|
8881
|
-
const newUnion = (0, types_1.combineTypes)([adjustedLeftType, adjustedRightType]);
|
8882
|
-
if ((0, types_1.isUnion)(newUnion)) {
|
8883
|
-
types_1.TypeBase.setSpecialForm(newUnion);
|
8884
|
-
}
|
8885
|
-
// Check for "stringified" forward reference type expressions. The "|" operator
|
8886
|
-
// doesn't support these except in certain circumstances. Notably, it can't be used
|
8887
|
-
// with other strings or with types that are not specialized using an index form.
|
8888
|
-
if (!fileInfo.isStubFile) {
|
8889
|
-
let stringNode;
|
8890
|
-
let otherNode;
|
8891
|
-
let otherType;
|
8892
|
-
if (leftExpression.nodeType === 48 /* StringList */) {
|
8893
|
-
stringNode = leftExpression;
|
8894
|
-
otherNode = rightExpression;
|
8895
|
-
otherType = rightType;
|
8896
|
-
}
|
8897
|
-
else if (rightExpression.nodeType === 48 /* StringList */) {
|
8898
|
-
stringNode = rightExpression;
|
8899
|
-
otherNode = leftExpression;
|
8900
|
-
otherType = leftType;
|
8901
|
-
}
|
8902
|
-
if (stringNode && otherNode && otherType) {
|
8903
|
-
let isAllowed = true;
|
8904
|
-
if ((0, types_1.isClass)(otherType)) {
|
8905
|
-
if (!otherType.isTypeArgumentExplicit || (0, types_1.isClassInstance)(otherType)) {
|
8906
|
-
isAllowed = false;
|
8907
|
-
}
|
8908
|
-
}
|
8909
|
-
if (!isAllowed) {
|
8910
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.unionForwardReferenceNotAllowed(), stringNode);
|
8911
|
-
}
|
8912
|
-
}
|
8913
|
-
}
|
8914
|
-
return { type: newUnion };
|
8915
|
-
}
|
8916
|
-
}
|
8917
|
-
// Optional checks apply to all operations except for boolean operations.
|
8918
|
-
let isLeftOptionalType = false;
|
8919
|
-
if (booleanOperatorMap[node.operator] === undefined) {
|
8920
|
-
// None is a valid operand for == and != even if the type stub says otherwise.
|
8921
|
-
if (node.operator === 12 /* Equals */ || node.operator === 28 /* NotEquals */) {
|
8922
|
-
leftType = (0, types_1.removeNoneFromUnion)(leftType);
|
8923
|
-
}
|
8924
|
-
else {
|
8925
|
-
isLeftOptionalType = (0, typeUtils_1.isOptionalType)(leftType);
|
8926
|
-
}
|
8927
|
-
// None is a valid operand for == and != even if the type stub says otherwise.
|
8928
|
-
if (node.operator === 12 /* Equals */ || node.operator === 28 /* NotEquals */) {
|
8929
|
-
rightType = (0, types_1.removeNoneFromUnion)(rightType);
|
8930
|
-
}
|
8931
|
-
}
|
8932
|
-
const diag = new diagnostic_1.DiagnosticAddendum();
|
8933
|
-
// Don't use literal math if either of the operation is within a loop
|
8934
|
-
// because the literal values may change each time.
|
8935
|
-
const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node);
|
8936
|
-
// Don't special-case tuple __add__ if the left type is a union. This
|
8937
|
-
// can result in an infinite loop if we keep creating new tuple types
|
8938
|
-
// within a loop construct using __add__.
|
8939
|
-
const isTupleAddAllowed = !(0, types_1.isUnion)(leftType);
|
8940
|
-
let type = validateBinaryOperation(node.operator, { type: leftType, isIncomplete: leftTypeResult.isIncomplete }, { type: rightType, isIncomplete: rightTypeResult.isIncomplete }, node, inferenceContext, diag, { isLiteralMathAllowed, isTupleAddAllowed });
|
8941
|
-
if (!diag.isEmpty() || !type) {
|
8942
|
-
typeErrors = true;
|
8943
|
-
if (!isIncomplete) {
|
8944
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
8945
|
-
if (isLeftOptionalType && diag.getMessages().length === 1) {
|
8946
|
-
// If the left was an optional type and there is just one diagnostic,
|
8947
|
-
// assume that it was due to a "None" not being supported. Report
|
8948
|
-
// this as a reportOptionalOperand diagnostic rather than a
|
8949
|
-
// reportGeneralTypeIssues diagnostic.
|
8950
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportOptionalOperand, diagnosticRules_1.DiagnosticRule.reportOptionalOperand, localize_1.Localizer.Diagnostic.noneOperator().format({
|
8951
|
-
operator: ParseTreeUtils.printOperator(node.operator),
|
8952
|
-
}), node.leftExpression);
|
8953
|
-
}
|
8954
|
-
else {
|
8955
|
-
// If neither the LHS or RHS are unions, don't include a diagnostic addendum
|
8956
|
-
// because it will be redundant with the main diagnostic message. The addenda
|
8957
|
-
// are useful only if union expansion was used for one or both operands.
|
8958
|
-
let diagString = '';
|
8959
|
-
if ((0, types_1.isUnion)(makeTopLevelTypeVarsConcrete(leftType)) ||
|
8960
|
-
(0, types_1.isUnion)(makeTopLevelTypeVarsConcrete(rightType))) {
|
8961
|
-
diagString = diag.getString();
|
8962
|
-
}
|
8963
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
|
8964
|
-
operator: ParseTreeUtils.printOperator(node.operator),
|
8965
|
-
leftType: printType(leftType),
|
8966
|
-
rightType: printType(rightType),
|
8967
|
-
}) + diagString, node);
|
8968
|
-
}
|
8969
|
-
}
|
8970
|
-
type = types_1.UnknownType.create();
|
8971
|
-
}
|
8972
|
-
return { type, isIncomplete, typeErrors };
|
8973
|
-
}
|
8974
|
-
function customMetaclassSupportsMethod(type, methodName) {
|
8975
|
-
if (!(0, types_1.isInstantiableClass)(type)) {
|
8976
|
-
return false;
|
8977
|
-
}
|
8978
|
-
const metaclass = type.details.effectiveMetaclass;
|
8979
|
-
if (!metaclass || !(0, types_1.isInstantiableClass)(metaclass)) {
|
8980
|
-
return false;
|
8981
|
-
}
|
8982
|
-
if (types_1.ClassType.isBuiltIn(metaclass, 'type')) {
|
8983
|
-
return false;
|
8984
|
-
}
|
8985
|
-
const memberInfo = (0, typeUtils_1.lookUpClassMember)(metaclass, methodName);
|
8986
|
-
if (!memberInfo) {
|
8987
|
-
return false;
|
8988
|
-
}
|
8989
|
-
if ((0, types_1.isInstantiableClass)(memberInfo.classType) && types_1.ClassType.isBuiltIn(memberInfo.classType, 'type')) {
|
8990
|
-
return false;
|
8991
|
-
}
|
8992
|
-
return true;
|
8993
|
-
}
|
8994
|
-
function getTypeOfAugmentedAssignment(node, inferenceContext) {
|
8995
|
-
const operatorMap = {
|
8996
|
-
[1 /* AddEqual */]: ['__iadd__', 0 /* Add */],
|
8997
|
-
[34 /* SubtractEqual */]: ['__isub__', 33 /* Subtract */],
|
8998
|
-
[27 /* MultiplyEqual */]: ['__imul__', 26 /* Multiply */],
|
8999
|
-
[14 /* FloorDivideEqual */]: ['__ifloordiv__', 13 /* FloorDivide */],
|
9000
|
-
[11 /* DivideEqual */]: ['__itruediv__', 10 /* Divide */],
|
9001
|
-
[25 /* ModEqual */]: ['__imod__', 24 /* Mod */],
|
9002
|
-
[30 /* PowerEqual */]: ['__ipow__', 29 /* Power */],
|
9003
|
-
[23 /* MatrixMultiplyEqual */]: ['__imatmul__', 22 /* MatrixMultiply */],
|
9004
|
-
[4 /* BitwiseAndEqual */]: ['__iand__', 3 /* BitwiseAnd */],
|
9005
|
-
[7 /* BitwiseOrEqual */]: ['__ior__', 6 /* BitwiseOr */],
|
9006
|
-
[9 /* BitwiseXorEqual */]: ['__ixor__', 8 /* BitwiseXor */],
|
9007
|
-
[18 /* LeftShiftEqual */]: ['__ilshift__', 17 /* LeftShift */],
|
9008
|
-
[32 /* RightShiftEqual */]: ['__irshift__', 31 /* RightShift */],
|
9009
|
-
};
|
9010
|
-
let type;
|
9011
|
-
let typeResult;
|
9012
|
-
const diag = new diagnostic_1.DiagnosticAddendum();
|
9013
|
-
const leftTypeResult = getTypeOfExpression(node.leftExpression);
|
9014
|
-
const leftType = leftTypeResult.type;
|
9015
|
-
let expectedOperandType;
|
9016
|
-
if (node.operator === 7 /* BitwiseOrEqual */) {
|
9017
|
-
// If this is a bitwise or ("|="), use the type of the left operand. This allows
|
9018
|
-
// us to support the case where a TypedDict is being updated with a dict expression.
|
9019
|
-
expectedOperandType = leftType;
|
9020
|
-
}
|
9021
|
-
const rightTypeResult = getTypeOfExpression(node.rightExpression,
|
9022
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedOperandType));
|
9023
|
-
const rightType = rightTypeResult.type;
|
9024
|
-
const isIncomplete = !!rightTypeResult.isIncomplete || !!leftTypeResult.isIncomplete;
|
9025
|
-
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
9026
|
-
typeResult = { type: types_1.NeverType.createNever(), isIncomplete };
|
9027
|
-
}
|
9028
|
-
else {
|
9029
|
-
type = mapSubtypesExpandTypeVars(leftType,
|
9030
|
-
/* conditionFilter */ undefined, (leftSubtypeExpanded, leftSubtypeUnexpanded) => {
|
9031
|
-
return mapSubtypesExpandTypeVars(rightType, (0, typeUtils_1.getTypeCondition)(leftSubtypeExpanded), (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
|
9032
|
-
if ((0, types_1.isAnyOrUnknown)(leftSubtypeUnexpanded) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
|
9033
|
-
return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
|
9034
|
-
}
|
9035
|
-
const magicMethodName = operatorMap[node.operator][0];
|
9036
|
-
let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
|
9037
|
-
if (!returnType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
9038
|
-
// Try with the expanded left type.
|
9039
|
-
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
|
9040
|
-
}
|
9041
|
-
if (!returnType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
9042
|
-
// Try with the expanded left and right type.
|
9043
|
-
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
|
9044
|
-
}
|
9045
|
-
if (!returnType) {
|
9046
|
-
// If the LHS class didn't support the magic method for augmented
|
9047
|
-
// assignment, fall back on the normal binary expression evaluator.
|
9048
|
-
const binaryOperator = operatorMap[node.operator][1];
|
9049
|
-
// Don't use literal math if either of the operation is within a loop
|
9050
|
-
// because the literal values may change each time.
|
9051
|
-
const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node) &&
|
9052
|
-
(0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) <
|
9053
|
-
maxLiteralMathSubtypeCount;
|
9054
|
-
// Don't special-case tuple __add__ if the left type is a union. This
|
9055
|
-
// can result in an infinite loop if we keep creating new tuple types
|
9056
|
-
// within a loop construct using __add__.
|
9057
|
-
const isTupleAddAllowed = !(0, types_1.isUnion)(leftType);
|
9058
|
-
returnType = validateBinaryOperation(binaryOperator, { type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }, { type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }, node, inferenceContext, diag, { isLiteralMathAllowed, isTupleAddAllowed });
|
9059
|
-
}
|
9060
|
-
return returnType;
|
9061
|
-
});
|
9062
|
-
});
|
9063
|
-
// If the LHS class didn't support the magic method for augmented
|
9064
|
-
// assignment, fall back on the normal binary expression evaluator.
|
9065
|
-
if (!diag.isEmpty() || !type || (0, types_1.isNever)(type)) {
|
9066
|
-
if (!isIncomplete) {
|
9067
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
9068
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
|
9069
|
-
operator: ParseTreeUtils.printOperator(node.operator),
|
9070
|
-
leftType: printType(leftType),
|
9071
|
-
rightType: printType(rightType),
|
9072
|
-
}) + diag.getString(), node);
|
9073
|
-
}
|
9074
|
-
type = types_1.UnknownType.create();
|
9075
|
-
}
|
9076
|
-
typeResult = { type, isIncomplete };
|
9077
|
-
}
|
9078
|
-
assignTypeToExpression(node.destExpression, typeResult.type, !!typeResult.isIncomplete, node.rightExpression);
|
9079
|
-
return typeResult;
|
9080
|
-
}
|
9081
|
-
function validateBinaryOperation(operator, leftTypeResult, rightTypeResult, errorNode, inferenceContext, diag, options) {
|
9082
|
-
const leftType = leftTypeResult.type;
|
9083
|
-
const rightType = rightTypeResult.type;
|
9084
|
-
let type;
|
9085
|
-
let concreteLeftType = makeTopLevelTypeVarsConcrete(leftType);
|
9086
|
-
if (booleanOperatorMap[operator] !== undefined) {
|
9087
|
-
// If it's an AND or OR, we need to handle short-circuiting by
|
9088
|
-
// eliminating any known-truthy or known-falsy types.
|
9089
|
-
if (operator === 36 /* And */) {
|
9090
|
-
// If the LHS evaluates to falsy, the And expression will
|
9091
|
-
// always return the type of the left-hand side.
|
9092
|
-
if (!canBeTruthy(concreteLeftType)) {
|
9093
|
-
return leftType;
|
9094
|
-
}
|
9095
|
-
// If the LHS evaluates to truthy, the And expression will
|
9096
|
-
// always return the type of the right-hand side.
|
9097
|
-
if (!canBeFalsy(concreteLeftType)) {
|
9098
|
-
return rightType;
|
9099
|
-
}
|
9100
|
-
concreteLeftType = removeTruthinessFromType(concreteLeftType);
|
9101
|
-
if ((0, types_1.isNever)(rightType)) {
|
9102
|
-
return concreteLeftType;
|
9103
|
-
}
|
9104
|
-
}
|
9105
|
-
else if (operator === 37 /* Or */) {
|
9106
|
-
// If the LHS evaluates to truthy, the Or expression will
|
9107
|
-
// always return the type of the left-hand side.
|
9108
|
-
if (!canBeFalsy(concreteLeftType)) {
|
9109
|
-
return leftType;
|
9110
|
-
}
|
9111
|
-
// If the LHS evaluates to falsy, the Or expression will
|
9112
|
-
// always return the type of the right-hand side.
|
9113
|
-
if (!canBeTruthy(concreteLeftType)) {
|
9114
|
-
return rightType;
|
9115
|
-
}
|
9116
|
-
concreteLeftType = removeFalsinessFromType(concreteLeftType);
|
9117
|
-
if ((0, types_1.isNever)(rightType)) {
|
9118
|
-
return concreteLeftType;
|
9119
|
-
}
|
9120
|
-
}
|
9121
|
-
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
9122
|
-
return types_1.NeverType.createNever();
|
9123
|
-
}
|
9124
|
-
// The "in" and "not in" operators make use of the __contains__
|
9125
|
-
// magic method.
|
9126
|
-
if (operator === 41 /* In */ || operator === 42 /* NotIn */) {
|
9127
|
-
type = mapSubtypesExpandTypeVars(rightType,
|
9128
|
-
/* conditionFilter */ undefined, (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
|
9129
|
-
return mapSubtypesExpandTypeVars(concreteLeftType, (0, typeUtils_1.getTypeCondition)(rightSubtypeExpanded), (leftSubtype) => {
|
9130
|
-
var _a;
|
9131
|
-
if ((0, types_1.isAnyOrUnknown)(leftSubtype) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
|
9132
|
-
return (0, typeUtils_1.preserveUnknown)(leftSubtype, rightSubtypeExpanded);
|
9133
|
-
}
|
9134
|
-
let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], '__contains__', errorNode,
|
9135
|
-
/* inferenceContext */ undefined);
|
9136
|
-
if (!returnType) {
|
9137
|
-
// If __contains__ was not supported, fall back
|
9138
|
-
// on an iterable.
|
9139
|
-
const iteratorType = (_a = getTypeOfIterator({ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete },
|
9140
|
-
/* isAsync */ false,
|
9141
|
-
/* errorNode */ undefined)) === null || _a === void 0 ? void 0 : _a.type;
|
9142
|
-
if (iteratorType && assignType(iteratorType, leftSubtype)) {
|
9143
|
-
returnType = getBuiltInObject(errorNode, 'bool');
|
9144
|
-
}
|
9145
|
-
}
|
9146
|
-
if (!returnType) {
|
9147
|
-
diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
|
9148
|
-
operator: ParseTreeUtils.printOperator(operator),
|
9149
|
-
leftType: printType(leftSubtype),
|
9150
|
-
rightType: printType(rightSubtypeExpanded),
|
9151
|
-
}));
|
9152
|
-
}
|
9153
|
-
return returnType;
|
9154
|
-
});
|
9155
|
-
});
|
9156
|
-
// Assume that a bool is returned even if the type is unknown
|
9157
|
-
if (type && !(0, types_1.isNever)(type)) {
|
9158
|
-
type = getBuiltInObject(errorNode, 'bool');
|
9159
|
-
}
|
9160
|
-
}
|
9161
|
-
else {
|
9162
|
-
type = mapSubtypesExpandTypeVars(concreteLeftType,
|
9163
|
-
/* conditionFilter */ undefined, (leftSubtypeExpanded, leftSubtypeUnexpanded) => {
|
9164
|
-
return mapSubtypesExpandTypeVars(rightType, (0, typeUtils_1.getTypeCondition)(leftSubtypeExpanded), (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
|
9165
|
-
// If the operator is an AND or OR, we need to combine the two types.
|
9166
|
-
if (operator === 36 /* And */ || operator === 37 /* Or */) {
|
9167
|
-
return (0, types_1.combineTypes)([leftSubtypeUnexpanded, rightSubtypeUnexpanded]);
|
9168
|
-
}
|
9169
|
-
// The other boolean operators always return a bool value.
|
9170
|
-
return getBuiltInObject(errorNode, 'bool');
|
9171
|
-
});
|
9172
|
-
});
|
9173
|
-
}
|
9174
|
-
}
|
9175
|
-
else if (binaryOperatorMap[operator]) {
|
9176
|
-
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
9177
|
-
return types_1.NeverType.createNever();
|
9178
|
-
}
|
9179
|
-
// Handle certain operations on certain homogenous literal types
|
9180
|
-
// using special-case math. For example, Literal[1, 2] + Literal[3, 4]
|
9181
|
-
// should result in Literal[4, 5, 6].
|
9182
|
-
if (options.isLiteralMathAllowed) {
|
9183
|
-
const leftLiteralClassName = (0, typeUtils_1.getLiteralTypeClassName)(leftType);
|
9184
|
-
if (leftLiteralClassName && !(0, typeUtils_1.getTypeCondition)(leftType)) {
|
9185
|
-
const rightLiteralClassName = (0, typeUtils_1.getLiteralTypeClassName)(rightType);
|
9186
|
-
if (leftLiteralClassName === rightLiteralClassName &&
|
9187
|
-
!(0, typeUtils_1.getTypeCondition)(rightType) &&
|
9188
|
-
(0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) < maxLiteralMathSubtypeCount) {
|
9189
|
-
if (leftLiteralClassName === 'str' || leftLiteralClassName === 'bytes') {
|
9190
|
-
if (operator === 0 /* Add */) {
|
9191
|
-
type = (0, typeUtils_1.mapSubtypes)(leftType, (leftSubtype) => {
|
9192
|
-
return (0, typeUtils_1.mapSubtypes)(rightType, (rightSubtype) => {
|
9193
|
-
const leftClassSubtype = leftSubtype;
|
9194
|
-
const rightClassSubtype = rightSubtype;
|
9195
|
-
return types_1.ClassType.cloneWithLiteral(leftClassSubtype, (leftClassSubtype.literalValue +
|
9196
|
-
rightClassSubtype.literalValue));
|
9197
|
-
});
|
9198
|
-
});
|
9199
|
-
}
|
9200
|
-
}
|
9201
|
-
else if (leftLiteralClassName === 'int') {
|
9202
|
-
if (operator === 0 /* Add */ ||
|
9203
|
-
operator === 33 /* Subtract */ ||
|
9204
|
-
operator === 26 /* Multiply */ ||
|
9205
|
-
operator === 13 /* FloorDivide */ ||
|
9206
|
-
operator === 24 /* Mod */) {
|
9207
|
-
let isValidResult = true;
|
9208
|
-
type = (0, typeUtils_1.mapSubtypes)(leftType, (leftSubtype) => {
|
9209
|
-
return (0, typeUtils_1.mapSubtypes)(rightType, (rightSubtype) => {
|
9210
|
-
try {
|
9211
|
-
const leftClassSubtype = leftSubtype;
|
9212
|
-
const rightClassSubtype = rightSubtype;
|
9213
|
-
const leftLiteralValue = BigInt(leftClassSubtype.literalValue);
|
9214
|
-
const rightLiteralValue = BigInt(rightClassSubtype.literalValue);
|
9215
|
-
let newValue;
|
9216
|
-
if (operator === 0 /* Add */) {
|
9217
|
-
newValue = leftLiteralValue + rightLiteralValue;
|
9218
|
-
}
|
9219
|
-
else if (operator === 33 /* Subtract */) {
|
9220
|
-
newValue = leftLiteralValue - rightLiteralValue;
|
9221
|
-
}
|
9222
|
-
else if (operator === 26 /* Multiply */) {
|
9223
|
-
newValue = leftLiteralValue * rightLiteralValue;
|
9224
|
-
}
|
9225
|
-
else if (operator === 13 /* FloorDivide */) {
|
9226
|
-
if (rightLiteralValue !== BigInt(0)) {
|
9227
|
-
newValue = leftLiteralValue / rightLiteralValue;
|
9228
|
-
}
|
9229
|
-
}
|
9230
|
-
else if (operator === 24 /* Mod */) {
|
9231
|
-
if (rightLiteralValue !== BigInt(0)) {
|
9232
|
-
newValue = leftLiteralValue % rightLiteralValue;
|
9233
|
-
}
|
9234
|
-
}
|
9235
|
-
if (newValue === undefined) {
|
9236
|
-
isValidResult = false;
|
9237
|
-
return undefined;
|
9238
|
-
}
|
9239
|
-
else if (typeof newValue === 'number' && isNaN(newValue)) {
|
9240
|
-
isValidResult = false;
|
9241
|
-
return undefined;
|
9242
|
-
}
|
9243
|
-
else {
|
9244
|
-
// Convert back to a simple number if it fits. Leave as a bigint
|
9245
|
-
// if it doesn't.
|
9246
|
-
if (newValue >= Number.MIN_SAFE_INTEGER &&
|
9247
|
-
newValue <= Number.MAX_SAFE_INTEGER) {
|
9248
|
-
newValue = Number(newValue);
|
9249
|
-
}
|
9250
|
-
return types_1.ClassType.cloneWithLiteral(leftClassSubtype, newValue);
|
9251
|
-
}
|
9252
|
-
}
|
9253
|
-
catch {
|
9254
|
-
isValidResult = false;
|
9255
|
-
return undefined;
|
9256
|
-
}
|
9257
|
-
});
|
9258
|
-
});
|
9259
|
-
if (!isValidResult) {
|
9260
|
-
type = undefined;
|
9261
|
-
}
|
9262
|
-
}
|
9263
|
-
}
|
9264
|
-
}
|
9265
|
-
}
|
9266
|
-
}
|
9267
|
-
if (!type) {
|
9268
|
-
type = mapSubtypesExpandTypeVars(leftType,
|
9269
|
-
/* conditionFilter */ undefined, (leftSubtypeExpanded, leftSubtypeUnexpanded) => {
|
9270
|
-
return mapSubtypesExpandTypeVars(rightType, (0, typeUtils_1.getTypeCondition)(leftSubtypeExpanded), (rightSubtypeExpanded, rightSubtypeUnexpanded) => {
|
9271
|
-
if ((0, types_1.isAnyOrUnknown)(leftSubtypeUnexpanded) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
|
9272
|
-
return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
|
9273
|
-
}
|
9274
|
-
// Special-case __add__ for tuples when the types for both tuples are known.
|
9275
|
-
if (options.isTupleAddAllowed &&
|
9276
|
-
operator === 0 /* Add */ &&
|
9277
|
-
(0, types_1.isClassInstance)(leftSubtypeExpanded) &&
|
9278
|
-
(0, typeUtils_1.isTupleClass)(leftSubtypeExpanded) &&
|
9279
|
-
leftSubtypeExpanded.tupleTypeArguments &&
|
9280
|
-
!(0, typeUtils_1.isUnboundedTupleClass)(leftSubtypeExpanded) &&
|
9281
|
-
(0, types_1.isClassInstance)(rightSubtypeExpanded) &&
|
9282
|
-
(0, typeUtils_1.isTupleClass)(rightSubtypeExpanded) &&
|
9283
|
-
rightSubtypeExpanded.tupleTypeArguments &&
|
9284
|
-
!(0, typeUtils_1.isUnboundedTupleClass)(rightSubtypeExpanded) &&
|
9285
|
-
tupleClassType &&
|
9286
|
-
(0, types_1.isInstantiableClass)(tupleClassType)) {
|
9287
|
-
return types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeTupleClass)(tupleClassType, [
|
9288
|
-
...leftSubtypeExpanded.tupleTypeArguments,
|
9289
|
-
...rightSubtypeExpanded.tupleTypeArguments,
|
9290
|
-
]));
|
9291
|
-
}
|
9292
|
-
const magicMethodName = binaryOperatorMap[operator][0];
|
9293
|
-
let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
|
9294
|
-
if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
9295
|
-
// Try the expanded left type.
|
9296
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
|
9297
|
-
}
|
9298
|
-
if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
9299
|
-
// Try the expanded left and right type.
|
9300
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
|
9301
|
-
}
|
9302
|
-
if (!resultType) {
|
9303
|
-
// Try the alternate form (swapping right and left).
|
9304
|
-
const altMagicMethodName = binaryOperatorMap[operator][1];
|
9305
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, inferenceContext);
|
9306
|
-
if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
9307
|
-
// Try the expanded right type.
|
9308
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [
|
9309
|
-
{
|
9310
|
-
type: leftSubtypeUnexpanded,
|
9311
|
-
isIncomplete: leftTypeResult.isIncomplete,
|
9312
|
-
},
|
9313
|
-
], altMagicMethodName, errorNode, inferenceContext);
|
9314
|
-
}
|
9315
|
-
if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
9316
|
-
// Try the expanded right and left type.
|
9317
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, inferenceContext);
|
9318
|
-
}
|
9319
|
-
}
|
9320
|
-
if (!resultType) {
|
9321
|
-
if (inferenceContext) {
|
9322
|
-
diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperatorBidirectional().format({
|
9323
|
-
operator: ParseTreeUtils.printOperator(operator),
|
9324
|
-
leftType: printType(leftSubtypeExpanded),
|
9325
|
-
rightType: printType(rightSubtypeExpanded),
|
9326
|
-
expectedType: printType(inferenceContext.expectedType),
|
9327
|
-
}));
|
9328
|
-
}
|
9329
|
-
else {
|
9330
|
-
diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperator().format({
|
9331
|
-
operator: ParseTreeUtils.printOperator(operator),
|
9332
|
-
leftType: printType(leftSubtypeExpanded),
|
9333
|
-
rightType: printType(rightSubtypeExpanded),
|
9334
|
-
}));
|
9335
|
-
}
|
9336
|
-
}
|
9337
|
-
return resultType;
|
9338
|
-
});
|
9339
|
-
});
|
9340
|
-
}
|
9341
|
-
}
|
9342
|
-
return type && (0, types_1.isNever)(type) ? undefined : type;
|
9343
|
-
}
|
9344
8293
|
function getTypeOfMagicMethodReturn(objType, args, magicMethodName, errorNode, inferenceContext) {
|
9345
8294
|
let magicMethodSupported = true;
|
9346
8295
|
// Create a helper lambda for object subtypes.
|
@@ -9415,17 +8364,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9415
8364
|
}
|
9416
8365
|
return returnType;
|
9417
8366
|
}
|
9418
|
-
// All functions in Python derive from object, so they inherit all
|
9419
|
-
// of the capabilities of an object. This function converts a function
|
9420
|
-
// to an object instance.
|
9421
|
-
function convertFunctionToObject(type) {
|
9422
|
-
if ((0, types_1.isFunction)(type) || (0, types_1.isOverloadedFunction)(type)) {
|
9423
|
-
if (objectType) {
|
9424
|
-
return objectType;
|
9425
|
-
}
|
9426
|
-
}
|
9427
|
-
return type;
|
9428
|
-
}
|
9429
8367
|
function getTypeOfDictionary(node, inferenceContext) {
|
9430
8368
|
// If the expected type is a union, analyze for each of the subtypes
|
9431
8369
|
// to find one that matches.
|
@@ -9501,7 +8439,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9501
8439
|
return undefined;
|
9502
8440
|
}
|
9503
8441
|
const dictTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInDict));
|
9504
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, getTypeVarScopesForNode(node))) {
|
8442
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
|
9505
8443
|
return undefined;
|
9506
8444
|
}
|
9507
8445
|
const specializedDict = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInDict), dictTypeVarContext);
|
@@ -9763,7 +8701,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9763
8701
|
return undefined;
|
9764
8702
|
}
|
9765
8703
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInListOrSet));
|
9766
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(node))) {
|
8704
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
|
9767
8705
|
return undefined;
|
9768
8706
|
}
|
9769
8707
|
const specializedListOrSet = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInListOrSet), typeVarContext);
|
@@ -9909,35 +8847,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9909
8847
|
}
|
9910
8848
|
return inferenceContext.expectedType;
|
9911
8849
|
}
|
9912
|
-
function getTypeOfTernary(node, flags, inferenceContext) {
|
9913
|
-
getTypeOfExpression(node.testExpression);
|
9914
|
-
const typesToCombine = [];
|
9915
|
-
let isIncomplete = false;
|
9916
|
-
let typeErrors = false;
|
9917
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
9918
|
-
const constExprValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(node.testExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
|
9919
|
-
if (constExprValue !== false && isNodeReachable(node.ifExpression)) {
|
9920
|
-
const ifType = getTypeOfExpression(node.ifExpression, flags, inferenceContext);
|
9921
|
-
typesToCombine.push(ifType.type);
|
9922
|
-
if (ifType.isIncomplete) {
|
9923
|
-
isIncomplete = true;
|
9924
|
-
}
|
9925
|
-
if (ifType.typeErrors) {
|
9926
|
-
typeErrors = true;
|
9927
|
-
}
|
9928
|
-
}
|
9929
|
-
if (constExprValue !== true && isNodeReachable(node.elseExpression)) {
|
9930
|
-
const elseType = getTypeOfExpression(node.elseExpression, flags, inferenceContext);
|
9931
|
-
typesToCombine.push(elseType.type);
|
9932
|
-
if (elseType.isIncomplete) {
|
9933
|
-
isIncomplete = true;
|
9934
|
-
}
|
9935
|
-
if (elseType.typeErrors) {
|
9936
|
-
typeErrors = true;
|
9937
|
-
}
|
9938
|
-
}
|
9939
|
-
return { type: (0, types_1.combineTypes)(typesToCombine), isIncomplete, typeErrors };
|
9940
|
-
}
|
9941
8850
|
function getTypeOfYield(node) {
|
9942
8851
|
let expectedYieldType;
|
9943
8852
|
let sentType;
|
@@ -9990,7 +8899,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9990
8899
|
function getTypeOfLambda(node, inferenceContext) {
|
9991
8900
|
let isIncomplete = !!(inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete);
|
9992
8901
|
const functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* PartiallyEvaluated */);
|
9993
|
-
functionType.details.typeVarScopeId = getScopeIdForNode(node);
|
8902
|
+
functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
|
9994
8903
|
// Pre-cache the incomplete function type in case the evaluation of the
|
9995
8904
|
// lambda depends on itself.
|
9996
8905
|
writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
|
@@ -10096,19 +9005,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10096
9005
|
isIncomplete = true;
|
10097
9006
|
}
|
10098
9007
|
};
|
10099
|
-
|
10100
|
-
|
10101
|
-
|
10102
|
-
|
10103
|
-
|
10104
|
-
useSpeculativeMode(node.expression, () => {
|
10105
|
-
inferLambdaReturnType();
|
10106
|
-
},
|
10107
|
-
/* allowCacheRetention */ false);
|
10108
|
-
}
|
10109
|
-
else {
|
9008
|
+
// We need to set allowCacheRetention to false because we don't want to
|
9009
|
+
// cache the type of the lambda return expression because it depends on
|
9010
|
+
// the parameter types that we set above, and the speculative type cache
|
9011
|
+
// doesn't know about that context.
|
9012
|
+
useSpeculativeMode(isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete) ? node.expression : undefined, () => {
|
10110
9013
|
inferLambdaReturnType();
|
10111
|
-
}
|
9014
|
+
},
|
9015
|
+
/* allowCacheRetention */ false);
|
10112
9016
|
// Mark the function type as no longer being evaluated.
|
10113
9017
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
10114
9018
|
return { type: functionType, isIncomplete };
|
@@ -10201,7 +9105,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10201
9105
|
// Evaluate the test expression to validate it and mark symbols
|
10202
9106
|
// as referenced. Don't bother doing this if we're in speculative
|
10203
9107
|
// mode because it doesn't affect the element type.
|
10204
|
-
if (!
|
9108
|
+
if (!isSpeculativeModeInUse(node.testExpression)) {
|
10205
9109
|
getTypeOfExpression(node.testExpression);
|
10206
9110
|
}
|
10207
9111
|
}
|
@@ -10268,7 +9172,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10268
9172
|
function getTypeOfSlice(node) {
|
10269
9173
|
// Evaluate the expressions to report errors and record symbol
|
10270
9174
|
// references. We can skip this if we're executing speculatively.
|
10271
|
-
if (!
|
9175
|
+
if (!isSpeculativeModeInUse(node)) {
|
10272
9176
|
if (node.startValue) {
|
10273
9177
|
getTypeOfExpression(node.startValue);
|
10274
9178
|
}
|
@@ -10341,7 +9245,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10341
9245
|
const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
|
10342
9246
|
types_1.TypeBase.setSpecialForm(functionType);
|
10343
9247
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
10344
|
-
functionType.details.typeVarScopeId = getScopeIdForNode(errorNode);
|
9248
|
+
functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(errorNode);
|
10345
9249
|
if (typeArgs && typeArgs.length > 0) {
|
10346
9250
|
if (typeArgs[0].typeList) {
|
10347
9251
|
const typeList = typeArgs[0].typeList;
|
@@ -11035,7 +9939,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11035
9939
|
}), errorNode);
|
11036
9940
|
}
|
11037
9941
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(name);
|
11038
|
-
const typeAliasScopeId = getScopeIdForNode(name);
|
9942
|
+
const typeAliasScopeId = ParseTreeUtils.getScopeIdForNode(name);
|
11039
9943
|
const boundTypeVars = typeParameters.filter((typeVar) => typeVar.scopeId !== typeAliasScopeId && typeVar.scopeType === 0 /* Class */);
|
11040
9944
|
if (boundTypeVars.length > 0) {
|
11041
9945
|
addError(localize_1.Localizer.Diagnostic.genericTypeAliasBoundTypeVar().format({
|
@@ -11256,7 +10160,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11256
10160
|
typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${typeAliasNameNode.value}`);
|
11257
10161
|
typeAliasTypeVar.details.isSynthesized = true;
|
11258
10162
|
typeAliasTypeVar.details.recursiveTypeAliasName = typeAliasNameNode.value;
|
11259
|
-
const scopeId = getScopeIdForNode(typeAliasNameNode);
|
10163
|
+
const scopeId = ParseTreeUtils.getScopeIdForNode(typeAliasNameNode);
|
11260
10164
|
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
11261
10165
|
typeAliasTypeVar.scopeId = scopeId;
|
11262
10166
|
// Write the type back to the type cache. It will be replaced below.
|
@@ -11365,7 +10269,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11365
10269
|
const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${node.name.value}`);
|
11366
10270
|
typeAliasTypeVar.details.isSynthesized = true;
|
11367
10271
|
typeAliasTypeVar.details.recursiveTypeAliasName = node.name.value;
|
11368
|
-
const scopeId = getScopeIdForNode(node.name);
|
10272
|
+
const scopeId = ParseTreeUtils.getScopeIdForNode(node.name);
|
11369
10273
|
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
11370
10274
|
typeAliasTypeVar.scopeId = scopeId;
|
11371
10275
|
// Write the type to the type cache. It will be replaced below.
|
@@ -11408,7 +10312,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11408
10312
|
if (isTypeCached(node)) {
|
11409
10313
|
return;
|
11410
10314
|
}
|
11411
|
-
const destTypeResult = getTypeOfAugmentedAssignment(node, /* inferenceContext */ undefined);
|
10315
|
+
const destTypeResult = (0, operations_1.getTypeOfAugmentedAssignment)(evaluatorInterface, node, /* inferenceContext */ undefined);
|
11412
10316
|
writeTypeCache(node, destTypeResult, 0 /* None */);
|
11413
10317
|
}
|
11414
10318
|
function getPseudoGenericTypeVarName(paramName) {
|
@@ -11454,7 +10358,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11454
10358
|
/* typeSourceId */ 0,
|
11455
10359
|
/* declaredMetaclass */ undefined,
|
11456
10360
|
/* effectiveMetaclass */ undefined, ParseTreeUtils.getDocString(node.suite.statements));
|
11457
|
-
classType.details.typeVarScopeId = getScopeIdForNode(node);
|
10361
|
+
classType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
|
11458
10362
|
// Some classes refer to themselves within type arguments used within
|
11459
10363
|
// base classes. We'll register the partially-constructed class type
|
11460
10364
|
// to allow these to be resolved.
|
@@ -11771,9 +10675,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11771
10675
|
classType.details.typeParameters = genericParams.map((param) => {
|
11772
10676
|
const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
|
11773
10677
|
typeVar.details.isSynthesized = true;
|
11774
|
-
typeVar.scopeId = getScopeIdForNode(initDeclNode);
|
10678
|
+
typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
|
11775
10679
|
typeVar.details.boundType = types_1.UnknownType.create();
|
11776
|
-
return types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
10680
|
+
return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
11777
10681
|
});
|
11778
10682
|
}
|
11779
10683
|
}
|
@@ -11903,11 +10807,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11903
10807
|
writeTypeCache(node.name, { type: classType }, 0 /* None */);
|
11904
10808
|
// Update the decorated class type.
|
11905
10809
|
writeTypeCache(node, { type: decoratedType }, 0 /* None */);
|
11906
|
-
// Stash away a reference to the UnionType class if we encounter it.
|
11907
|
-
// There's no easy way to otherwise reference it.
|
11908
|
-
if (types_1.ClassType.isBuiltIn(classType, 'UnionType')) {
|
11909
|
-
unionType = types_1.ClassType.cloneAsInstance(classType);
|
11910
|
-
}
|
11911
10810
|
// Validate that arguments passed to `__init_subclass__` are of the correct type.
|
11912
10811
|
// Defer this if the metaclass calculation is deferred.
|
11913
10812
|
if (!isMetaclassDeferred) {
|
@@ -12342,10 +11241,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12342
11241
|
functionFlags |= 512 /* Async */;
|
12343
11242
|
}
|
12344
11243
|
const functionType = types_1.FunctionType.createInstance(node.name.value, getFunctionFullName(node, fileInfo.moduleName, node.name.value), fileInfo.moduleName, functionFlags | 131072 /* PartiallyEvaluated */, ParseTreeUtils.getDocString(node.suite.statements));
|
12345
|
-
functionType.details.typeVarScopeId = getScopeIdForNode(node);
|
11244
|
+
functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
|
12346
11245
|
if (node.name.value === '__init__' || node.name.value === '__new__') {
|
12347
11246
|
if (containingClassNode) {
|
12348
|
-
functionType.details.constructorTypeVarScopeId = getScopeIdForNode(containingClassNode);
|
11247
|
+
functionType.details.constructorTypeVarScopeId = ParseTreeUtils.getScopeIdForNode(containingClassNode);
|
12349
11248
|
}
|
12350
11249
|
}
|
12351
11250
|
if (fileInfo.isBuiltInStubFile || fileInfo.isTypingStubFile || fileInfo.isTypingExtensionsStubFile) {
|
@@ -14697,10 +13596,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14697
13596
|
throw e;
|
14698
13597
|
}
|
14699
13598
|
}
|
14700
|
-
// Disables recording of errors and warnings and disables
|
14701
|
-
//
|
14702
|
-
//
|
13599
|
+
// Disables recording of errors and warnings and disables any caching of
|
13600
|
+
// types, under the assumption that we're performing speculative evaluations.
|
13601
|
+
// If speculativeNode is undefined, speculative mode is not used. This is
|
13602
|
+
// useful in cases where we conditionally want to use speculative mode.
|
14703
13603
|
function useSpeculativeMode(speculativeNode, callback, allowCacheRetention = true) {
|
13604
|
+
if (!speculativeNode) {
|
13605
|
+
return callback();
|
13606
|
+
}
|
14704
13607
|
speculativeTypeTracker.enterSpeculativeContext(speculativeNode, allowCacheRetention);
|
14705
13608
|
try {
|
14706
13609
|
const result = callback();
|
@@ -14727,6 +13630,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14727
13630
|
throw e;
|
14728
13631
|
}
|
14729
13632
|
}
|
13633
|
+
// Indicates whether the specified node is within a context that
|
13634
|
+
// is currently being evaluated speculative. If node is undefined,
|
13635
|
+
// returns true if any node is being evaluated speculatively.
|
13636
|
+
function isSpeculativeModeInUse(node) {
|
13637
|
+
return speculativeTypeTracker.isSpeculative(node);
|
13638
|
+
}
|
14730
13639
|
function getDeclarationFromFunctionNamedParameter(type, paramName) {
|
14731
13640
|
if ((0, types_1.isFunction)(type)) {
|
14732
13641
|
if (type.details.declaration) {
|
@@ -15156,7 +14065,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15156
14065
|
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
15157
14066
|
scopeType = 2 /* TypeAlias */;
|
15158
14067
|
}
|
15159
|
-
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
14068
|
+
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
15160
14069
|
}
|
15161
14070
|
return typeVar;
|
15162
14071
|
}
|
@@ -15582,7 +14491,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15582
14491
|
}
|
15583
14492
|
}
|
15584
14493
|
typesToCombine.push(type);
|
15585
|
-
if (
|
14494
|
+
if (isSpeculativeModeInUse(decl.node)) {
|
15586
14495
|
includesSpeculativeResult = true;
|
15587
14496
|
}
|
15588
14497
|
}
|
@@ -16644,11 +15553,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16644
15553
|
}
|
16645
15554
|
return true;
|
16646
15555
|
}
|
16647
|
-
// Handle the special case where the expression is an actual
|
16648
|
-
// UnionType special form.
|
16649
|
-
if ((0, types_1.isUnion)(srcType) && types_1.TypeBase.isSpecialForm(srcType)) {
|
16650
|
-
srcType = unionType || objectType || types_1.AnyType.create();
|
16651
|
-
}
|
16652
15556
|
if ((0, types_1.isUnion)(destType)) {
|
16653
15557
|
if ((0, types_1.isUnion)(srcType)) {
|
16654
15558
|
if (assignFromUnionType(destType, srcType,
|
@@ -16875,7 +15779,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16875
15779
|
}
|
16876
15780
|
// If it's a class, use the constructor for type compatibility checking.
|
16877
15781
|
if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
|
16878
|
-
const constructor = createFunctionFromConstructor(concreteSrcType, recursionCount);
|
15782
|
+
const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
|
16879
15783
|
if (constructor) {
|
16880
15784
|
concreteSrcType = constructor;
|
16881
15785
|
}
|
@@ -17322,98 +16226,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17322
16226
|
});
|
17323
16227
|
});
|
17324
16228
|
}
|
17325
|
-
// Synthesize a function that represents the constructor for this class
|
17326
|
-
// taking into consideration the __init__ and __new__ methods.
|
17327
|
-
function createFunctionFromConstructor(classType, recursionCount = 0) {
|
17328
|
-
// Use the __init__ method if available. It's usually more detailed.
|
17329
|
-
const initInfo = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 8 /* SkipInstanceVariables */ | 4 /* SkipObjectBaseClass */);
|
17330
|
-
if (initInfo) {
|
17331
|
-
const initType = getTypeOfMember(initInfo);
|
17332
|
-
const objectType = types_1.ClassType.cloneAsInstance(classType);
|
17333
|
-
const convertInitToConstructor = (initSubtype) => {
|
17334
|
-
let constructorFunction = bindFunctionToClassOrObject(objectType, initSubtype,
|
17335
|
-
/* memberClass */ undefined,
|
17336
|
-
/* errorNode */ undefined, recursionCount);
|
17337
|
-
if (constructorFunction) {
|
17338
|
-
constructorFunction = types_1.FunctionType.clone(constructorFunction);
|
17339
|
-
constructorFunction.details.declaredReturnType = objectType;
|
17340
|
-
if (constructorFunction.specializedTypes) {
|
17341
|
-
constructorFunction.specializedTypes.returnType = objectType;
|
17342
|
-
}
|
17343
|
-
if (!constructorFunction.details.docString && classType.details.docString) {
|
17344
|
-
constructorFunction.details.docString = classType.details.docString;
|
17345
|
-
}
|
17346
|
-
constructorFunction.details.flags &= ~4 /* StaticMethod */;
|
17347
|
-
}
|
17348
|
-
return constructorFunction;
|
17349
|
-
};
|
17350
|
-
if ((0, types_1.isFunction)(initType)) {
|
17351
|
-
return convertInitToConstructor(initType);
|
17352
|
-
}
|
17353
|
-
else if ((0, types_1.isOverloadedFunction)(initType)) {
|
17354
|
-
const initOverloads = [];
|
17355
|
-
initType.overloads.forEach((overload) => {
|
17356
|
-
const converted = convertInitToConstructor(overload);
|
17357
|
-
if (converted) {
|
17358
|
-
initOverloads.push(converted);
|
17359
|
-
}
|
17360
|
-
});
|
17361
|
-
if (initOverloads.length === 0) {
|
17362
|
-
return undefined;
|
17363
|
-
}
|
17364
|
-
else if (initOverloads.length === 1) {
|
17365
|
-
return initOverloads[0];
|
17366
|
-
}
|
17367
|
-
return types_1.OverloadedFunctionType.create(initOverloads);
|
17368
|
-
}
|
17369
|
-
}
|
17370
|
-
// Fall back on the __new__ method if __init__ isn't available.
|
17371
|
-
const newInfo = (0, typeUtils_1.lookUpClassMember)(classType, '__new__', 8 /* SkipInstanceVariables */ | 4 /* SkipObjectBaseClass */);
|
17372
|
-
if (newInfo) {
|
17373
|
-
const newType = getTypeOfMember(newInfo);
|
17374
|
-
const convertNewToConstructor = (newSubtype) => {
|
17375
|
-
let constructorFunction = bindFunctionToClassOrObject(classType, newSubtype,
|
17376
|
-
/* memberClass */ undefined,
|
17377
|
-
/* errorNode */ undefined, recursionCount,
|
17378
|
-
/* treatConstructorAsClassMember */ true);
|
17379
|
-
if (constructorFunction) {
|
17380
|
-
constructorFunction = types_1.FunctionType.clone(constructorFunction);
|
17381
|
-
if (!constructorFunction.details.docString && classType.details.docString) {
|
17382
|
-
constructorFunction.details.docString = classType.details.docString;
|
17383
|
-
}
|
17384
|
-
constructorFunction.details.flags &= ~(4 /* StaticMethod */ | 1 /* ConstructorMethod */);
|
17385
|
-
}
|
17386
|
-
return constructorFunction;
|
17387
|
-
};
|
17388
|
-
if ((0, types_1.isFunction)(newType)) {
|
17389
|
-
return convertNewToConstructor(newType);
|
17390
|
-
}
|
17391
|
-
else if ((0, types_1.isOverloadedFunction)(newType)) {
|
17392
|
-
const newOverloads = [];
|
17393
|
-
newType.overloads.forEach((overload) => {
|
17394
|
-
const converted = convertNewToConstructor(overload);
|
17395
|
-
if (converted) {
|
17396
|
-
newOverloads.push(converted);
|
17397
|
-
}
|
17398
|
-
});
|
17399
|
-
if (newOverloads.length === 0) {
|
17400
|
-
return undefined;
|
17401
|
-
}
|
17402
|
-
else if (newOverloads.length === 1) {
|
17403
|
-
return newOverloads[0];
|
17404
|
-
}
|
17405
|
-
return types_1.OverloadedFunctionType.create(newOverloads);
|
17406
|
-
}
|
17407
|
-
}
|
17408
|
-
// Return a generic constructor.
|
17409
|
-
const constructorFunction = types_1.FunctionType.createSynthesizedInstance('__new__', 0 /* None */);
|
17410
|
-
constructorFunction.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
|
17411
|
-
types_1.FunctionType.addDefaultParameters(constructorFunction);
|
17412
|
-
if (!constructorFunction.details.docString && classType.details.docString) {
|
17413
|
-
constructorFunction.details.docString = classType.details.docString;
|
17414
|
-
}
|
17415
|
-
return constructorFunction;
|
17416
|
-
}
|
17417
16229
|
// If the class is a protocol and it has a `__call__` method but no other methods
|
17418
16230
|
// or attributes that would be incompatible with a function, this method returns
|
17419
16231
|
// the signature of the call implied by the `__call__` method. Otherwise it returns
|
@@ -18840,7 +17652,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18840
17652
|
getGetterTypeFromProperty,
|
18841
17653
|
getTypeOfArgument,
|
18842
17654
|
markNamesAccessed,
|
18843
|
-
getScopeIdForNode,
|
18844
17655
|
makeTopLevelTypeVarsConcrete,
|
18845
17656
|
mapSubtypesExpandTypeVars,
|
18846
17657
|
lookUpSymbolRecursive,
|
@@ -18855,6 +17666,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18855
17666
|
getBuiltInType,
|
18856
17667
|
getTypeOfMember,
|
18857
17668
|
getTypeOfObjectMember,
|
17669
|
+
getTypeOfClassMemberName,
|
18858
17670
|
getBoundMethod,
|
18859
17671
|
getTypeOfMagicMethodReturn,
|
18860
17672
|
bindFunctionToClassOrObject,
|
@@ -18863,6 +17675,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18863
17675
|
narrowConstrainedTypeVar,
|
18864
17676
|
assignType,
|
18865
17677
|
validateOverrideMethod,
|
17678
|
+
validateCallArguments,
|
17679
|
+
validateTypeArg,
|
18866
17680
|
assignTypeToExpression,
|
18867
17681
|
assignClassToSelf,
|
18868
17682
|
getTypedDictClassType,
|
@@ -18889,6 +17703,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18889
17703
|
getTypeCacheEntryCount,
|
18890
17704
|
disposeEvaluator,
|
18891
17705
|
useSpeculativeMode,
|
17706
|
+
isSpeculativeModeInUse,
|
18892
17707
|
setTypeForNode,
|
18893
17708
|
checkForCancellation,
|
18894
17709
|
printControlFlowGraph,
|