@zzzen/pyright-internal 1.2.0-dev.20230101 → 1.2.0-dev.20230115
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/analyzerFileInfo.js +14 -1
- package/dist/analyzer/analyzerFileInfo.js.map +1 -1
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +3 -3
- package/dist/analyzer/backgroundAnalysisProgram.js +4 -4
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -1
- package/dist/analyzer/checker.js +145 -53
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +26 -11
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +4 -2
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/dataClasses.js +6 -1
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +2 -1
- package/dist/analyzer/importResolver.js +18 -3
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/patternMatching.js +2 -2
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +1 -0
- package/dist/analyzer/program.js +54 -32
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/regions.js +14 -5
- package/dist/analyzer/regions.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -2
- package/dist/analyzer/service.js +14 -12
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +4 -3
- package/dist/analyzer/sourceFile.js +4 -4
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceMapper.d.ts +2 -2
- package/dist/analyzer/sourceMapper.js +14 -5
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +0 -1
- package/dist/analyzer/typeCacheUtils.js +3 -3
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeDocStringUtils.d.ts +2 -1
- package/dist/analyzer/typeDocStringUtils.js +18 -7
- package/dist/analyzer/typeDocStringUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +494 -423
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +20 -13
- package/dist/analyzer/typeEvaluatorTypes.js +15 -15
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.d.ts +5 -1
- package/dist/analyzer/typeGuards.js +204 -44
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +8 -0
- package/dist/analyzer/typeUtils.js +15 -4
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +3 -0
- package/dist/analyzer/types.js +10 -2
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +4 -1
- package/dist/backgroundAnalysisBase.js +1 -1
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.d.ts +5 -2
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/commands/createTypeStub.js +3 -0
- package/dist/commands/createTypeStub.js.map +1 -1
- package/dist/commands/quickActionCommand.js +1 -1
- package/dist/commands/quickActionCommand.js.map +1 -1
- package/dist/common/collectionUtils.d.ts +1 -0
- package/dist/common/collectionUtils.js +9 -1
- package/dist/common/collectionUtils.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +4 -0
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/diagnosticRules.d.ts +1 -0
- package/dist/common/diagnosticRules.js +1 -0
- package/dist/common/diagnosticRules.js.map +1 -1
- package/dist/common/fileSystem.d.ts +1 -0
- package/dist/common/fileSystem.js.map +1 -1
- package/dist/common/textEditUtils.d.ts +3 -2
- package/dist/common/textEditUtils.js +11 -10
- package/dist/common/textEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +1 -1
- package/dist/languageServerBase.js +2 -2
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +3 -0
- package/dist/languageService/completionProvider.js +212 -159
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/documentSymbolCollector.d.ts +12 -4
- package/dist/languageService/documentSymbolCollector.js +103 -22
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/documentSymbolProvider.js +6 -0
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +0 -1
- package/dist/languageService/hoverProvider.js +7 -20
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/indentationUtils.d.ts +1 -1
- package/dist/languageService/indentationUtils.js +74 -29
- package/dist/languageService/indentationUtils.js.map +1 -1
- package/dist/languageService/referencesProvider.d.ts +5 -4
- package/dist/languageService/referencesProvider.js +15 -10
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameModuleProvider.js +11 -11
- package/dist/languageService/renameModuleProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.d.ts +5 -1
- package/dist/languageService/tooltipUtils.js +28 -4
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +3 -0
- package/dist/localization/localize.js +3 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +3 -0
- package/dist/parser/tokenizer.js +6 -2
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/tests/checker.test.js +16 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/completions.test.d.ts +1 -0
- package/dist/tests/completions.test.js +331 -0
- package/dist/tests/completions.test.js.map +1 -0
- package/dist/tests/documentSymbolCollector.test.js +86 -5
- package/dist/tests/documentSymbolCollector.test.js.map +1 -1
- package/dist/tests/filesystem.test.js +11 -0
- package/dist/tests/filesystem.test.js.map +1 -1
- package/dist/tests/fourslash/rename.init.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.init.fourslash.js +23 -0
- package/dist/tests/fourslash/rename.init.fourslash.js.map +1 -0
- package/dist/tests/harness/fourslash/testState.d.ts +2 -2
- package/dist/tests/harness/fourslash/testState.js +10 -7
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.d.ts +2 -2
- package/dist/tests/harness/vfs/filesystem.js +5 -1
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/hoverProvider.test.d.ts +1 -0
- package/dist/tests/hoverProvider.test.js +247 -0
- package/dist/tests/hoverProvider.test.js.map +1 -0
- package/dist/tests/indentationUtils.ptvs.test.js +13 -13
- package/dist/tests/indentationUtils.ptvs.test.js.map +1 -1
- package/dist/tests/indentationUtils.test.js +68 -10
- package/dist/tests/indentationUtils.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +24 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +5 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +10 -2
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +4 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +6 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/workspaceMap.js +1 -3
- package/dist/workspaceMap.js.map +1 -1
- package/package.json +6 -6
@@ -72,7 +72,7 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
72
72
|
}
|
73
73
|
if (ParseTreeUtils.isMatchingExpression(reference, leftExpression)) {
|
74
74
|
return (type) => {
|
75
|
-
return narrowTypeForIsNone(evaluator, type, adjIsPositiveTest);
|
75
|
+
return { type: narrowTypeForIsNone(evaluator, type, adjIsPositiveTest), isIncomplete: false };
|
76
76
|
};
|
77
77
|
}
|
78
78
|
if (leftExpression.nodeType === 24 /* Index */ &&
|
@@ -87,11 +87,31 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
87
87
|
const indexValue = leftExpression.items[0].valueExpression.value;
|
88
88
|
if (typeof indexValue === 'number') {
|
89
89
|
return (type) => {
|
90
|
-
return
|
90
|
+
return {
|
91
|
+
type: narrowTupleTypeForIsNone(evaluator, type, adjIsPositiveTest, indexValue),
|
92
|
+
isIncomplete: false,
|
93
|
+
};
|
91
94
|
};
|
92
95
|
}
|
93
96
|
}
|
94
97
|
}
|
98
|
+
// Look for "X is ...", "X is not ...", "X == ...", and "X != ...".
|
99
|
+
if (testExpression.rightExpression.nodeType === 18 /* Ellipsis */) {
|
100
|
+
// Allow the LHS to be either a simple expression or an assignment
|
101
|
+
// expression that assigns to a simple name.
|
102
|
+
let leftExpression = testExpression.leftExpression;
|
103
|
+
if (leftExpression.nodeType === 4 /* AssignmentExpression */) {
|
104
|
+
leftExpression = leftExpression.name;
|
105
|
+
}
|
106
|
+
if (ParseTreeUtils.isMatchingExpression(reference, leftExpression)) {
|
107
|
+
return (type) => {
|
108
|
+
return {
|
109
|
+
type: narrowTypeForIsEllipsis(evaluator, type, adjIsPositiveTest),
|
110
|
+
isIncomplete: false,
|
111
|
+
};
|
112
|
+
};
|
113
|
+
}
|
114
|
+
}
|
95
115
|
// Look for "type(X) is Y" or "type(X) is not Y".
|
96
116
|
if (isOrIsNotOperator && testExpression.leftExpression.nodeType === 9 /* Call */) {
|
97
117
|
if (testExpression.leftExpression.arguments.length === 1 &&
|
@@ -100,10 +120,14 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
100
120
|
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
101
121
|
const callType = evaluator.getTypeOfExpression(testExpression.leftExpression.leftExpression, 2 /* DoNotSpecialize */).type;
|
102
122
|
if ((0, types_1.isInstantiableClass)(callType) && types_1.ClassType.isBuiltIn(callType, 'type')) {
|
103
|
-
const
|
123
|
+
const classTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
124
|
+
const classType = evaluator.makeTopLevelTypeVarsConcrete(classTypeResult.type);
|
104
125
|
if ((0, types_1.isInstantiableClass)(classType)) {
|
105
126
|
return (type) => {
|
106
|
-
return
|
127
|
+
return {
|
128
|
+
type: narrowTypeForTypeIs(evaluator, type, classType, adjIsPositiveTest),
|
129
|
+
isIncomplete: !!classTypeResult.isIncomplete,
|
130
|
+
};
|
107
131
|
};
|
108
132
|
}
|
109
133
|
}
|
@@ -113,36 +137,70 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
113
137
|
// Look for "X is Y" or "X is not Y" where Y is a an enum or bool literal.
|
114
138
|
if (isOrIsNotOperator) {
|
115
139
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
|
116
|
-
const
|
140
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
141
|
+
const rightType = rightTypeResult.type;
|
117
142
|
if ((0, types_1.isClassInstance)(rightType) &&
|
118
143
|
(types_1.ClassType.isEnumClass(rightType) || types_1.ClassType.isBuiltIn(rightType, 'bool')) &&
|
119
144
|
rightType.literalValue !== undefined) {
|
120
145
|
return (type) => {
|
121
|
-
return
|
122
|
-
|
146
|
+
return {
|
147
|
+
type: narrowTypeForLiteralComparison(evaluator, type, rightType, adjIsPositiveTest,
|
148
|
+
/* isIsOperator */ true),
|
149
|
+
isIncomplete: !!rightTypeResult.isIncomplete,
|
150
|
+
};
|
123
151
|
};
|
124
152
|
}
|
125
153
|
}
|
154
|
+
// Look for X[<literal>] is <literal> or X[<literal>] is not <literal>
|
155
|
+
if (testExpression.leftExpression.nodeType === 24 /* Index */ &&
|
156
|
+
testExpression.leftExpression.items.length === 1 &&
|
157
|
+
!testExpression.leftExpression.trailingComma &&
|
158
|
+
testExpression.leftExpression.items[0].argumentCategory === 0 /* Simple */ &&
|
159
|
+
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.baseExpression)) {
|
160
|
+
const indexTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression.items[0].valueExpression);
|
161
|
+
const indexType = indexTypeResult.type;
|
162
|
+
if ((0, types_1.isClassInstance)(indexType) && (0, typeUtils_1.isLiteralType)(indexType)) {
|
163
|
+
if (types_1.ClassType.isBuiltIn(indexType, 'str')) {
|
164
|
+
const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
|
165
|
+
if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
|
166
|
+
return (type) => {
|
167
|
+
return {
|
168
|
+
type: narrowTypeForDiscriminatedDictEntryComparison(evaluator, type, indexType, rightType, adjIsPositiveTest),
|
169
|
+
isIncomplete: !!indexTypeResult.isIncomplete,
|
170
|
+
};
|
171
|
+
};
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
126
176
|
}
|
127
177
|
if (equalsOrNotEqualsOperator) {
|
128
178
|
// Look for X == <literal> or X != <literal>
|
129
179
|
const adjIsPositiveTest = testExpression.operator === 12 /* Equals */ ? isPositiveTest : !isPositiveTest;
|
130
180
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
|
131
|
-
const
|
181
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
182
|
+
const rightType = rightTypeResult.type;
|
132
183
|
if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
|
133
184
|
return (type) => {
|
134
|
-
return
|
135
|
-
|
185
|
+
return {
|
186
|
+
type: narrowTypeForLiteralComparison(evaluator, type, rightType, adjIsPositiveTest,
|
187
|
+
/* isIsOperator */ false),
|
188
|
+
isIncomplete: !!rightTypeResult.isIncomplete,
|
189
|
+
};
|
136
190
|
};
|
137
191
|
}
|
138
192
|
}
|
139
193
|
// Look for <literal> == X or <literal> != X
|
140
194
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.rightExpression)) {
|
141
|
-
const
|
195
|
+
const leftTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression);
|
196
|
+
const leftType = leftTypeResult.type;
|
142
197
|
if ((0, types_1.isClassInstance)(leftType) && leftType.literalValue !== undefined) {
|
143
198
|
return (type) => {
|
144
|
-
return
|
145
|
-
|
199
|
+
return {
|
200
|
+
type: narrowTypeForLiteralComparison(evaluator, type, leftType, adjIsPositiveTest,
|
201
|
+
/* isIsOperator */ false),
|
202
|
+
isIncomplete: !!leftTypeResult.isIncomplete,
|
203
|
+
};
|
146
204
|
};
|
147
205
|
}
|
148
206
|
}
|
@@ -152,21 +210,29 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
152
210
|
!testExpression.leftExpression.trailingComma &&
|
153
211
|
testExpression.leftExpression.items[0].argumentCategory === 0 /* Simple */ &&
|
154
212
|
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.baseExpression)) {
|
155
|
-
const
|
213
|
+
const indexTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression.items[0].valueExpression);
|
214
|
+
const indexType = indexTypeResult.type;
|
156
215
|
if ((0, types_1.isClassInstance)(indexType) && (0, typeUtils_1.isLiteralType)(indexType)) {
|
157
216
|
if (types_1.ClassType.isBuiltIn(indexType, 'str')) {
|
158
217
|
const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
|
159
218
|
if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
|
160
219
|
return (type) => {
|
161
|
-
return
|
220
|
+
return {
|
221
|
+
type: narrowTypeForDiscriminatedDictEntryComparison(evaluator, type, indexType, rightType, adjIsPositiveTest),
|
222
|
+
isIncomplete: !!indexTypeResult.isIncomplete,
|
223
|
+
};
|
162
224
|
};
|
163
225
|
}
|
164
226
|
}
|
165
227
|
else if (types_1.ClassType.isBuiltIn(indexType, 'int')) {
|
166
|
-
const
|
228
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
229
|
+
const rightType = rightTypeResult.type;
|
167
230
|
if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
|
168
231
|
return (type) => {
|
169
|
-
return
|
232
|
+
return {
|
233
|
+
type: narrowTypeForDiscriminatedTupleComparison(evaluator, type, indexType, rightType, adjIsPositiveTest),
|
234
|
+
isIncomplete: !!rightTypeResult.isIncomplete,
|
235
|
+
};
|
170
236
|
};
|
171
237
|
}
|
172
238
|
}
|
@@ -181,12 +247,16 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
181
247
|
testExpression.rightExpression.isInteger) {
|
182
248
|
const arg0Expr = testExpression.leftExpression.arguments[0].valueExpression;
|
183
249
|
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
184
|
-
const
|
250
|
+
const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression.leftExpression, 2 /* DoNotSpecialize */);
|
251
|
+
const callType = callTypeResult.type;
|
185
252
|
if ((0, types_1.isFunction)(callType) && callType.details.fullName === 'builtins.len') {
|
186
253
|
const tupleLength = testExpression.rightExpression.value;
|
187
254
|
if (typeof tupleLength === 'number') {
|
188
255
|
return (type) => {
|
189
|
-
return
|
256
|
+
return {
|
257
|
+
type: narrowTypeForTupleLength(evaluator, type, tupleLength, adjIsPositiveTest),
|
258
|
+
isIncomplete: !!callTypeResult.isIncomplete,
|
259
|
+
};
|
190
260
|
};
|
191
261
|
}
|
192
262
|
}
|
@@ -196,11 +266,15 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
196
266
|
if (equalsOrNotEqualsOperator &&
|
197
267
|
testExpression.leftExpression.nodeType === 35 /* MemberAccess */ &&
|
198
268
|
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression)) {
|
199
|
-
const
|
269
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
270
|
+
const rightType = rightTypeResult.type;
|
200
271
|
const memberName = testExpression.leftExpression.memberName;
|
201
272
|
if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
|
202
273
|
return (type) => {
|
203
|
-
return
|
274
|
+
return {
|
275
|
+
type: narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest),
|
276
|
+
isIncomplete: !!rightTypeResult.isIncomplete,
|
277
|
+
};
|
204
278
|
};
|
205
279
|
}
|
206
280
|
}
|
@@ -208,13 +282,17 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
208
282
|
// an enum or bool literal
|
209
283
|
if (testExpression.leftExpression.nodeType === 35 /* MemberAccess */ &&
|
210
284
|
ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression)) {
|
211
|
-
const
|
285
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
286
|
+
const rightType = rightTypeResult.type;
|
212
287
|
const memberName = testExpression.leftExpression.memberName;
|
213
288
|
if ((0, types_1.isClassInstance)(rightType) &&
|
214
289
|
(types_1.ClassType.isEnumClass(rightType) || types_1.ClassType.isBuiltIn(rightType, 'bool')) &&
|
215
290
|
rightType.literalValue !== undefined) {
|
216
291
|
return (type) => {
|
217
|
-
return
|
292
|
+
return {
|
293
|
+
type: narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest),
|
294
|
+
isIncomplete: !!rightTypeResult.isIncomplete,
|
295
|
+
};
|
218
296
|
};
|
219
297
|
}
|
220
298
|
}
|
@@ -226,27 +304,38 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
226
304
|
testExpression.rightExpression.constType === 26 /* None */) {
|
227
305
|
const memberName = testExpression.leftExpression.memberName;
|
228
306
|
return (type) => {
|
229
|
-
return
|
307
|
+
return {
|
308
|
+
type: narrowTypeForDiscriminatedFieldNoneComparison(evaluator, type, memberName.value, adjIsPositiveTest),
|
309
|
+
isIncomplete: false,
|
310
|
+
};
|
230
311
|
};
|
231
312
|
}
|
232
313
|
}
|
233
314
|
if (testExpression.operator === 41 /* In */ || testExpression.operator === 42 /* NotIn */) {
|
234
315
|
// Look for "x in y" or "x not in y" where y is one of several built-in types.
|
235
316
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
|
236
|
-
const
|
317
|
+
const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
|
318
|
+
const rightType = rightTypeResult.type;
|
237
319
|
const adjIsPositiveTest = testExpression.operator === 41 /* In */ ? isPositiveTest : !isPositiveTest;
|
238
320
|
return (type) => {
|
239
|
-
return
|
321
|
+
return {
|
322
|
+
type: narrowTypeForContainerType(evaluator, type, rightType, adjIsPositiveTest),
|
323
|
+
isIncomplete: !!rightTypeResult.isIncomplete,
|
324
|
+
};
|
240
325
|
};
|
241
326
|
}
|
242
327
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.rightExpression)) {
|
243
328
|
// Look for <string literal> in y where y is a union that contains
|
244
329
|
// one or more TypedDicts.
|
245
|
-
const
|
330
|
+
const leftTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression);
|
331
|
+
const leftType = leftTypeResult.type;
|
246
332
|
if ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isBuiltIn(leftType, 'str') && (0, typeUtils_1.isLiteralType)(leftType)) {
|
247
333
|
const adjIsPositiveTest = testExpression.operator === 41 /* In */ ? isPositiveTest : !isPositiveTest;
|
248
334
|
return (type) => {
|
249
|
-
return
|
335
|
+
return {
|
336
|
+
type: narrowTypeForTypedDictKey(evaluator, type, types_1.ClassType.cloneAsInstantiable(leftType), adjIsPositiveTest),
|
337
|
+
isIncomplete: !!leftTypeResult.isIncomplete,
|
338
|
+
};
|
250
339
|
};
|
251
340
|
}
|
252
341
|
}
|
@@ -261,24 +350,43 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
261
350
|
const arg0Expr = testExpression.arguments[0].valueExpression;
|
262
351
|
const arg1Expr = testExpression.arguments[1].valueExpression;
|
263
352
|
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
264
|
-
const
|
353
|
+
const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
|
354
|
+
const callType = callTypeResult.type;
|
265
355
|
if ((0, types_1.isFunction)(callType) &&
|
266
356
|
(callType.details.builtInName === 'isinstance' || callType.details.builtInName === 'issubclass')) {
|
267
357
|
const isInstanceCheck = callType.details.builtInName === 'isinstance';
|
268
|
-
const
|
269
|
-
32 /*
|
270
|
-
|
358
|
+
const arg1TypeResult = evaluator.getTypeOfExpression(arg1Expr, 8 /* EvaluateStringLiteralAsType */ |
|
359
|
+
32 /* DisallowParamSpec */ |
|
360
|
+
64 /* DisallowTypeVarTuple */);
|
361
|
+
const arg1Type = arg1TypeResult.type;
|
271
362
|
const classTypeList = getIsInstanceClassTypes(arg1Type);
|
363
|
+
const isIncomplete = !!callTypeResult.isIncomplete || !!arg1TypeResult.isIncomplete;
|
272
364
|
if (classTypeList) {
|
273
365
|
return (type) => {
|
274
366
|
const narrowedType = narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck, isPositiveTest,
|
275
367
|
/* allowIntersections */ false, testExpression);
|
276
368
|
if (!(0, types_1.isNever)(narrowedType)) {
|
277
|
-
return
|
369
|
+
return {
|
370
|
+
type: narrowedType,
|
371
|
+
isIncomplete,
|
372
|
+
};
|
278
373
|
}
|
279
374
|
// Try again with intersection types allowed.
|
280
|
-
return
|
281
|
-
|
375
|
+
return {
|
376
|
+
type: narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck, isPositiveTest,
|
377
|
+
/* allowIntersections */ true, testExpression),
|
378
|
+
isIncomplete,
|
379
|
+
};
|
380
|
+
};
|
381
|
+
}
|
382
|
+
else if (isIncomplete) {
|
383
|
+
// If the type is incomplete, it may include unknowns, which will result
|
384
|
+
// in classTypeList being undefined.
|
385
|
+
return (type) => {
|
386
|
+
return {
|
387
|
+
type,
|
388
|
+
isIncomplete: true,
|
389
|
+
};
|
282
390
|
};
|
283
391
|
}
|
284
392
|
}
|
@@ -288,7 +396,8 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
288
396
|
if (testExpression.arguments.length === 1) {
|
289
397
|
const arg0Expr = testExpression.arguments[0].valueExpression;
|
290
398
|
if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
|
291
|
-
const
|
399
|
+
const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
|
400
|
+
const callType = callTypeResult.type;
|
292
401
|
if ((0, types_1.isFunction)(callType) && callType.details.builtInName === 'callable') {
|
293
402
|
return (type) => {
|
294
403
|
let narrowedType = narrowTypeForCallable(evaluator, type, isPositiveTest, testExpression,
|
@@ -298,7 +407,7 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
298
407
|
narrowedType = narrowTypeForCallable(evaluator, type, isPositiveTest, testExpression,
|
299
408
|
/* allowIntersections */ true);
|
300
409
|
}
|
301
|
-
return narrowedType;
|
410
|
+
return { type: narrowedType, isIncomplete: !!callTypeResult.isIncomplete };
|
302
411
|
};
|
303
412
|
}
|
304
413
|
}
|
@@ -306,10 +415,14 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
306
415
|
// Look for "bool(X)"
|
307
416
|
if (testExpression.arguments.length === 1 && !testExpression.arguments[0].name) {
|
308
417
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression.arguments[0].valueExpression)) {
|
309
|
-
const
|
418
|
+
const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
|
419
|
+
const callType = callTypeResult.type;
|
310
420
|
if ((0, types_1.isInstantiableClass)(callType) && types_1.ClassType.isBuiltIn(callType, 'bool')) {
|
311
421
|
return (type) => {
|
312
|
-
return
|
422
|
+
return {
|
423
|
+
type: narrowTypeForTruthiness(evaluator, type, isPositiveTest),
|
424
|
+
isIncomplete: !!callTypeResult.isIncomplete,
|
425
|
+
};
|
313
426
|
};
|
314
427
|
}
|
315
428
|
}
|
@@ -325,7 +438,8 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
325
438
|
(0, types_1.isClassInstance)(type.details.declaredReturnType) &&
|
326
439
|
types_1.ClassType.isBuiltIn(type.details.declaredReturnType, ['TypeGuard', 'StrictTypeGuard']));
|
327
440
|
};
|
328
|
-
const
|
441
|
+
const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
|
442
|
+
const callType = callTypeResult.type;
|
329
443
|
if ((0, types_1.isFunction)(callType) && isFunctionReturnTypeGuard(callType)) {
|
330
444
|
isPossiblyTypeGuard = true;
|
331
445
|
}
|
@@ -335,14 +449,19 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
335
449
|
}
|
336
450
|
if (isPossiblyTypeGuard) {
|
337
451
|
// Evaluate the type guard call expression.
|
338
|
-
const
|
452
|
+
const functionReturnTypeResult = evaluator.getTypeOfExpression(testExpression);
|
453
|
+
const functionReturnType = functionReturnTypeResult.type;
|
339
454
|
if ((0, types_1.isClassInstance)(functionReturnType) &&
|
340
455
|
types_1.ClassType.isBuiltIn(functionReturnType, 'bool') &&
|
341
456
|
functionReturnType.typeGuardType) {
|
342
457
|
const isStrictTypeGuard = !!functionReturnType.isStrictTypeGuard;
|
343
458
|
const typeGuardType = functionReturnType.typeGuardType;
|
459
|
+
const isIncomplete = !!callTypeResult.isIncomplete || !!functionReturnTypeResult.isIncomplete;
|
344
460
|
return (type) => {
|
345
|
-
return
|
461
|
+
return {
|
462
|
+
type: narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPositiveTest, isStrictTypeGuard),
|
463
|
+
isIncomplete,
|
464
|
+
};
|
346
465
|
};
|
347
466
|
}
|
348
467
|
}
|
@@ -351,7 +470,10 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
|
|
351
470
|
}
|
352
471
|
if (ParseTreeUtils.isMatchingExpression(reference, testExpression)) {
|
353
472
|
return (type) => {
|
354
|
-
return
|
473
|
+
return {
|
474
|
+
type: narrowTypeForTruthiness(evaluator, type, isPositiveTest),
|
475
|
+
isIncomplete: false,
|
476
|
+
};
|
355
477
|
};
|
356
478
|
}
|
357
479
|
// Is this a reference to an aliased conditional expression (a local variable
|
@@ -487,6 +609,7 @@ function narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPos
|
|
487
609
|
// Narrow the type based on whether the subtype can be true or false.
|
488
610
|
function narrowTypeForTruthiness(evaluator, type, isPositiveTest) {
|
489
611
|
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
612
|
+
subtype = evaluator.makeTopLevelTypeVarsConcrete(subtype);
|
490
613
|
if (isPositiveTest) {
|
491
614
|
if (evaluator.canBeTruthy(subtype)) {
|
492
615
|
return evaluator.removeFalsinessFromType(subtype);
|
@@ -557,6 +680,38 @@ function narrowTypeForIsNone(evaluator, type, isPositiveTest) {
|
|
557
680
|
return undefined;
|
558
681
|
});
|
559
682
|
}
|
683
|
+
// Handle type narrowing for expressions of the form "x is ..." and "x is not ...".
|
684
|
+
function narrowTypeForIsEllipsis(evaluator, type, isPositiveTest) {
|
685
|
+
const expandedType = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
686
|
+
return (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
|
687
|
+
});
|
688
|
+
return evaluator.mapSubtypesExpandTypeVars(expandedType,
|
689
|
+
/* conditionFilter */ undefined, (subtype, unexpandedSubtype) => {
|
690
|
+
if ((0, types_1.isAnyOrUnknown)(subtype)) {
|
691
|
+
// We need to assume that "Any" is always both None and not None,
|
692
|
+
// so it matches regardless of whether the test is positive or negative.
|
693
|
+
return subtype;
|
694
|
+
}
|
695
|
+
// If this is a TypeVar that isn't constrained, use the unexpanded
|
696
|
+
// TypeVar. For all other cases (including constrained TypeVars),
|
697
|
+
// use the expanded subtype.
|
698
|
+
const adjustedSubtype = (0, types_1.isTypeVar)(unexpandedSubtype) && unexpandedSubtype.details.constraints.length === 0
|
699
|
+
? unexpandedSubtype
|
700
|
+
: subtype;
|
701
|
+
// See if it's a match for object.
|
702
|
+
if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'object')) {
|
703
|
+
return isPositiveTest
|
704
|
+
? (0, typeUtils_1.addConditionToType)(types_1.NoneType.createInstance(), subtype.condition)
|
705
|
+
: adjustedSubtype;
|
706
|
+
}
|
707
|
+
const isEllipsis = (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'ellipsis');
|
708
|
+
// See if it's a match for "...".
|
709
|
+
if (isEllipsis === isPositiveTest) {
|
710
|
+
return subtype;
|
711
|
+
}
|
712
|
+
return undefined;
|
713
|
+
});
|
714
|
+
}
|
560
715
|
// The "isinstance" and "issubclass" calls support two forms - a simple form
|
561
716
|
// that accepts a single class, and a more complex form that accepts a tuple
|
562
717
|
// of classes (including arbitrarily-nested tuples). This method determines
|
@@ -881,7 +1036,12 @@ function narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck
|
|
881
1036
|
}
|
882
1037
|
if (isInstanceCheck) {
|
883
1038
|
if ((0, types_1.isNoneInstance)(subtype)) {
|
884
|
-
const containsNoneType = classTypeList.some((t) =>
|
1039
|
+
const containsNoneType = classTypeList.some((t) => {
|
1040
|
+
if ((0, types_1.isNoneTypeClass)(t)) {
|
1041
|
+
return true;
|
1042
|
+
}
|
1043
|
+
return (0, types_1.isInstantiableClass)(t) && types_1.ClassType.isBuiltIn(t, 'NoneType');
|
1044
|
+
});
|
885
1045
|
if (isPositiveTest) {
|
886
1046
|
return containsNoneType ? subtype : undefined;
|
887
1047
|
}
|