@zzzen/pyright-internal 1.2.0-dev.20230430 → 1.2.0-dev.20230514
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 +4 -1
- 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 +89 -6
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +14 -15
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +6 -0
- package/dist/analyzer/constructors.js +513 -0
- package/dist/analyzer/constructors.js.map +1 -0
- package/dist/analyzer/dataClasses.js +86 -2
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/docStringConversion.js +1 -1
- package/dist/analyzer/docStringConversion.js.map +1 -1
- package/dist/analyzer/enums.js +62 -8
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importResolver.js +47 -29
- package/dist/analyzer/importResolver.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 +3 -6
- 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 +11 -33
- package/dist/analyzer/program.js +73 -735
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.js +1 -1
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +5 -21
- package/dist/analyzer/service.js +26 -33
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +9 -41
- package/dist/analyzer/sourceFile.js +219 -238
- 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/symbol.d.ts +3 -1
- package/dist/analyzer/symbol.js +5 -0
- package/dist/analyzer/symbol.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +460 -1425
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +42 -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/typePrinter.d.ts +3 -3
- package/dist/analyzer/typePrinter.js +247 -100
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +14 -7
- package/dist/analyzer/typeUtils.js +204 -49
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +6 -7
- package/dist/analyzer/typeVarContext.js +21 -32
- 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 +7 -4
- package/dist/analyzer/types.js +20 -10
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +1 -1
- package/dist/backgroundAnalysisBase.js +16 -0
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +0 -1
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/common/extensibility.d.ts +28 -4
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/logTracker.d.ts +2 -0
- package/dist/common/logTracker.js +8 -1
- package/dist/common/logTracker.js.map +1 -1
- package/dist/common/lspUtils.d.ts +4 -1
- package/dist/common/lspUtils.js +38 -1
- package/dist/common/lspUtils.js.map +1 -1
- package/dist/common/pathUtils.d.ts +11 -11
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/pythonVersion.d.ts +2 -1
- package/dist/common/pythonVersion.js +1 -0
- package/dist/common/pythonVersion.js.map +1 -1
- package/dist/common/workspaceEditUtils.d.ts +8 -8
- package/dist/common/workspaceEditUtils.js +10 -10
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +3 -7
- package/dist/languageServerBase.js +41 -73
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/autoImporter.d.ts +50 -51
- package/dist/languageService/autoImporter.js +125 -210
- package/dist/languageService/autoImporter.js.map +1 -1
- package/dist/languageService/callHierarchyProvider.d.ts +1 -1
- package/dist/languageService/callHierarchyProvider.js +11 -37
- package/dist/languageService/callHierarchyProvider.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +39 -81
- package/dist/languageService/completionProvider.js +572 -801
- 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 +47 -28
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/documentSymbolProvider.d.ts +13 -35
- package/dist/languageService/documentSymbolProvider.js +52 -264
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +5 -6
- package/dist/languageService/hoverProvider.js +40 -132
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/referencesProvider.d.ts +6 -11
- package/dist/languageService/referencesProvider.js +23 -17
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameProvider.d.ts +16 -0
- package/dist/languageService/renameProvider.js +139 -0
- package/dist/languageService/renameProvider.js.map +1 -0
- package/dist/languageService/symbolIndexer.d.ts +31 -0
- package/dist/languageService/symbolIndexer.js +105 -0
- package/dist/languageService/symbolIndexer.js.map +1 -0
- package/dist/languageService/tooltipUtils.d.ts +8 -1
- package/dist/languageService/tooltipUtils.js +102 -1
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/languageService/workspaceSymbolProvider.d.ts +17 -0
- package/dist/languageService/workspaceSymbolProvider.js +133 -0
- package/dist/languageService/workspaceSymbolProvider.js.map +1 -0
- package/dist/localization/localize.d.ts +33 -15
- package/dist/localization/localize.js +13 -7
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +14 -7
- package/dist/parser/parser.js +3 -0
- package/dist/parser/parser.js.map +1 -1
- package/dist/pyright.js +26 -4
- package/dist/pyright.js.map +1 -1
- package/dist/tests/chainedSourceFiles.test.js +15 -20
- package/dist/tests/chainedSourceFiles.test.js.map +1 -1
- package/dist/tests/checker.test.js +14 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/completions.test.js +11 -236
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/docStringConversion.test.js +36 -2
- package/dist/tests/docStringConversion.test.js.map +1 -1
- package/dist/tests/documentSymbolCollector.test.js +3 -3
- package/dist/tests/documentSymbolCollector.test.js.map +1 -1
- package/dist/tests/fourslash/completions.override2.fourslash.js +1 -16
- package/dist/tests/fourslash/completions.override2.fourslash.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 +17 -11
- package/dist/tests/harness/fourslash/testState.js +39 -50
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/importResolver.test.js +81 -1
- package/dist/tests/importResolver.test.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 +13 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +5 -1
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +9 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +25 -9
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/tests/workspaceEditUtils.test.js +95 -6
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/package.json +4 -4
- package/dist/languageService/importAdder.d.ts +0 -40
- package/dist/languageService/importAdder.js +0 -388
- package/dist/languageService/importAdder.js.map +0 -1
- 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/fourslash/completions.commitChars.fourslash.d.ts +0 -1
- package/dist/tests/fourslash/completions.commitChars.fourslash.js +0 -81
- package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +0 -1
- package/dist/tests/importAdder.test.d.ts +0 -1
- package/dist/tests/importAdder.test.js +0 -1325
- package/dist/tests/importAdder.test.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);
|
@@ -512,7 +446,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
512
446
|
}
|
513
447
|
}
|
514
448
|
function getTypeOfExpression(node, flags = 0 /* None */, inferenceContext) {
|
515
|
-
var _a
|
449
|
+
var _a;
|
516
450
|
// Is this type already cached?
|
517
451
|
const cacheEntry = readTypeCacheEntry(node);
|
518
452
|
if (cacheEntry &&
|
@@ -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 */: {
|
@@ -712,6 +646,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
712
646
|
}
|
713
647
|
}
|
714
648
|
writeTypeCache(node, typeResult, flags, inferenceContext, /* allowSpeculativeCaching */ true);
|
649
|
+
// If there was an expected type, make sure that the result type is compatible.
|
715
650
|
if (inferenceContext &&
|
716
651
|
!(0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) &&
|
717
652
|
!(0, types_1.isNever)(inferenceContext.expectedType)) {
|
@@ -719,9 +654,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
719
654
|
if (!typeResult.isIncomplete && !typeResult.expectedTypeDiagAddendum) {
|
720
655
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
721
656
|
// Make sure the resulting type is assignable to the expected type.
|
722
|
-
|
723
|
-
// it is provided.
|
724
|
-
if (!assignType(inferenceContext.expectedType, typeResult.type, diag, new typeVarContext_1.TypeVarContext((_b = inferenceContext.typeVarContext) === null || _b === void 0 ? void 0 : _b.getSolveForScopes()))) {
|
657
|
+
if (!assignType(inferenceContext.expectedType, typeResult.type, diag)) {
|
725
658
|
typeResult.typeErrors = true;
|
726
659
|
typeResult.expectedTypeDiagAddendum = diag;
|
727
660
|
diag.addTextRange(node);
|
@@ -1451,12 +1384,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1451
1384
|
const isObjectInit = !!methodType &&
|
1452
1385
|
(0, types_1.isFunction)(methodType) &&
|
1453
1386
|
methodType.details.fullName === 'builtins.object.__init__';
|
1454
|
-
const isSkipConstructor = !!methodType && (0, types_1.isFunction)(methodType) && types_1.FunctionType.isSkipConstructorCheck(methodType);
|
1455
1387
|
const isDefaultParams = methodType && (0, types_1.isFunction)(methodType) && types_1.FunctionType.hasDefaultParameters(methodType);
|
1456
1388
|
// If there was no `__init__` or the only `__init__` that was found was from
|
1457
1389
|
// the `object` class or accepts only default parameters(* args, ** kwargs),
|
1458
1390
|
// see if we can find a better signature from the `__new__` method.
|
1459
|
-
if (!methodType || isObjectInit ||
|
1391
|
+
if (!methodType || isObjectInit || isDefaultParams) {
|
1460
1392
|
const constructorType = getBoundMethod(subtype, '__new__',
|
1461
1393
|
/* recursionCount */ undefined,
|
1462
1394
|
/* treatConstructorAsClassMember */ true);
|
@@ -1600,8 +1532,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1600
1532
|
if ((0, types_1.isClassInstance)(declaredType)) {
|
1601
1533
|
const setterInfo = (0, typeUtils_1.lookUpClassMember)(declaredType, '__set__');
|
1602
1534
|
const setter = setterInfo ? getTypeOfMember(setterInfo) : undefined;
|
1603
|
-
if (setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 3) {
|
1535
|
+
if (setterInfo && setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 3) {
|
1604
1536
|
declaredType = setter.details.parameters[2].type;
|
1537
|
+
if ((0, types_1.isClass)(setterInfo.classType)) {
|
1538
|
+
const typeVarMap = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(setterInfo.classType);
|
1539
|
+
declaredType = (0, typeUtils_1.applySolvedTypeVars)(declaredType, typeVarMap);
|
1540
|
+
}
|
1605
1541
|
if ((0, types_1.isAnyOrUnknown)(declaredType)) {
|
1606
1542
|
return undefined;
|
1607
1543
|
}
|
@@ -1996,7 +1932,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1996
1932
|
}
|
1997
1933
|
function isDiagnosticSuppressedForNode(node) {
|
1998
1934
|
return (suppressedNodeStack.some((suppressedNode) => ParseTreeUtils.isNodeContainedWithin(node, suppressedNode)) ||
|
1999
|
-
|
1935
|
+
isSpeculativeModeInUse(node));
|
2000
1936
|
}
|
2001
1937
|
function addDiagnostic(diagLevel, rule, message, node, range) {
|
2002
1938
|
if (diagLevel === 'none') {
|
@@ -2087,7 +2023,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2087
2023
|
}
|
2088
2024
|
else {
|
2089
2025
|
// Constrain the resulting type to match the declared type.
|
2090
|
-
destType = narrowTypeBasedOnAssignment(declaredType, type);
|
2026
|
+
destType = narrowTypeBasedOnAssignment(nameNode, declaredType, type);
|
2091
2027
|
}
|
2092
2028
|
}
|
2093
2029
|
else {
|
@@ -2604,7 +2540,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2604
2540
|
// is a enum because the annotated type in an enum doesn't reflect
|
2605
2541
|
// the type of the symbol.
|
2606
2542
|
if (!(0, types_1.isClassInstance)(type) || !types_1.ClassType.isEnumClass(type)) {
|
2607
|
-
type = narrowTypeBasedOnAssignment(annotationType, type);
|
2543
|
+
type = narrowTypeBasedOnAssignment(target, annotationType, type);
|
2608
2544
|
}
|
2609
2545
|
}
|
2610
2546
|
}
|
@@ -2658,7 +2594,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2658
2594
|
else {
|
2659
2595
|
let callResult;
|
2660
2596
|
suppressDiagnostics(node.typeExpression, () => {
|
2661
|
-
callResult = validateConstructorArguments(node.typeExpression, [], concreteSubtype,
|
2597
|
+
callResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, node.typeExpression, [], concreteSubtype,
|
2662
2598
|
/* skipUnknownArgCheck */ false,
|
2663
2599
|
/* inferenceContext */ undefined);
|
2664
2600
|
});
|
@@ -2736,7 +2672,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2736
2672
|
}
|
2737
2673
|
}
|
2738
2674
|
function setSymbolAccessed(fileInfo, symbol, node) {
|
2739
|
-
if (!
|
2675
|
+
if (!isSpeculativeModeInUse(node)) {
|
2740
2676
|
fileInfo.accessedSymbolSet.add(symbol.id);
|
2741
2677
|
}
|
2742
2678
|
}
|
@@ -3095,7 +3031,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3095
3031
|
container: enclosingScope.name.value,
|
3096
3032
|
}), node);
|
3097
3033
|
}
|
3098
|
-
type = types_1.TypeVarType.cloneForScopeId(type, getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
|
3034
|
+
type = types_1.TypeVarType.cloneForScopeId(type, ParseTreeUtils.getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
|
3099
3035
|
? 1 /* Function */
|
3100
3036
|
: 0 /* Class */);
|
3101
3037
|
}
|
@@ -3186,35 +3122,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3186
3122
|
}
|
3187
3123
|
return type;
|
3188
3124
|
}
|
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
3125
|
// Walks up the parse tree to find a function, class, or type alias
|
3219
3126
|
// declaration that provides the context for a type variable.
|
3220
3127
|
function findScopedTypeVar(node, type) {
|
@@ -3294,6 +3201,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3294
3201
|
container: typeAliasNode.name.value,
|
3295
3202
|
}), node);
|
3296
3203
|
}
|
3204
|
+
else {
|
3205
|
+
// If this is a TypeAliasType call, the recursiveTypeParameters will already
|
3206
|
+
// be populated, and we need to verify that the type parameter is in the
|
3207
|
+
// list of allowed type parameters.
|
3208
|
+
const allowedTypeParams = leftType.details.recursiveTypeParameters;
|
3209
|
+
if (allowedTypeParams) {
|
3210
|
+
if (!allowedTypeParams.some((param) => param.details.name === type.details.name)) {
|
3211
|
+
// Return the original type.
|
3212
|
+
return { type, isRescoped: false, foundInterveningClass: false };
|
3213
|
+
}
|
3214
|
+
}
|
3215
|
+
}
|
3297
3216
|
return {
|
3298
3217
|
type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
|
3299
3218
|
isRescoped: false,
|
@@ -4063,16 +3982,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4063
3982
|
// If this function is an instance member (e.g. a lambda that was
|
4064
3983
|
// assigned to an instance variable), don't perform any binding.
|
4065
3984
|
if (!isAccessedThroughObject || (memberInfo && !memberInfo.isInstanceMember)) {
|
4066
|
-
// Skip binding if the class appears to be a metaclass (i.e. a subclass of
|
4067
|
-
// `type`) because the first parameter of instance methods in a metaclass
|
4068
|
-
// are not `self` instances.
|
4069
|
-
const isMetaclass = !isAccessedThroughObject &&
|
4070
|
-
(0, types_1.isClass)(baseTypeClass) &&
|
4071
|
-
(flags & 16 /* TreatConstructorAsClassMethod */) === 0 &&
|
4072
|
-
baseTypeClass.details.mro.some((mroType) => (0, types_1.isClass)(mroType) && types_1.ClassType.isBuiltIn(mroType, 'type'));
|
4073
|
-
if (isMetaclass) {
|
4074
|
-
return concreteSubtype;
|
4075
|
-
}
|
4076
3985
|
return bindFunctionToClassOrObject(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode,
|
4077
3986
|
/* recursionCount */ undefined, treatConstructorAsClassMember, bindToType);
|
4078
3987
|
}
|
@@ -5154,7 +5063,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5154
5063
|
}
|
5155
5064
|
if (!matchingSubtype) {
|
5156
5065
|
const subtypeResult = useSpeculativeMode(node, () => {
|
5157
|
-
return getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype
|
5066
|
+
return getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype));
|
5158
5067
|
});
|
5159
5068
|
if (subtypeResult && assignType(subtype, subtypeResult.type)) {
|
5160
5069
|
matchingSubtype = subtype;
|
@@ -5165,7 +5074,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5165
5074
|
}
|
5166
5075
|
let expectedTypeDiagAddendum;
|
5167
5076
|
if (effectiveExpectedType) {
|
5168
|
-
const result = getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType
|
5077
|
+
const result = getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType));
|
5169
5078
|
if (result && !result.typeErrors) {
|
5170
5079
|
return result;
|
5171
5080
|
}
|
@@ -5205,7 +5114,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5205
5114
|
}
|
5206
5115
|
else {
|
5207
5116
|
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))) {
|
5117
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), inferenceContext.expectedType, tupleTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
|
5209
5118
|
return undefined;
|
5210
5119
|
}
|
5211
5120
|
const specializedTuple = (0, typeUtils_1.applySolvedTypeVars)(tupleClassType, tupleTypeVarContext);
|
@@ -5341,6 +5250,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5341
5250
|
}
|
5342
5251
|
}
|
5343
5252
|
else {
|
5253
|
+
// Check for an attempt to invoke an abstract static or class method.
|
5254
|
+
if ((0, types_1.isFunction)(baseTypeResult.type) &&
|
5255
|
+
baseTypeResult.type.boundToType &&
|
5256
|
+
(0, types_1.isInstantiableClass)(baseTypeResult.type.boundToType) &&
|
5257
|
+
!baseTypeResult.type.boundToType.includeSubclasses) {
|
5258
|
+
if (types_1.FunctionType.isAbstractMethod(baseTypeResult.type)) {
|
5259
|
+
if (types_1.FunctionType.isStaticMethod(baseTypeResult.type) ||
|
5260
|
+
types_1.FunctionType.isClassMethod(baseTypeResult.type)) {
|
5261
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
|
5262
|
+
method: baseTypeResult.type.details.name,
|
5263
|
+
}), node.leftExpression);
|
5264
|
+
}
|
5265
|
+
}
|
5266
|
+
}
|
5344
5267
|
const callResult = validateCallArguments(node, argList, baseTypeResult,
|
5345
5268
|
/* typeVarContext */ undefined,
|
5346
5269
|
/* skipUnknownArgCheck */ false, inferenceContext);
|
@@ -5364,7 +5287,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5364
5287
|
}
|
5365
5288
|
// Don't bother evaluating the arguments if we're speculatively evaluating the call
|
5366
5289
|
// or the base type is incomplete.
|
5367
|
-
if (!
|
5290
|
+
if (!isSpeculativeModeInUse(node) && !baseTypeResult.isIncomplete) {
|
5368
5291
|
// Touch all of the args so they're marked accessed even if there were errors.
|
5369
5292
|
// We skip this if it's a TypeVar() call in the typing.pyi module because
|
5370
5293
|
// this results in a cyclical type resolution problem whereby we try to
|
@@ -5432,7 +5355,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5432
5355
|
// If one or more of the arguments are incomplete, use speculative mode
|
5433
5356
|
// for the lambda evaluation because it may need to be reevaluated once
|
5434
5357
|
// the arg types are complete.
|
5435
|
-
let typeResult = isArgTypeIncomplete ||
|
5358
|
+
let typeResult = isArgTypeIncomplete || isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete)
|
5436
5359
|
? useSpeculativeMode(node.leftExpression, getLambdaType)
|
5437
5360
|
: getLambdaType();
|
5438
5361
|
// If bidirectional type inference failed, use normal type inference instead.
|
@@ -5740,10 +5663,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5740
5663
|
? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
|
5741
5664
|
: typeVarContext;
|
5742
5665
|
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
|
-
}
|
5666
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
|
5747
5667
|
effectiveTypeVarContext.unlock();
|
5748
5668
|
// Use speculative mode so we don't output any diagnostics or
|
5749
5669
|
// record any final types in the type cache.
|
@@ -5793,15 +5713,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5793
5713
|
else {
|
5794
5714
|
// Eliminate any return types that are subsumed by other return types.
|
5795
5715
|
let dedupedMatchResults = [];
|
5716
|
+
let dedupedResultsIncludeAny = false;
|
5796
5717
|
possibleMatchResults.forEach((result) => {
|
5797
5718
|
let isSubtypeSubsumed = false;
|
5798
5719
|
for (let dedupedIndex = 0; dedupedIndex < dedupedMatchResults.length; dedupedIndex++) {
|
5799
5720
|
if (assignType(dedupedMatchResults[dedupedIndex], result.returnType)) {
|
5800
|
-
|
5721
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(dedupedMatchResults[dedupedIndex])) {
|
5722
|
+
isSubtypeSubsumed = true;
|
5723
|
+
}
|
5724
|
+
else if (!(0, typeUtils_1.containsUnknown)(dedupedMatchResults[dedupedIndex])) {
|
5725
|
+
dedupedResultsIncludeAny = true;
|
5726
|
+
}
|
5801
5727
|
break;
|
5802
5728
|
}
|
5803
5729
|
else if (assignType(result.returnType, dedupedMatchResults[dedupedIndex])) {
|
5804
|
-
|
5730
|
+
if (!(0, typeUtils_1.containsAnyOrUnknown)(result.returnType)) {
|
5731
|
+
dedupedMatchResults[dedupedIndex] = types_1.NeverType.createNever();
|
5732
|
+
}
|
5733
|
+
else if (!(0, typeUtils_1.containsUnknown)(dedupedMatchResults[dedupedIndex])) {
|
5734
|
+
dedupedResultsIncludeAny = true;
|
5735
|
+
}
|
5805
5736
|
break;
|
5806
5737
|
}
|
5807
5738
|
}
|
@@ -5811,9 +5742,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5811
5742
|
});
|
5812
5743
|
dedupedMatchResults = dedupedMatchResults.filter((t) => !(0, types_1.isNever)(t));
|
5813
5744
|
const combinedTypes = (0, types_1.combineTypes)(dedupedMatchResults);
|
5814
|
-
|
5815
|
-
|
5816
|
-
|
5745
|
+
let effectiveReturnType = combinedTypes;
|
5746
|
+
if (dedupedMatchResults.length > 1) {
|
5747
|
+
// If one or more of the deduped types is Any or contains Any,
|
5748
|
+
// we will assume that the person who defined the overload really
|
5749
|
+
// wanted Any rather than Unknown. In cases where the deduped types
|
5750
|
+
// simply contains conflicting results without an Any, we'll use
|
5751
|
+
// an UnknownType.
|
5752
|
+
if (dedupedResultsIncludeAny) {
|
5753
|
+
effectiveReturnType = types_1.AnyType.create();
|
5754
|
+
}
|
5755
|
+
else {
|
5756
|
+
effectiveReturnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
5757
|
+
}
|
5758
|
+
}
|
5759
|
+
returnTypes.push(effectiveReturnType);
|
5817
5760
|
}
|
5818
5761
|
}
|
5819
5762
|
if (!matchedOverload) {
|
@@ -5955,10 +5898,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5955
5898
|
return current.overloadIndex > previous.overloadIndex ? current : previous;
|
5956
5899
|
});
|
5957
5900
|
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
|
-
}
|
5901
|
+
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(lastMatch.overload));
|
5962
5902
|
effectiveTypeVarContext.unlock();
|
5963
5903
|
return validateFunctionArgumentTypesWithContext(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5964
5904
|
};
|
@@ -6063,331 +6003,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6063
6003
|
});
|
6064
6004
|
return newExpandedArgTypes;
|
6065
6005
|
}
|
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
6006
|
// Validates that the arguments can be assigned to the call's parameter
|
6392
6007
|
// list, specializes the call based on arg types, and returns the
|
6393
6008
|
// specialized type of the return value. If it detects an error along
|
@@ -6420,7 +6035,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6420
6035
|
// to be done again once it is complete.
|
6421
6036
|
if (!callTypeResult.isIncomplete) {
|
6422
6037
|
argList.forEach((arg) => {
|
6423
|
-
if (arg.valueExpression && !
|
6038
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
6424
6039
|
getTypeOfArgument(arg);
|
6425
6040
|
}
|
6426
6041
|
});
|
@@ -6449,7 +6064,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6449
6064
|
let effectiveTypeVarContext = typeVarContext;
|
6450
6065
|
if (!effectiveTypeVarContext) {
|
6451
6066
|
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6452
|
-
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.
|
6067
|
+
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
|
6453
6068
|
// There are certain cases, such as with super().__new__(cls) calls where
|
6454
6069
|
// the call is a constructor but the proper TypeVar scope has been lost.
|
6455
6070
|
// We'll add a wildcard TypeVar scope here. This is a bit of a hack and
|
@@ -6544,7 +6159,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6544
6159
|
const className = expandedSubtype.aliasName || expandedSubtype.details.name;
|
6545
6160
|
if (className === 'type') {
|
6546
6161
|
// Validate the constructor arguments.
|
6547
|
-
validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6162
|
+
(0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6548
6163
|
// Handle the 'type' call specially.
|
6549
6164
|
if (argList.length === 1) {
|
6550
6165
|
// The one-parameter form of "type" returns the class
|
@@ -6572,13 +6187,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6572
6187
|
return types_1.AnyType.create();
|
6573
6188
|
}
|
6574
6189
|
if (className === 'TypeVar') {
|
6575
|
-
return createTypeVarType(errorNode, argList);
|
6190
|
+
return createTypeVarType(errorNode, expandedSubtype, argList);
|
6576
6191
|
}
|
6577
6192
|
if (className === 'TypeVarTuple') {
|
6578
|
-
return createTypeVarTupleType(errorNode, argList);
|
6193
|
+
return createTypeVarTupleType(errorNode, expandedSubtype, argList);
|
6579
6194
|
}
|
6580
6195
|
if (className === 'ParamSpec') {
|
6581
|
-
return createParamSpecType(errorNode, argList);
|
6196
|
+
return createParamSpecType(errorNode, expandedSubtype, argList);
|
6197
|
+
}
|
6198
|
+
if (className === 'TypeAliasType') {
|
6199
|
+
const newTypeAlias = createTypeAliasType(errorNode, argList);
|
6200
|
+
if (newTypeAlias) {
|
6201
|
+
return newTypeAlias;
|
6202
|
+
}
|
6582
6203
|
}
|
6583
6204
|
if (className === 'NamedTuple') {
|
6584
6205
|
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
@@ -6643,7 +6264,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6643
6264
|
}), errorNode);
|
6644
6265
|
}
|
6645
6266
|
// Assume this is a call to the constructor.
|
6646
|
-
const constructorResult = validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6267
|
+
const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6647
6268
|
overloadsUsedForCall.push(...constructorResult.overloadsUsedForCall);
|
6648
6269
|
if (constructorResult.argumentErrors) {
|
6649
6270
|
argumentErrors = true;
|
@@ -7485,7 +7106,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7485
7106
|
// If we're in speculative mode and an arg/param mismatch has already been reported, don't
|
7486
7107
|
// bother doing the extra work here. This occurs frequently when attempting to find the
|
7487
7108
|
// correct overload.
|
7488
|
-
if (!reportedArgError || !
|
7109
|
+
if (!reportedArgError || !isSpeculativeModeInUse(undefined)) {
|
7489
7110
|
// If there are arguments that map to a variadic *args parameter that hasn't
|
7490
7111
|
// already been matched, see if the type of that *args parameter is a variadic
|
7491
7112
|
// type variable. If so, we'll preprocess those arguments and combine them
|
@@ -7618,18 +7239,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7618
7239
|
// Prepopulate the typeVarContext based on the specialized expected type if the
|
7619
7240
|
// callee has a declared return type. This will allow us to more closely match
|
7620
7241
|
// the expected type if possible.
|
7621
|
-
//
|
7622
|
-
|
7623
|
-
|
7624
|
-
|
7625
|
-
(0, types_1.
|
7626
|
-
|
7627
|
-
|
7628
|
-
|
7629
|
-
|
7630
|
-
|
7631
|
-
|
7632
|
-
|
7242
|
+
// Determine which type arguments are needed to match the expected type.
|
7243
|
+
if ((0, types_1.isClassInstance)(effectiveReturnType)) {
|
7244
|
+
// If the return type is a class and the expected type is a union that contains
|
7245
|
+
// that class, see if we can eliminate the other subtypes in the union.
|
7246
|
+
if ((0, types_1.isUnion)(effectiveExpectedType)) {
|
7247
|
+
const filteredType = (0, typeUtils_1.mapSubtypes)(effectiveExpectedType, (subtype) => {
|
7248
|
+
return (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isSameGenericClass(effectiveReturnType, subtype)
|
7249
|
+
? subtype
|
7250
|
+
: undefined;
|
7251
|
+
});
|
7252
|
+
if ((0, types_1.isClassInstance)(filteredType)) {
|
7253
|
+
effectiveExpectedType = filteredType;
|
7254
|
+
}
|
7255
|
+
}
|
7256
|
+
if ((0, types_1.isClassInstance)(effectiveExpectedType) && !(0, types_1.isTypeSame)(effectiveReturnType, effectiveExpectedType)) {
|
7257
|
+
const tempTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(effectiveReturnType));
|
7258
|
+
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, effectiveReturnType, effectiveExpectedType, tempTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(errorNode));
|
7259
|
+
const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
|
7260
|
+
/* typeArguments */ undefined,
|
7261
|
+
/* isTypeArgumentExplicit */ false);
|
7262
|
+
effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext);
|
7263
|
+
}
|
7633
7264
|
}
|
7634
7265
|
else if ((0, types_1.isFunction)(effectiveReturnType)) {
|
7635
7266
|
// If the return type is a callable and the expected type is a union that
|
@@ -7739,7 +7370,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7739
7370
|
// If we skipped a overload arg during the first pass,
|
7740
7371
|
// add another pass to ensure that we handle all of the
|
7741
7372
|
// type variables.
|
7742
|
-
if (i === 0 && argResult.skippedOverloadArg) {
|
7373
|
+
if (i === 0 && (argResult.skippedOverloadArg || argResult.skippedBareTypeVarExpectedType)) {
|
7743
7374
|
passCount++;
|
7744
7375
|
}
|
7745
7376
|
});
|
@@ -7820,7 +7451,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7820
7451
|
if (!typeVarScopeNode) {
|
7821
7452
|
break;
|
7822
7453
|
}
|
7823
|
-
const typeVarScopeId = getScopeIdForNode(typeVarScopeNode);
|
7454
|
+
const typeVarScopeId = ParseTreeUtils.getScopeIdForNode(typeVarScopeNode);
|
7824
7455
|
if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
|
7825
7456
|
eliminateUnsolvedInUnions = false;
|
7826
7457
|
}
|
@@ -7843,15 +7474,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7843
7474
|
let unknownIfNotFound = !(0, types_1.isFunction)(returnType);
|
7844
7475
|
// We'll also leave TypeVars unsolved if the call is a recursive
|
7845
7476
|
// call to a generic function.
|
7846
|
-
const typeVarScopes = getTypeVarScopesForNode(errorNode);
|
7477
|
+
const typeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
|
7847
7478
|
if (typeVarScopes.some((typeVarScope) => typeVarContext.hasSolveForScope(typeVarScope))) {
|
7848
7479
|
unknownIfNotFound = false;
|
7849
7480
|
}
|
7850
|
-
let specializedReturnType = (0, typeUtils_1.
|
7481
|
+
let specializedReturnType = (0, typeUtils_1.applySolvedTypeVars)(returnType, typeVarContext, {
|
7851
7482
|
unknownIfNotFound,
|
7852
7483
|
useUnknownOverDefault: skipUnknownArgCheck,
|
7853
7484
|
eliminateUnsolvedInUnions,
|
7854
|
-
|
7485
|
+
applyInScopePlaceholders: true,
|
7486
|
+
});
|
7487
|
+
specializedReturnType = (0, typeUtils_1.addConditionToType)(specializedReturnType, typeCondition);
|
7855
7488
|
// If the final return type is an unpacked tuple, turn it into a normal (unpacked) tuple.
|
7856
7489
|
if ((0, types_1.isUnpackedClass)(specializedReturnType)) {
|
7857
7490
|
specializedReturnType = types_1.ClassType.cloneForUnpacked(specializedReturnType, /* isUnpackedTuple */ false);
|
@@ -7919,7 +7552,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7919
7552
|
// Evaluate types of all args. This will ensure that referenced symbols are
|
7920
7553
|
// not reported as unaccessed.
|
7921
7554
|
argList.forEach((arg) => {
|
7922
|
-
if (arg.valueExpression && !
|
7555
|
+
if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
|
7923
7556
|
getTypeOfExpression(arg.valueExpression);
|
7924
7557
|
}
|
7925
7558
|
});
|
@@ -7962,6 +7595,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7962
7595
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecNotBound().format({ type: printType(paramSpec) }), ((_a = argList[0]) === null || _a === void 0 ? void 0 : _a.valueExpression) || errorNode);
|
7963
7596
|
return false;
|
7964
7597
|
}
|
7598
|
+
const liveTypeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
|
7965
7599
|
const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecType.details.typeVarScopeId);
|
7966
7600
|
let reportedArgError = false;
|
7967
7601
|
// Build a map of all named parameters.
|
@@ -8024,7 +7658,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8024
7658
|
if (paramType) {
|
8025
7659
|
const argResult = validateArgType({
|
8026
7660
|
paramCategory: 0 /* Simple */,
|
8027
|
-
paramType,
|
7661
|
+
paramType: (0, typeUtils_1.transformExpectedType)(paramType, liveTypeVarScopes),
|
8028
7662
|
requiresTypeVarMatching: false,
|
8029
7663
|
argument: arg,
|
8030
7664
|
errorNode: arg.valueExpression || errorNode,
|
@@ -8075,7 +7709,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8075
7709
|
}
|
8076
7710
|
}
|
8077
7711
|
if (!reportedArgError) {
|
8078
|
-
|
7712
|
+
(0, typeUtils_1.applySourceContextTypeVarsToSignature)(typeVarContext, srcTypeVarContext);
|
8079
7713
|
}
|
8080
7714
|
return !reportedArgError;
|
8081
7715
|
}
|
@@ -8086,14 +7720,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8086
7720
|
let isTypeIncomplete = !!(typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete);
|
8087
7721
|
let isCompatible = true;
|
8088
7722
|
const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
|
7723
|
+
let skippedBareTypeVarExpectedType = false;
|
8089
7724
|
if (argParam.argument.valueExpression) {
|
8090
7725
|
let expectedType;
|
8091
|
-
|
8092
|
-
|
8093
|
-
argParam.paramType
|
8094
|
-
|
8095
|
-
|
8096
|
-
|
7726
|
+
const isBareTypeVarExpectedType = (0, types_1.isTypeVar)(argParam.paramType) && argParam.paramType.scopeId === (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId);
|
7727
|
+
if (!options.skipBareTypeVarExpectedType || !isBareTypeVarExpectedType) {
|
7728
|
+
expectedType = argParam.paramType;
|
7729
|
+
// If the parameter type is a function with a ParamSpec, don't apply
|
7730
|
+
// the solved TypeVars if the typeVarContext has more than one signature.
|
7731
|
+
// This will expand the ParamSpec into an overload, which will cause problems.
|
7732
|
+
const skipApplySolvedTypeVars = (0, types_1.isFunction)(argParam.paramType) &&
|
7733
|
+
!!argParam.paramType.details.paramSpec &&
|
7734
|
+
typeVarContext.getSignatureContexts().length > 1;
|
7735
|
+
if (!skipApplySolvedTypeVars) {
|
7736
|
+
expectedType = (0, typeUtils_1.applySolvedTypeVars)(expectedType, typeVarContext, {
|
7737
|
+
useNarrowBoundOnly: !!options.useNarrowBoundOnly,
|
7738
|
+
});
|
7739
|
+
}
|
7740
|
+
}
|
7741
|
+
else {
|
7742
|
+
skippedBareTypeVarExpectedType = true;
|
8097
7743
|
}
|
8098
7744
|
// If the expected type is unknown, don't use an expected type. Instead,
|
8099
7745
|
// use default rules for evaluating the expression type.
|
@@ -8110,19 +7756,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8110
7756
|
32 /* DisallowParamSpec */ |
|
8111
7757
|
64 /* DisallowTypeVarTuple */
|
8112
7758
|
: 0 /* None */;
|
8113
|
-
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedType,
|
7759
|
+
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedType, !!(typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete)));
|
8114
7760
|
argType = exprTypeResult.type;
|
7761
|
+
// If the type includes multiple instances of a generic function
|
7762
|
+
// signature, force the type arguments for the duplicates to have
|
7763
|
+
// unique names.
|
7764
|
+
argType = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(argType, signatureTracker);
|
8115
7765
|
if (exprTypeResult.isIncomplete) {
|
8116
7766
|
isTypeIncomplete = true;
|
8117
7767
|
}
|
8118
7768
|
if (exprTypeResult.typeErrors) {
|
8119
7769
|
isCompatible = false;
|
8120
7770
|
}
|
7771
|
+
else if (expectedType && (0, typeUtils_1.requiresSpecialization)(expectedType)) {
|
7772
|
+
// Assign the argument type back to the expected type to assign
|
7773
|
+
// values to any in-scope placeholder type variables.
|
7774
|
+
const typeVarContextClone = typeVarContext.clone();
|
7775
|
+
if (assignType(expectedType, argType, /* diag */ undefined, typeVarContextClone)) {
|
7776
|
+
typeVarContext.copyFromClone(typeVarContextClone);
|
7777
|
+
}
|
7778
|
+
else {
|
7779
|
+
isCompatible = false;
|
7780
|
+
}
|
7781
|
+
}
|
8121
7782
|
expectedTypeDiag = exprTypeResult.expectedTypeDiagAddendum;
|
8122
7783
|
}
|
8123
|
-
if (argParam.argument &&
|
8124
|
-
argParam.argument.name &&
|
8125
|
-
!speculativeTypeTracker.isSpeculative(argParam.errorNode)) {
|
7784
|
+
if (argParam.argument && argParam.argument.name && !isSpeculativeModeInUse(argParam.errorNode)) {
|
8126
7785
|
writeTypeCache(argParam.argument.name, { type: expectedType !== null && expectedType !== void 0 ? expectedType : argType, isIncomplete: isTypeIncomplete }, 0 /* None */);
|
8127
7786
|
}
|
8128
7787
|
}
|
@@ -8148,10 +7807,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8148
7807
|
}
|
8149
7808
|
}
|
8150
7809
|
}
|
8151
|
-
// If the type includes multiple instances of a generic function
|
8152
|
-
// signature, force the type arguments for the duplicates to have
|
8153
|
-
// unique names.
|
8154
|
-
argType = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(argType, signatureTracker);
|
8155
7810
|
// If we're assigning to a var arg dictionary with a TypeVar type,
|
8156
7811
|
// strip literals before performing the assignment. This is used in
|
8157
7812
|
// places like a dict constructor.
|
@@ -8183,14 +7838,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8183
7838
|
// an overloaded callback protocol.
|
8184
7839
|
if (options.skipOverloadArg) {
|
8185
7840
|
if ((0, types_1.isOverloadedFunction)(argType)) {
|
8186
|
-
return {
|
7841
|
+
return {
|
7842
|
+
isCompatible,
|
7843
|
+
argType,
|
7844
|
+
isTypeIncomplete,
|
7845
|
+
skippedOverloadArg: true,
|
7846
|
+
skippedBareTypeVarExpectedType,
|
7847
|
+
condition,
|
7848
|
+
};
|
8187
7849
|
}
|
8188
7850
|
const concreteParamType = makeTopLevelTypeVarsConcrete(argParam.paramType);
|
8189
7851
|
if ((0, types_1.isFunction)(concreteParamType) || (0, types_1.isOverloadedFunction)(concreteParamType)) {
|
8190
7852
|
if ((0, types_1.isInstantiableClass)(argType)) {
|
8191
|
-
const constructor = createFunctionFromConstructor(argType);
|
7853
|
+
const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, argType);
|
8192
7854
|
if (constructor && (0, types_1.isOverloadedFunction)(constructor)) {
|
8193
|
-
return {
|
7855
|
+
return {
|
7856
|
+
isCompatible,
|
7857
|
+
argType,
|
7858
|
+
isTypeIncomplete,
|
7859
|
+
skippedOverloadArg: true,
|
7860
|
+
skippedBareTypeVarExpectedType,
|
7861
|
+
condition,
|
7862
|
+
};
|
8194
7863
|
}
|
8195
7864
|
}
|
8196
7865
|
if ((0, types_1.isClassInstance)(argType)) {
|
@@ -8198,7 +7867,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8198
7867
|
if (callMember) {
|
8199
7868
|
const memberType = getTypeOfMember(callMember);
|
8200
7869
|
if ((0, types_1.isOverloadedFunction)(memberType)) {
|
8201
|
-
return {
|
7870
|
+
return {
|
7871
|
+
isCompatible,
|
7872
|
+
argType,
|
7873
|
+
isTypeIncomplete,
|
7874
|
+
skippedOverloadArg: true,
|
7875
|
+
skippedBareTypeVarExpectedType,
|
7876
|
+
condition,
|
7877
|
+
};
|
8202
7878
|
}
|
8203
7879
|
}
|
8204
7880
|
}
|
@@ -8255,7 +7931,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8255
7931
|
}
|
8256
7932
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message + diag.getString(), argParam.errorNode, (_a = diag.getEffectiveTextRange()) !== null && _a !== void 0 ? _a : argParam.errorNode);
|
8257
7933
|
}
|
8258
|
-
return { isCompatible: false, argType, isTypeIncomplete, condition };
|
7934
|
+
return { isCompatible: false, argType, isTypeIncomplete, skippedBareTypeVarExpectedType, condition };
|
8259
7935
|
}
|
8260
7936
|
if (!options.skipUnknownArgCheck) {
|
8261
7937
|
const simplifiedType = (0, types_1.removeUnbound)(argType);
|
@@ -8311,9 +7987,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8311
7987
|
}
|
8312
7988
|
}
|
8313
7989
|
}
|
8314
|
-
return { isCompatible, argType, isTypeIncomplete, condition };
|
7990
|
+
return { isCompatible, argType, isTypeIncomplete, skippedBareTypeVarExpectedType, condition };
|
8315
7991
|
}
|
8316
|
-
function createTypeVarType(errorNode, argList) {
|
7992
|
+
function createTypeVarType(errorNode, classType, argList) {
|
8317
7993
|
var _a, _b, _c, _d, _e, _f, _g;
|
8318
7994
|
let typeVarName = '';
|
8319
7995
|
let firstConstraintArg;
|
@@ -8386,8 +8062,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8386
8062
|
}
|
8387
8063
|
else if (paramName === 'default') {
|
8388
8064
|
defaultValueNode = argList[i].valueExpression;
|
8389
|
-
const argType = (_d = (_c = argList[i].typeResult) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : getTypeOfExpressionExpectingType(
|
8065
|
+
const argType = (_d = (_c = argList[i].typeResult) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : getTypeOfExpressionExpectingType(defaultValueNode, {
|
8066
|
+
allowTypeVarsWithoutScopeId: true,
|
8067
|
+
}).type;
|
8390
8068
|
typeVar.details.defaultType = (0, typeUtils_1.convertToInstance)(argType);
|
8069
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
8070
|
+
if (!fileInfo.isStubFile &&
|
8071
|
+
fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_13 &&
|
8072
|
+
classType.details.moduleName !== 'typing_extensions') {
|
8073
|
+
addError(localize_1.Localizer.Diagnostic.typeVarDefaultIllegal(), defaultValueNode);
|
8074
|
+
}
|
8391
8075
|
}
|
8392
8076
|
else {
|
8393
8077
|
addError(localize_1.Localizer.Diagnostic.typeVarUnknownParam().format({ name: paramName }), ((_e = argList[i].node) === null || _e === void 0 ? void 0 : _e.name) || argList[i].valueExpression || errorNode);
|
@@ -8433,7 +8117,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8433
8117
|
}
|
8434
8118
|
return typeVar;
|
8435
8119
|
}
|
8436
|
-
function createTypeVarTupleType(errorNode, argList) {
|
8120
|
+
function createTypeVarTupleType(errorNode, classType, argList) {
|
8437
8121
|
var _a, _b;
|
8438
8122
|
let typeVarName = '';
|
8439
8123
|
if (argList.length === 0) {
|
@@ -8459,6 +8143,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8459
8143
|
if (expr) {
|
8460
8144
|
typeVar.details.defaultType = getTypeVarTupleDefaultType(expr);
|
8461
8145
|
}
|
8146
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
8147
|
+
if (!fileInfo.isStubFile &&
|
8148
|
+
fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_13 &&
|
8149
|
+
classType.details.moduleName !== 'typing_extensions') {
|
8150
|
+
addError(localize_1.Localizer.Diagnostic.typeVarDefaultIllegal(), expr);
|
8151
|
+
}
|
8462
8152
|
}
|
8463
8153
|
else {
|
8464
8154
|
addError(localize_1.Localizer.Diagnostic.typeVarTupleUnknownParam().format({ name: ((_a = argList[i].name) === null || _a === void 0 ? void 0 : _a.value) || '?' }), ((_b = argList[i].node) === null || _b === void 0 ? void 0 : _b.name) || argList[i].valueExpression || errorNode);
|
@@ -8468,7 +8158,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8468
8158
|
return typeVar;
|
8469
8159
|
}
|
8470
8160
|
function getTypeVarTupleDefaultType(node) {
|
8471
|
-
const argType = getTypeOfExpressionExpectingType(node, {
|
8161
|
+
const argType = getTypeOfExpressionExpectingType(node, {
|
8162
|
+
allowUnpackedTuple: true,
|
8163
|
+
allowTypeVarsWithoutScopeId: true,
|
8164
|
+
}).type;
|
8472
8165
|
const isUnpackedTuple = (0, types_1.isClass)(argType) && (0, typeUtils_1.isTupleClass)(argType) && argType.isUnpacked;
|
8473
8166
|
const isUnpackedTypeVarTuple = (0, types_1.isUnpackedVariadicTypeVar)(argType);
|
8474
8167
|
if (!isUnpackedTuple && !isUnpackedTypeVarTuple) {
|
@@ -8477,7 +8170,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8477
8170
|
}
|
8478
8171
|
return (0, typeUtils_1.convertToInstance)(argType);
|
8479
8172
|
}
|
8480
|
-
function createParamSpecType(errorNode, argList) {
|
8173
|
+
function createParamSpecType(errorNode, classType, argList) {
|
8481
8174
|
if (argList.length === 0) {
|
8482
8175
|
addError(localize_1.Localizer.Diagnostic.paramSpecFirstArg(), errorNode);
|
8483
8176
|
return undefined;
|
@@ -8501,6 +8194,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8501
8194
|
if (expr) {
|
8502
8195
|
paramSpec.details.defaultType = getParamSpecDefaultType(expr);
|
8503
8196
|
}
|
8197
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
|
8198
|
+
if (!fileInfo.isStubFile &&
|
8199
|
+
fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_13 &&
|
8200
|
+
classType.details.moduleName !== 'typing_extensions') {
|
8201
|
+
addError(localize_1.Localizer.Diagnostic.typeVarDefaultIllegal(), expr);
|
8202
|
+
}
|
8504
8203
|
}
|
8505
8204
|
else {
|
8506
8205
|
addError(localize_1.Localizer.Diagnostic.paramSpecUnknownParam().format({ name: paramName }), paramNameNode || argList[i].valueExpression || errorNode);
|
@@ -8522,7 +8221,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8522
8221
|
}
|
8523
8222
|
if (node.nodeType === 31 /* List */) {
|
8524
8223
|
node.entries.forEach((paramExpr, index) => {
|
8525
|
-
const typeResult = getTypeOfExpressionExpectingType(paramExpr);
|
8224
|
+
const typeResult = getTypeOfExpressionExpectingType(paramExpr, { allowTypeVarsWithoutScopeId: true });
|
8526
8225
|
types_1.FunctionType.addParameter(functionType, {
|
8527
8226
|
category: 0 /* Simple */,
|
8528
8227
|
name: `__p${index}`,
|
@@ -8537,7 +8236,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8537
8236
|
return functionType;
|
8538
8237
|
}
|
8539
8238
|
else {
|
8540
|
-
const typeResult = getTypeOfExpressionExpectingType(node, {
|
8239
|
+
const typeResult = getTypeOfExpressionExpectingType(node, {
|
8240
|
+
allowParamSpec: true,
|
8241
|
+
allowTypeVarsWithoutScopeId: true,
|
8242
|
+
});
|
8541
8243
|
if (typeResult.typeErrors) {
|
8542
8244
|
return undefined;
|
8543
8245
|
}
|
@@ -8549,6 +8251,91 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8549
8251
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecDefaultNotTuple(), node);
|
8550
8252
|
return undefined;
|
8551
8253
|
}
|
8254
|
+
// Handles a call to TypeAliasType(). This special form allows a caller to programmatically
|
8255
|
+
// create a type alias as defined in PEP 695. If one or more of the arguments is incorrect,
|
8256
|
+
// it returns undefined so the normal constructor evaluation can be performed (and type errors
|
8257
|
+
// emitted).
|
8258
|
+
function createTypeAliasType(errorNode, argList) {
|
8259
|
+
if (errorNode.nodeType !== 9 /* Call */ || !errorNode.parent || argList.length < 2) {
|
8260
|
+
return undefined;
|
8261
|
+
}
|
8262
|
+
if (errorNode.parent.nodeType !== 3 /* Assignment */ ||
|
8263
|
+
errorNode.parent.rightExpression !== errorNode ||
|
8264
|
+
errorNode.parent.leftExpression.nodeType !== 38 /* Name */) {
|
8265
|
+
addError(localize_1.Localizer.Diagnostic.typeAliasTypeMustBeAssigned(), errorNode);
|
8266
|
+
return undefined;
|
8267
|
+
}
|
8268
|
+
const nameNode = errorNode.parent.leftExpression;
|
8269
|
+
const firstArg = argList[0];
|
8270
|
+
if (firstArg.valueExpression && firstArg.valueExpression.nodeType === 48 /* StringList */) {
|
8271
|
+
const typeAliasName = firstArg.valueExpression.strings.map((s) => s.value).join('');
|
8272
|
+
if (typeAliasName !== nameNode.value) {
|
8273
|
+
addError(localize_1.Localizer.Diagnostic.typeAliasTypeNameMismatch(), firstArg.valueExpression);
|
8274
|
+
}
|
8275
|
+
}
|
8276
|
+
else {
|
8277
|
+
addError(localize_1.Localizer.Diagnostic.typeAliasTypeNameArg(), firstArg.valueExpression || errorNode);
|
8278
|
+
return undefined;
|
8279
|
+
}
|
8280
|
+
let valueExpr;
|
8281
|
+
let typeParamsExpr;
|
8282
|
+
// Parse the remaining parameters.
|
8283
|
+
for (let i = 1; i < argList.length; i++) {
|
8284
|
+
const paramNameNode = argList[i].name;
|
8285
|
+
const paramName = paramNameNode ? paramNameNode.value : undefined;
|
8286
|
+
if (paramName) {
|
8287
|
+
if (paramName === 'type_params' && !typeParamsExpr) {
|
8288
|
+
typeParamsExpr = argList[i].valueExpression;
|
8289
|
+
}
|
8290
|
+
else if (paramName === 'value' && !valueExpr) {
|
8291
|
+
valueExpr = argList[i].valueExpression;
|
8292
|
+
}
|
8293
|
+
else {
|
8294
|
+
return undefined;
|
8295
|
+
}
|
8296
|
+
}
|
8297
|
+
else if (i === 1) {
|
8298
|
+
valueExpr = argList[i].valueExpression;
|
8299
|
+
}
|
8300
|
+
else {
|
8301
|
+
return undefined;
|
8302
|
+
}
|
8303
|
+
}
|
8304
|
+
// The value expression is not optional, so bail if it's not present.
|
8305
|
+
if (!valueExpr) {
|
8306
|
+
return undefined;
|
8307
|
+
}
|
8308
|
+
let typeParameters;
|
8309
|
+
if (typeParamsExpr) {
|
8310
|
+
if (typeParamsExpr.nodeType !== 52 /* Tuple */) {
|
8311
|
+
addError(localize_1.Localizer.Diagnostic.typeAliasTypeParamInvalid(), typeParamsExpr);
|
8312
|
+
return undefined;
|
8313
|
+
}
|
8314
|
+
typeParameters = [];
|
8315
|
+
let isTypeParamListValid = true;
|
8316
|
+
typeParamsExpr.expressions.map((expr) => {
|
8317
|
+
let entryType = getTypeOfExpression(expr, 128 /* ExpectingType */).type;
|
8318
|
+
if ((0, types_1.isTypeVar)(entryType)) {
|
8319
|
+
if (entryType.scopeId) {
|
8320
|
+
isTypeParamListValid = false;
|
8321
|
+
}
|
8322
|
+
else {
|
8323
|
+
entryType = types_1.TypeVarType.cloneForScopeId(entryType, ParseTreeUtils.getScopeIdForNode(nameNode), nameNode.value, 2 /* TypeAlias */);
|
8324
|
+
}
|
8325
|
+
typeParameters.push(entryType);
|
8326
|
+
}
|
8327
|
+
else {
|
8328
|
+
isTypeParamListValid = false;
|
8329
|
+
}
|
8330
|
+
});
|
8331
|
+
if (!isTypeParamListValid) {
|
8332
|
+
addError(localize_1.Localizer.Diagnostic.typeAliasTypeParamInvalid(), typeParamsExpr);
|
8333
|
+
return undefined;
|
8334
|
+
}
|
8335
|
+
}
|
8336
|
+
return getTypeOfTypeAliasCommon(nameNode, nameNode, valueExpr,
|
8337
|
+
/* typeParamNodes */ undefined, () => typeParameters);
|
8338
|
+
}
|
8552
8339
|
function getBooleanValue(node) {
|
8553
8340
|
if (node.nodeType === 11 /* Constant */) {
|
8554
8341
|
if (node.constType === 15 /* False */) {
|
@@ -8595,19 +8382,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8595
8382
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.newTypeBadName(), (_a = argList[0].node) !== null && _a !== void 0 ? _a : errorNode);
|
8596
8383
|
return undefined;
|
8597
8384
|
}
|
8598
|
-
|
8599
|
-
|
8600
|
-
|
8601
|
-
|
8602
|
-
|
8603
|
-
else if (baseClass.literalValue !== undefined) {
|
8604
|
-
addError(localize_1.Localizer.Diagnostic.newTypeLiteral(), argList[1].node || errorNode);
|
8385
|
+
let baseClass = getTypeOfArgumentExpectingType(argList[1]).type;
|
8386
|
+
let isBaseClassAny = false;
|
8387
|
+
if ((0, types_1.isAnyOrUnknown)(baseClass)) {
|
8388
|
+
if (objectType && (0, types_1.isClassInstance)(objectType)) {
|
8389
|
+
baseClass = types_1.ClassType.cloneAsInstantiable(objectType);
|
8605
8390
|
}
|
8606
|
-
|
8607
|
-
|
8608
|
-
|
8609
|
-
|
8610
|
-
|
8391
|
+
isBaseClassAny = true;
|
8392
|
+
}
|
8393
|
+
if (!(0, types_1.isInstantiableClass)(baseClass)) {
|
8394
|
+
addError(localize_1.Localizer.Diagnostic.newTypeNotAClass(), argList[1].node || errorNode);
|
8395
|
+
return undefined;
|
8396
|
+
}
|
8397
|
+
if (types_1.ClassType.isProtocolClass(baseClass)) {
|
8398
|
+
addError(localize_1.Localizer.Diagnostic.newTypeProtocolClass(), argList[1].node || errorNode);
|
8399
|
+
}
|
8400
|
+
else if (baseClass.literalValue !== undefined) {
|
8401
|
+
addError(localize_1.Localizer.Diagnostic.newTypeLiteral(), argList[1].node || errorNode);
|
8402
|
+
}
|
8403
|
+
const classFlags = baseClass.details.flags & ~(1 /* BuiltInClass */ | 2 /* SpecialBuiltIn */);
|
8404
|
+
const classType = types_1.ClassType.createInstantiable(className, ParseTreeUtils.getClassFullName(errorNode, fileInfo.moduleName, className), fileInfo.moduleName, fileInfo.filePath, classFlags, ParseTreeUtils.getTypeSourceId(errorNode),
|
8405
|
+
/* declaredMetaclass */ undefined, baseClass.details.effectiveMetaclass);
|
8406
|
+
classType.details.baseClasses.push(isBaseClassAny ? types_1.AnyType.create() : baseClass);
|
8407
|
+
(0, typeUtils_1.computeMroLinearization)(classType);
|
8408
|
+
if (!isBaseClassAny) {
|
8611
8409
|
// Synthesize an __init__ method that accepts only the specified type.
|
8612
8410
|
const initType = types_1.FunctionType.createSynthesizedInstance('__init__');
|
8613
8411
|
types_1.FunctionType.addParameter(initType, {
|
@@ -8635,12 +8433,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8635
8433
|
types_1.FunctionType.addDefaultParameters(newType);
|
8636
8434
|
newType.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
|
8637
8435
|
classType.details.fields.set('__new__', symbol_1.Symbol.createWithType(4 /* ClassMember */, newType));
|
8638
|
-
return classType;
|
8639
8436
|
}
|
8640
|
-
|
8641
|
-
addError(localize_1.Localizer.Diagnostic.newTypeNotAClass(), argList[1].node || errorNode);
|
8642
|
-
}
|
8643
|
-
return undefined;
|
8437
|
+
return classType;
|
8644
8438
|
}
|
8645
8439
|
// Implements the semantics of the multi-parameter variant of the "type" call.
|
8646
8440
|
function createType(errorNode, argList) {
|
@@ -8695,652 +8489,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8695
8489
|
}
|
8696
8490
|
return { type };
|
8697
8491
|
}
|
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
8492
|
function getTypeOfMagicMethodReturn(objType, args, magicMethodName, errorNode, inferenceContext) {
|
9345
8493
|
let magicMethodSupported = true;
|
9346
8494
|
// Create a helper lambda for object subtypes.
|
@@ -9415,17 +8563,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9415
8563
|
}
|
9416
8564
|
return returnType;
|
9417
8565
|
}
|
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
8566
|
function getTypeOfDictionary(node, inferenceContext) {
|
9430
8567
|
// If the expected type is a union, analyze for each of the subtypes
|
9431
8568
|
// to find one that matches.
|
@@ -9439,7 +8576,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9439
8576
|
return;
|
9440
8577
|
}
|
9441
8578
|
const subtypeResult = useSpeculativeMode(node, () => {
|
9442
|
-
return getTypeOfDictionaryWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype
|
8579
|
+
return getTypeOfDictionaryWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype));
|
9443
8580
|
});
|
9444
8581
|
if (subtypeResult && assignType(subtype, subtypeResult.type)) {
|
9445
8582
|
// If this is the first result we're seeing or it's the first result
|
@@ -9455,7 +8592,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9455
8592
|
let expectedTypeDiagAddendum = undefined;
|
9456
8593
|
if (effectiveExpectedType) {
|
9457
8594
|
expectedTypeDiagAddendum = new diagnostic_1.DiagnosticAddendum();
|
9458
|
-
const result = getTypeOfDictionaryWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType
|
8595
|
+
const result = getTypeOfDictionaryWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType), expectedTypeDiagAddendum);
|
9459
8596
|
if (result) {
|
9460
8597
|
return result;
|
9461
8598
|
}
|
@@ -9501,7 +8638,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9501
8638
|
return undefined;
|
9502
8639
|
}
|
9503
8640
|
const dictTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInDict));
|
9504
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, getTypeVarScopesForNode(node))) {
|
8641
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
|
9505
8642
|
return undefined;
|
9506
8643
|
}
|
9507
8644
|
const specializedDict = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInDict), dictTypeVarContext);
|
@@ -9512,7 +8649,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9512
8649
|
const expectedValueType = specializedDict.typeArguments[1];
|
9513
8650
|
// Infer the key and value types if possible.
|
9514
8651
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
9515
|
-
/* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum
|
8652
|
+
/* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
9516
8653
|
isIncomplete = true;
|
9517
8654
|
}
|
9518
8655
|
// Dict and MutableMapping types have invariant value types, so they
|
@@ -9521,9 +8658,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9521
8658
|
const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
9522
8659
|
(types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
|
9523
8660
|
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
|
9524
|
-
const specializedKeyType =
|
8661
|
+
const specializedKeyType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedKeyType), keyTypes.map((result) => result.type),
|
9525
8662
|
/* isNarrowable */ false);
|
9526
|
-
const specializedValueType =
|
8663
|
+
const specializedValueType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedValueType), valueTypes.map((result) => result.type), !isValueTypeInvariant);
|
9527
8664
|
if (!specializedKeyType || !specializedValueType) {
|
9528
8665
|
return undefined;
|
9529
8666
|
}
|
@@ -9580,7 +8717,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9580
8717
|
}
|
9581
8718
|
return { type, isIncomplete };
|
9582
8719
|
}
|
9583
|
-
function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum
|
8720
|
+
function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
|
9584
8721
|
let isIncomplete = false;
|
9585
8722
|
// Infer the key and value types if possible.
|
9586
8723
|
node.entries.forEach((entryNode, index) => {
|
@@ -9588,7 +8725,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9588
8725
|
let addUnknown = true;
|
9589
8726
|
if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
|
9590
8727
|
const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
|
9591
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedKeyType !== null && expectedKeyType !== void 0 ? expectedKeyType : (forceStrictInference ? types_1.NeverType.createNever() : undefined)
|
8728
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedKeyType !== null && expectedKeyType !== void 0 ? expectedKeyType : (forceStrictInference ? types_1.NeverType.createNever() : undefined)));
|
9592
8729
|
if (keyTypeResult.isIncomplete) {
|
9593
8730
|
isIncomplete = true;
|
9594
8731
|
}
|
@@ -9607,12 +8744,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9607
8744
|
expectedTypedDictEntries.has(keyType.literalValue)) {
|
9608
8745
|
const effectiveValueType = expectedTypedDictEntries.get(keyType.literalValue).valueType;
|
9609
8746
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
9610
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType
|
8747
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
|
9611
8748
|
}
|
9612
8749
|
else {
|
9613
8750
|
const effectiveValueType = expectedValueType !== null && expectedValueType !== void 0 ? expectedValueType : (forceStrictInference ? types_1.NeverType.createNever() : undefined);
|
9614
8751
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
9615
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType
|
8752
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
|
9616
8753
|
}
|
9617
8754
|
if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
|
9618
8755
|
expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
|
@@ -9636,7 +8773,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9636
8773
|
}
|
9637
8774
|
}
|
9638
8775
|
const unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
|
9639
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedType
|
8776
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedType));
|
9640
8777
|
if (unexpandedTypeResult.isIncomplete) {
|
9641
8778
|
isIncomplete = true;
|
9642
8779
|
}
|
@@ -9723,7 +8860,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9723
8860
|
return;
|
9724
8861
|
}
|
9725
8862
|
const subtypeResult = useSpeculativeMode(node, () => {
|
9726
|
-
return getTypeOfListOrSetWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype
|
8863
|
+
return getTypeOfListOrSetWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype));
|
9727
8864
|
});
|
9728
8865
|
if (subtypeResult && assignType(subtype, subtypeResult.type)) {
|
9729
8866
|
// If this is the first result we're seeing or it's the first result
|
@@ -9738,7 +8875,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9738
8875
|
}
|
9739
8876
|
let expectedTypeDiagAddendum;
|
9740
8877
|
if (effectiveExpectedType) {
|
9741
|
-
const result = getTypeOfListOrSetWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType
|
8878
|
+
const result = getTypeOfListOrSetWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType));
|
9742
8879
|
if (result && !result.typeErrors) {
|
9743
8880
|
return result;
|
9744
8881
|
}
|
@@ -9763,7 +8900,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9763
8900
|
return undefined;
|
9764
8901
|
}
|
9765
8902
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInListOrSet));
|
9766
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(node))) {
|
8903
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node))) {
|
9767
8904
|
return undefined;
|
9768
8905
|
}
|
9769
8906
|
const specializedListOrSet = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInListOrSet), typeVarContext);
|
@@ -9780,7 +8917,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9780
8917
|
}
|
9781
8918
|
else {
|
9782
8919
|
entryTypeResult = getTypeOfExpression(entry,
|
9783
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedEntryType
|
8920
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedEntryType));
|
9784
8921
|
}
|
9785
8922
|
entryTypes.push(entryTypeResult.type);
|
9786
8923
|
if (entryTypeResult.isIncomplete) {
|
@@ -9798,7 +8935,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9798
8935
|
});
|
9799
8936
|
const isTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
9800
8937
|
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, builtInClassName);
|
9801
|
-
const specializedEntryType =
|
8938
|
+
const specializedEntryType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedEntryType), entryTypes, !isTypeInvariant);
|
9802
8939
|
if (!specializedEntryType) {
|
9803
8940
|
return { type: types_1.UnknownType.create(), isIncomplete, typeErrors: true, expectedTypeDiagAddendum };
|
9804
8941
|
}
|
@@ -9881,17 +9018,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9881
9018
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, message + diag.getString(), entry);
|
9882
9019
|
}
|
9883
9020
|
}
|
9884
|
-
function
|
9885
|
-
var _a;
|
9021
|
+
function inferTypeArgFromExpectedEntryType(inferenceContext, entryTypes, isNarrowable) {
|
9886
9022
|
// If the expected type is Any, the resulting type becomes Any.
|
9887
9023
|
if ((0, types_1.isAnyOrUnknown)(inferenceContext.expectedType)) {
|
9888
9024
|
return inferenceContext.expectedType;
|
9889
9025
|
}
|
9890
|
-
const typeVarContext =
|
9026
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
9027
|
+
const expectedType = inferenceContext.expectedType;
|
9891
9028
|
let isCompatible = true;
|
9892
9029
|
entryTypes.forEach((entryType) => {
|
9893
|
-
if (isCompatible &&
|
9894
|
-
!assignType(inferenceContext.expectedType, entryType, /* diag */ undefined, typeVarContext)) {
|
9030
|
+
if (isCompatible && !assignType(expectedType, entryType, /* diag */ undefined, typeVarContext)) {
|
9895
9031
|
isCompatible = false;
|
9896
9032
|
}
|
9897
9033
|
});
|
@@ -9904,39 +9040,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9904
9040
|
? combinedTypes
|
9905
9041
|
: stripLiteralValue(combinedTypes);
|
9906
9042
|
}
|
9907
|
-
|
9908
|
-
return (0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext);
|
9909
|
-
}
|
9910
|
-
return inferenceContext.expectedType;
|
9911
|
-
}
|
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 };
|
9043
|
+
return (0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true });
|
9940
9044
|
}
|
9941
9045
|
function getTypeOfYield(node) {
|
9942
9046
|
let expectedYieldType;
|
@@ -9990,7 +9094,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9990
9094
|
function getTypeOfLambda(node, inferenceContext) {
|
9991
9095
|
let isIncomplete = !!(inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete);
|
9992
9096
|
const functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* PartiallyEvaluated */);
|
9993
|
-
functionType.details.typeVarScopeId = getScopeIdForNode(node);
|
9097
|
+
functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
|
9994
9098
|
// Pre-cache the incomplete function type in case the evaluation of the
|
9995
9099
|
// lambda depends on itself.
|
9996
9100
|
writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
|
@@ -10079,36 +9183,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10079
9183
|
type: types_1.UnknownType.create(),
|
10080
9184
|
});
|
10081
9185
|
}
|
10082
|
-
|
9186
|
+
const expectedReturnType = expectedFunctionType
|
10083
9187
|
? getFunctionEffectiveReturnType(expectedFunctionType)
|
10084
9188
|
: undefined;
|
10085
|
-
if (expectedReturnType && (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext)) {
|
10086
|
-
expectedReturnType = (0, typeUtils_1.applySolvedTypeVars)(expectedReturnType, inferenceContext.typeVarContext);
|
10087
|
-
}
|
10088
9189
|
// If we're speculatively evaluating the lambda, create another speculative
|
10089
9190
|
// evaluation scope for the return expression and do not allow retention
|
10090
9191
|
// of the cached types.
|
10091
9192
|
const inferLambdaReturnType = () => {
|
10092
9193
|
const returnTypeResult = getTypeOfExpression(node.expression,
|
10093
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType
|
9194
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType));
|
10094
9195
|
functionType.inferredReturnType = returnTypeResult.type;
|
10095
9196
|
if (returnTypeResult.isIncomplete) {
|
10096
9197
|
isIncomplete = true;
|
10097
9198
|
}
|
10098
9199
|
};
|
10099
|
-
|
10100
|
-
|
10101
|
-
|
10102
|
-
|
10103
|
-
|
10104
|
-
useSpeculativeMode(node.expression, () => {
|
10105
|
-
inferLambdaReturnType();
|
10106
|
-
},
|
10107
|
-
/* allowCacheRetention */ false);
|
10108
|
-
}
|
10109
|
-
else {
|
9200
|
+
// We need to set allowCacheRetention to false because we don't want to
|
9201
|
+
// cache the type of the lambda return expression because it depends on
|
9202
|
+
// the parameter types that we set above, and the speculative type cache
|
9203
|
+
// doesn't know about that context.
|
9204
|
+
useSpeculativeMode(isSpeculativeModeInUse(node) || (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete) ? node.expression : undefined, () => {
|
10110
9205
|
inferLambdaReturnType();
|
10111
|
-
}
|
9206
|
+
},
|
9207
|
+
/* allowCacheRetention */ false);
|
10112
9208
|
// Mark the function type as no longer being evaluated.
|
10113
9209
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
10114
9210
|
return { type: functionType, isIncomplete };
|
@@ -10201,7 +9297,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10201
9297
|
// Evaluate the test expression to validate it and mark symbols
|
10202
9298
|
// as referenced. Don't bother doing this if we're in speculative
|
10203
9299
|
// mode because it doesn't affect the element type.
|
10204
|
-
if (!
|
9300
|
+
if (!isSpeculativeModeInUse(node.testExpression)) {
|
10205
9301
|
getTypeOfExpression(node.testExpression);
|
10206
9302
|
}
|
10207
9303
|
}
|
@@ -10268,7 +9364,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10268
9364
|
function getTypeOfSlice(node) {
|
10269
9365
|
// Evaluate the expressions to report errors and record symbol
|
10270
9366
|
// references. We can skip this if we're executing speculatively.
|
10271
|
-
if (!
|
9367
|
+
if (!isSpeculativeModeInUse(node)) {
|
10272
9368
|
if (node.startValue) {
|
10273
9369
|
getTypeOfExpression(node.startValue);
|
10274
9370
|
}
|
@@ -10341,7 +9437,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10341
9437
|
const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
|
10342
9438
|
types_1.TypeBase.setSpecialForm(functionType);
|
10343
9439
|
functionType.details.declaredReturnType = types_1.UnknownType.create();
|
10344
|
-
functionType.details.typeVarScopeId = getScopeIdForNode(errorNode);
|
9440
|
+
functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(errorNode);
|
10345
9441
|
if (typeArgs && typeArgs.length > 0) {
|
10346
9442
|
if (typeArgs[0].typeList) {
|
10347
9443
|
const typeList = typeArgs[0].typeList;
|
@@ -11035,14 +10131,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11035
10131
|
}), errorNode);
|
11036
10132
|
}
|
11037
10133
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(name);
|
11038
|
-
const typeAliasScopeId = getScopeIdForNode(name);
|
10134
|
+
const typeAliasScopeId = ParseTreeUtils.getScopeIdForNode(name);
|
11039
10135
|
const boundTypeVars = typeParameters.filter((typeVar) => typeVar.scopeId !== typeAliasScopeId && typeVar.scopeType === 0 /* Class */);
|
11040
10136
|
if (boundTypeVars.length > 0) {
|
11041
10137
|
addError(localize_1.Localizer.Diagnostic.genericTypeAliasBoundTypeVar().format({
|
11042
10138
|
names: boundTypeVars.map((t) => `${t.details.name}`).join(', '),
|
11043
10139
|
}), errorNode);
|
11044
10140
|
}
|
11045
|
-
return types_1.TypeBase.cloneForTypeAlias(type, name.value,
|
10141
|
+
return types_1.TypeBase.cloneForTypeAlias(type, name.value, ParseTreeUtils.getClassFullName(name, fileInfo.moduleName, name.value), typeAliasScopeId, typeParameters.length > 0 ? typeParameters : undefined);
|
11046
10142
|
}
|
11047
10143
|
function createSpecialBuiltInClass(node, assignedName, aliasMapEntry) {
|
11048
10144
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
@@ -11256,7 +10352,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11256
10352
|
typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${typeAliasNameNode.value}`);
|
11257
10353
|
typeAliasTypeVar.details.isSynthesized = true;
|
11258
10354
|
typeAliasTypeVar.details.recursiveTypeAliasName = typeAliasNameNode.value;
|
11259
|
-
const scopeId = getScopeIdForNode(typeAliasNameNode);
|
10355
|
+
const scopeId = ParseTreeUtils.getScopeIdForNode(typeAliasNameNode);
|
11260
10356
|
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
11261
10357
|
typeAliasTypeVar.scopeId = scopeId;
|
11262
10358
|
// Write the type back to the type cache. It will be replaced below.
|
@@ -11286,7 +10382,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11286
10382
|
if (assignType(declaredType, srcType)) {
|
11287
10383
|
// Narrow the resulting type if possible.
|
11288
10384
|
if (!(0, types_1.isAnyOrUnknown)(srcType)) {
|
11289
|
-
srcType = narrowTypeBasedOnAssignment(declaredType, srcType);
|
10385
|
+
srcType = narrowTypeBasedOnAssignment(node, declaredType, srcType);
|
11290
10386
|
}
|
11291
10387
|
}
|
11292
10388
|
}
|
@@ -11356,59 +10452,67 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11356
10452
|
// variables since they use normal variable assignment syntax.
|
11357
10453
|
function getTypeOfTypeAlias(node) {
|
11358
10454
|
var _a;
|
11359
|
-
|
10455
|
+
return getTypeOfTypeAliasCommon(node, node.name, node.expression, (_a = node.typeParameters) === null || _a === void 0 ? void 0 : _a.parameters, () => {
|
10456
|
+
let typeParameters = [];
|
10457
|
+
if (node.typeParameters) {
|
10458
|
+
typeParameters = evaluateTypeParameterList(node.typeParameters);
|
10459
|
+
}
|
10460
|
+
return typeParameters;
|
10461
|
+
});
|
10462
|
+
}
|
10463
|
+
// This function is common to the handling of "type" statements and explicit
|
10464
|
+
// calls to the TypeAliasType constructor.
|
10465
|
+
function getTypeOfTypeAliasCommon(declNode, nameNode, valueNode, typeParamNodes, getTypeParamCallback) {
|
10466
|
+
const cachedType = readTypeCache(nameNode, 0 /* None */);
|
11360
10467
|
if (cachedType) {
|
11361
10468
|
return cachedType;
|
11362
10469
|
}
|
11363
10470
|
// Synthesize a type variable that represents the type alias while we're
|
11364
10471
|
// evaluating it. This allows us to handle recursive definitions.
|
11365
|
-
const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${
|
10472
|
+
const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${nameNode.value}`);
|
11366
10473
|
typeAliasTypeVar.details.isSynthesized = true;
|
11367
|
-
typeAliasTypeVar.details.recursiveTypeAliasName =
|
11368
|
-
const scopeId = getScopeIdForNode(
|
10474
|
+
typeAliasTypeVar.details.recursiveTypeAliasName = nameNode.value;
|
10475
|
+
const scopeId = ParseTreeUtils.getScopeIdForNode(nameNode);
|
11369
10476
|
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
11370
10477
|
typeAliasTypeVar.scopeId = scopeId;
|
11371
10478
|
// Write the type to the type cache. It will be replaced below.
|
11372
|
-
writeTypeCache(
|
10479
|
+
writeTypeCache(nameNode, { type: typeAliasTypeVar }, /* flags */ undefined);
|
11373
10480
|
// Set a partial type to handle recursive (self-referential) type aliases.
|
11374
|
-
const scope = ScopeUtils.getScopeForNode(
|
11375
|
-
const typeAliasSymbol = scope === null || scope === void 0 ? void 0 : scope.lookUpSymbolRecursive(
|
11376
|
-
const typeAliasDecl = AnalyzerNodeInfo.getDeclaration(
|
10481
|
+
const scope = ScopeUtils.getScopeForNode(declNode);
|
10482
|
+
const typeAliasSymbol = scope === null || scope === void 0 ? void 0 : scope.lookUpSymbolRecursive(nameNode.value);
|
10483
|
+
const typeAliasDecl = AnalyzerNodeInfo.getDeclaration(declNode);
|
11377
10484
|
if (typeAliasDecl && typeAliasSymbol) {
|
11378
10485
|
setSymbolResolutionPartialType(typeAliasSymbol.symbol, typeAliasDecl, typeAliasTypeVar);
|
11379
10486
|
}
|
11380
|
-
|
11381
|
-
|
11382
|
-
|
11383
|
-
|
11384
|
-
}
|
11385
|
-
if (!isLegalTypeAliasExpressionForm(node.expression)) {
|
11386
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIllegalExpressionForm(), node.expression);
|
10487
|
+
const typeParameters = getTypeParamCallback();
|
10488
|
+
typeAliasTypeVar.details.recursiveTypeParameters = typeParameters;
|
10489
|
+
if (!isLegalTypeAliasExpressionForm(valueNode)) {
|
10490
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(valueNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIllegalExpressionForm(), valueNode);
|
11387
10491
|
}
|
11388
|
-
const aliasTypeResult = getTypeOfExpressionExpectingType(
|
10492
|
+
const aliasTypeResult = getTypeOfExpressionExpectingType(valueNode, { allowForwardReference: true });
|
11389
10493
|
let isIncomplete = false;
|
11390
10494
|
let aliasType = aliasTypeResult.type;
|
11391
10495
|
if (aliasTypeResult.isIncomplete) {
|
11392
10496
|
isIncomplete = true;
|
11393
10497
|
}
|
11394
|
-
aliasType = transformTypeForTypeAlias(aliasType,
|
10498
|
+
aliasType = transformTypeForTypeAlias(aliasType, nameNode, valueNode, typeParameters, typeParamNodes);
|
11395
10499
|
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
|
11396
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(
|
11397
|
-
name:
|
11398
|
-
}),
|
10500
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(valueNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
10501
|
+
name: nameNode.value,
|
10502
|
+
}), valueNode);
|
11399
10503
|
aliasType = types_1.UnknownType.create();
|
11400
10504
|
}
|
11401
10505
|
// Set the resulting type to the boundType of the original type alias
|
11402
10506
|
// to support recursive type aliases.
|
11403
10507
|
typeAliasTypeVar.details.boundType = aliasType;
|
11404
|
-
writeTypeCache(
|
10508
|
+
writeTypeCache(nameNode, { type: aliasType, isIncomplete }, 0 /* None */);
|
11405
10509
|
return aliasType;
|
11406
10510
|
}
|
11407
10511
|
function evaluateTypesForAugmentedAssignment(node) {
|
11408
10512
|
if (isTypeCached(node)) {
|
11409
10513
|
return;
|
11410
10514
|
}
|
11411
|
-
const destTypeResult = getTypeOfAugmentedAssignment(node, /* inferenceContext */ undefined);
|
10515
|
+
const destTypeResult = (0, operations_1.getTypeOfAugmentedAssignment)(evaluatorInterface, node, /* inferenceContext */ undefined);
|
11412
10516
|
writeTypeCache(node, destTypeResult, 0 /* None */);
|
11413
10517
|
}
|
11414
10518
|
function getPseudoGenericTypeVarName(paramName) {
|
@@ -11454,7 +10558,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11454
10558
|
/* typeSourceId */ 0,
|
11455
10559
|
/* declaredMetaclass */ undefined,
|
11456
10560
|
/* effectiveMetaclass */ undefined, ParseTreeUtils.getDocString(node.suite.statements));
|
11457
|
-
classType.details.typeVarScopeId = getScopeIdForNode(node);
|
10561
|
+
classType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
|
11458
10562
|
// Some classes refer to themselves within type arguments used within
|
11459
10563
|
// base classes. We'll register the partially-constructed class type
|
11460
10564
|
// to allow these to be resolved.
|
@@ -11771,9 +10875,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11771
10875
|
classType.details.typeParameters = genericParams.map((param) => {
|
11772
10876
|
const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
|
11773
10877
|
typeVar.details.isSynthesized = true;
|
11774
|
-
typeVar.scopeId = getScopeIdForNode(initDeclNode);
|
10878
|
+
typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
|
11775
10879
|
typeVar.details.boundType = types_1.UnknownType.create();
|
11776
|
-
return types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
10880
|
+
return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
11777
10881
|
});
|
11778
10882
|
}
|
11779
10883
|
}
|
@@ -11903,11 +11007,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11903
11007
|
writeTypeCache(node.name, { type: classType }, 0 /* None */);
|
11904
11008
|
// Update the decorated class type.
|
11905
11009
|
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
11010
|
// Validate that arguments passed to `__init_subclass__` are of the correct type.
|
11912
11011
|
// Defer this if the metaclass calculation is deferred.
|
11913
11012
|
if (!isMetaclassDeferred) {
|
@@ -12106,7 +11205,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12106
11205
|
decoratorCallType.details.builtInName === 'dataclass_transform') {
|
12107
11206
|
originalClassType.details.classDataClassTransform = (0, dataClasses_1.validateDataClassTransformDecorator)(evaluatorInterface, decoratorNode.expression);
|
12108
11207
|
}
|
12109
|
-
else if (decoratorCallType.details.
|
11208
|
+
else if (decoratorCallType.details.builtInName === 'deprecated') {
|
12110
11209
|
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12111
11210
|
return inputClassType;
|
12112
11211
|
}
|
@@ -12342,10 +11441,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12342
11441
|
functionFlags |= 512 /* Async */;
|
12343
11442
|
}
|
12344
11443
|
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);
|
11444
|
+
functionType.details.typeVarScopeId = ParseTreeUtils.getScopeIdForNode(node);
|
12346
11445
|
if (node.name.value === '__init__' || node.name.value === '__new__') {
|
12347
11446
|
if (containingClassNode) {
|
12348
|
-
functionType.details.constructorTypeVarScopeId = getScopeIdForNode(containingClassNode);
|
11447
|
+
functionType.details.constructorTypeVarScopeId = ParseTreeUtils.getScopeIdForNode(containingClassNode);
|
12349
11448
|
}
|
12350
11449
|
}
|
12351
11450
|
if (fileInfo.isBuiltInStubFile || fileInfo.isTypingStubFile || fileInfo.isTypingExtensionsStubFile) {
|
@@ -12931,7 +12030,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12931
12030
|
undecoratedType.details.decoratorDataClassBehaviors = (0, dataClasses_1.validateDataClassTransformDecorator)(evaluatorInterface, decoratorNode.expression);
|
12932
12031
|
return inputFunctionType;
|
12933
12032
|
}
|
12934
|
-
if (decoratorCallType.details.
|
12033
|
+
if (decoratorCallType.details.builtInName === 'deprecated') {
|
12935
12034
|
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12936
12035
|
return inputFunctionType;
|
12937
12036
|
}
|
@@ -14549,8 +13648,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14549
13648
|
}
|
14550
13649
|
function getTypeOfExpressionExpectingType(node, options) {
|
14551
13650
|
let flags = 128 /* ExpectingType */ | 8 /* EvaluateStringLiteralAsType */ | 131072 /* DisallowClassVar */;
|
13651
|
+
if (!(options === null || options === void 0 ? void 0 : options.allowTypeVarsWithoutScopeId)) {
|
13652
|
+
flags |= 4096 /* DisallowTypeVarsWithoutScopeId */;
|
13653
|
+
}
|
14552
13654
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
14553
|
-
if (fileInfo.isStubFile) {
|
13655
|
+
if (fileInfo.isStubFile || (options === null || options === void 0 ? void 0 : options.allowForwardReference)) {
|
14554
13656
|
flags |= 4 /* AllowForwardReferences */;
|
14555
13657
|
}
|
14556
13658
|
else {
|
@@ -14697,10 +13799,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14697
13799
|
throw e;
|
14698
13800
|
}
|
14699
13801
|
}
|
14700
|
-
// Disables recording of errors and warnings and disables
|
14701
|
-
//
|
14702
|
-
//
|
13802
|
+
// Disables recording of errors and warnings and disables any caching of
|
13803
|
+
// types, under the assumption that we're performing speculative evaluations.
|
13804
|
+
// If speculativeNode is undefined, speculative mode is not used. This is
|
13805
|
+
// useful in cases where we conditionally want to use speculative mode.
|
14703
13806
|
function useSpeculativeMode(speculativeNode, callback, allowCacheRetention = true) {
|
13807
|
+
if (!speculativeNode) {
|
13808
|
+
return callback();
|
13809
|
+
}
|
14704
13810
|
speculativeTypeTracker.enterSpeculativeContext(speculativeNode, allowCacheRetention);
|
14705
13811
|
try {
|
14706
13812
|
const result = callback();
|
@@ -14727,6 +13833,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14727
13833
|
throw e;
|
14728
13834
|
}
|
14729
13835
|
}
|
13836
|
+
// Indicates whether the specified node is within a context that
|
13837
|
+
// is currently being evaluated speculative. If node is undefined,
|
13838
|
+
// returns true if any node is being evaluated speculatively.
|
13839
|
+
function isSpeculativeModeInUse(node) {
|
13840
|
+
return speculativeTypeTracker.isSpeculative(node);
|
13841
|
+
}
|
14730
13842
|
function getDeclarationFromFunctionNamedParameter(type, paramName) {
|
14731
13843
|
if ((0, types_1.isFunction)(type)) {
|
14732
13844
|
if (type.details.declaration) {
|
@@ -15156,7 +14268,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15156
14268
|
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
15157
14269
|
scopeType = 2 /* TypeAlias */;
|
15158
14270
|
}
|
15159
|
-
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
14271
|
+
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
15160
14272
|
}
|
15161
14273
|
return typeVar;
|
15162
14274
|
}
|
@@ -15582,7 +14694,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15582
14694
|
}
|
15583
14695
|
}
|
15584
14696
|
typesToCombine.push(type);
|
15585
|
-
if (
|
14697
|
+
if (isSpeculativeModeInUse(decl.node)) {
|
15586
14698
|
includesSpeculativeResult = true;
|
15587
14699
|
}
|
15588
14700
|
}
|
@@ -16644,11 +15756,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16644
15756
|
}
|
16645
15757
|
return true;
|
16646
15758
|
}
|
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
15759
|
if ((0, types_1.isUnion)(destType)) {
|
16653
15760
|
if ((0, types_1.isUnion)(srcType)) {
|
16654
15761
|
if (assignFromUnionType(destType, srcType,
|
@@ -16875,7 +15982,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16875
15982
|
}
|
16876
15983
|
// If it's a class, use the constructor for type compatibility checking.
|
16877
15984
|
if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
|
16878
|
-
const constructor = createFunctionFromConstructor(concreteSrcType, recursionCount);
|
15985
|
+
const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
|
16879
15986
|
if (constructor) {
|
16880
15987
|
concreteSrcType = constructor;
|
16881
15988
|
}
|
@@ -17322,98 +16429,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17322
16429
|
});
|
17323
16430
|
});
|
17324
16431
|
}
|
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
16432
|
// If the class is a protocol and it has a `__call__` method but no other methods
|
17418
16433
|
// or attributes that would be incompatible with a function, this method returns
|
17419
16434
|
// the signature of the call implied by the `__call__` method. Otherwise it returns
|
@@ -18028,7 +17043,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18028
17043
|
}
|
18029
17044
|
// Apply any solved source TypeVars to the dest TypeVar solutions. This
|
18030
17045
|
// allows for higher-order functions to accept generic callbacks.
|
18031
|
-
|
17046
|
+
(0, typeUtils_1.applySourceContextTypeVars)(destTypeVarContext, srcTypeVarContext);
|
18032
17047
|
return canAssign;
|
18033
17048
|
}
|
18034
17049
|
// If the declaredType contains type arguments that are "Any" and
|
@@ -18036,7 +17051,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18036
17051
|
// replace that type argument in the assigned type. This function assumes
|
18037
17052
|
// that the caller has already verified that the assignedType is assignable
|
18038
17053
|
// to the declaredType.
|
18039
|
-
function replaceTypeArgsWithAny(declaredType, assignedType, recursionCount = 0) {
|
17054
|
+
function replaceTypeArgsWithAny(node, declaredType, assignedType, recursionCount = 0) {
|
18040
17055
|
if (recursionCount > types_1.maxTypeRecursionCount) {
|
18041
17056
|
return undefined;
|
18042
17057
|
}
|
@@ -18051,7 +17066,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18051
17066
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(assignedType));
|
18052
17067
|
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneForSpecialization(assignedType,
|
18053
17068
|
/* typeArguments */ undefined,
|
18054
|
-
/* isTypeArgumentExplicit */ false), declaredType, typeVarContext,
|
17069
|
+
/* isTypeArgumentExplicit */ false), declaredType, typeVarContext, ParseTreeUtils.getTypeVarScopesForNode(node));
|
18055
17070
|
let replacedTypeArg = false;
|
18056
17071
|
const newTypeArgs = assignedType.typeArguments.map((typeArg, index) => {
|
18057
17072
|
const typeParam = assignedType.details.typeParameters[index];
|
@@ -18063,7 +17078,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18063
17078
|
}
|
18064
17079
|
else if ((0, types_1.isClassInstance)(expectedTypeArgType) && (0, types_1.isClassInstance)(typeArg)) {
|
18065
17080
|
// Recursively replace Any in the type argument.
|
18066
|
-
const recursiveReplacement = replaceTypeArgsWithAny(expectedTypeArgType, typeArg, recursionCount);
|
17081
|
+
const recursiveReplacement = replaceTypeArgsWithAny(node, expectedTypeArgType, typeArg, recursionCount);
|
18067
17082
|
if (recursiveReplacement) {
|
18068
17083
|
replacedTypeArg = true;
|
18069
17084
|
return recursiveReplacement;
|
@@ -18080,7 +17095,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18080
17095
|
}
|
18081
17096
|
// When a value is assigned to a variable with a declared type,
|
18082
17097
|
// we may be able to narrow the type based on the assignment.
|
18083
|
-
function narrowTypeBasedOnAssignment(declaredType, assignedType) {
|
17098
|
+
function narrowTypeBasedOnAssignment(node, declaredType, assignedType) {
|
18084
17099
|
const narrowedType = (0, typeUtils_1.mapSubtypes)(assignedType, (assignedSubtype) => {
|
18085
17100
|
const narrowedSubtype = (0, typeUtils_1.mapSubtypes)(declaredType, (declaredSubtype) => {
|
18086
17101
|
// We can't narrow "Any".
|
@@ -18091,13 +17106,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18091
17106
|
// If the source is generic and has unspecified type arguments,
|
18092
17107
|
// see if we can determine then based on the declared type.
|
18093
17108
|
if ((0, types_1.isInstantiableClass)(declaredSubtype) && (0, types_1.isInstantiableClass)(assignedSubtype)) {
|
18094
|
-
const result = replaceTypeArgsWithAny(declaredSubtype, assignedSubtype);
|
17109
|
+
const result = replaceTypeArgsWithAny(node, declaredSubtype, assignedSubtype);
|
18095
17110
|
if (result) {
|
18096
17111
|
assignedSubtype = result;
|
18097
17112
|
}
|
18098
17113
|
}
|
18099
17114
|
else if ((0, types_1.isClassInstance)(declaredSubtype) && (0, types_1.isClassInstance)(assignedSubtype)) {
|
18100
|
-
const result = replaceTypeArgsWithAny(types_1.ClassType.cloneAsInstantiable(declaredSubtype), types_1.ClassType.cloneAsInstantiable(assignedSubtype));
|
17115
|
+
const result = replaceTypeArgsWithAny(node, types_1.ClassType.cloneAsInstantiable(declaredSubtype), types_1.ClassType.cloneAsInstantiable(assignedSubtype));
|
18101
17116
|
if (result) {
|
18102
17117
|
assignedSubtype = types_1.ClassType.cloneAsInstance(result);
|
18103
17118
|
}
|
@@ -18562,6 +17577,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18562
17577
|
return types_1.FunctionType.clone(memberType, /* stripFirstParam */ true);
|
18563
17578
|
}
|
18564
17579
|
if (types_1.FunctionType.isInstanceMethod(memberType)) {
|
17580
|
+
// If the baseType is a metaclass, don't specialize the function.
|
17581
|
+
if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
|
17582
|
+
return memberType;
|
17583
|
+
}
|
18565
17584
|
const baseObj = (0, types_1.isClassInstance)(baseType)
|
18566
17585
|
? baseType
|
18567
17586
|
: types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType));
|
@@ -18802,6 +17821,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18802
17821
|
function printControlFlowGraph(flowNode, reference, callName, logger) {
|
18803
17822
|
return codeFlowEngine.printControlFlowGraph(flowNode, reference, callName, logger);
|
18804
17823
|
}
|
17824
|
+
function printTypeVarContext(typeVarContext) {
|
17825
|
+
const contexts = typeVarContext.getSignatureContexts();
|
17826
|
+
contexts.forEach((context, index) => {
|
17827
|
+
if (contexts.length > 1) {
|
17828
|
+
console.log(`Signature context ${index + 1}:`);
|
17829
|
+
}
|
17830
|
+
context.getTypeVars().forEach((typeVarEntry) => {
|
17831
|
+
const type = context.getTypeVarType(typeVarEntry.typeVar);
|
17832
|
+
console.log(` ${typeVarEntry.typeVar.details.name}: ${type ? printType(type) : '<none>'}`);
|
17833
|
+
});
|
17834
|
+
});
|
17835
|
+
}
|
18805
17836
|
const evaluatorInterface = {
|
18806
17837
|
runWithCancellationToken,
|
18807
17838
|
getType,
|
@@ -18840,7 +17871,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18840
17871
|
getGetterTypeFromProperty,
|
18841
17872
|
getTypeOfArgument,
|
18842
17873
|
markNamesAccessed,
|
18843
|
-
getScopeIdForNode,
|
18844
17874
|
makeTopLevelTypeVarsConcrete,
|
18845
17875
|
mapSubtypesExpandTypeVars,
|
18846
17876
|
lookUpSymbolRecursive,
|
@@ -18855,6 +17885,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18855
17885
|
getBuiltInType,
|
18856
17886
|
getTypeOfMember,
|
18857
17887
|
getTypeOfObjectMember,
|
17888
|
+
getTypeOfClassMemberName,
|
18858
17889
|
getBoundMethod,
|
18859
17890
|
getTypeOfMagicMethodReturn,
|
18860
17891
|
bindFunctionToClassOrObject,
|
@@ -18863,6 +17894,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18863
17894
|
narrowConstrainedTypeVar,
|
18864
17895
|
assignType,
|
18865
17896
|
validateOverrideMethod,
|
17897
|
+
validateCallArguments,
|
17898
|
+
validateTypeArg,
|
18866
17899
|
assignTypeToExpression,
|
18867
17900
|
assignClassToSelf,
|
18868
17901
|
getTypedDictClassType,
|
@@ -18889,9 +17922,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18889
17922
|
getTypeCacheEntryCount,
|
18890
17923
|
disposeEvaluator,
|
18891
17924
|
useSpeculativeMode,
|
17925
|
+
isSpeculativeModeInUse,
|
18892
17926
|
setTypeForNode,
|
18893
17927
|
checkForCancellation,
|
18894
17928
|
printControlFlowGraph,
|
17929
|
+
printTypeVarContext,
|
18895
17930
|
};
|
18896
17931
|
const codeFlowEngine = (0, codeFlowEngine_1.getCodeFlowEngine)(evaluatorInterface, speculativeTypeTracker);
|
18897
17932
|
return evaluatorInterface;
|