@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.
Files changed (145) hide show
  1. package/dist/analyzer/analyzerFileInfo.js +14 -1
  2. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  3. package/dist/analyzer/backgroundAnalysisProgram.d.ts +3 -3
  4. package/dist/analyzer/backgroundAnalysisProgram.js +4 -4
  5. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  6. package/dist/analyzer/checker.d.ts +1 -1
  7. package/dist/analyzer/checker.js +145 -53
  8. package/dist/analyzer/checker.js.map +1 -1
  9. package/dist/analyzer/codeFlowEngine.js +26 -11
  10. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  11. package/dist/analyzer/constraintSolver.js +4 -2
  12. package/dist/analyzer/constraintSolver.js.map +1 -1
  13. package/dist/analyzer/dataClasses.js +6 -1
  14. package/dist/analyzer/dataClasses.js.map +1 -1
  15. package/dist/analyzer/importResolver.d.ts +2 -1
  16. package/dist/analyzer/importResolver.js +18 -3
  17. package/dist/analyzer/importResolver.js.map +1 -1
  18. package/dist/analyzer/patternMatching.js +2 -2
  19. package/dist/analyzer/patternMatching.js.map +1 -1
  20. package/dist/analyzer/program.d.ts +1 -0
  21. package/dist/analyzer/program.js +54 -32
  22. package/dist/analyzer/program.js.map +1 -1
  23. package/dist/analyzer/regions.js +14 -5
  24. package/dist/analyzer/regions.js.map +1 -1
  25. package/dist/analyzer/service.d.ts +3 -2
  26. package/dist/analyzer/service.js +14 -12
  27. package/dist/analyzer/service.js.map +1 -1
  28. package/dist/analyzer/sourceFile.d.ts +4 -3
  29. package/dist/analyzer/sourceFile.js +4 -4
  30. package/dist/analyzer/sourceFile.js.map +1 -1
  31. package/dist/analyzer/sourceMapper.d.ts +2 -2
  32. package/dist/analyzer/sourceMapper.js +14 -5
  33. package/dist/analyzer/sourceMapper.js.map +1 -1
  34. package/dist/analyzer/typeCacheUtils.d.ts +0 -1
  35. package/dist/analyzer/typeCacheUtils.js +3 -3
  36. package/dist/analyzer/typeCacheUtils.js.map +1 -1
  37. package/dist/analyzer/typeDocStringUtils.d.ts +2 -1
  38. package/dist/analyzer/typeDocStringUtils.js +18 -7
  39. package/dist/analyzer/typeDocStringUtils.js.map +1 -1
  40. package/dist/analyzer/typeEvaluator.js +494 -423
  41. package/dist/analyzer/typeEvaluator.js.map +1 -1
  42. package/dist/analyzer/typeEvaluatorTypes.d.ts +20 -13
  43. package/dist/analyzer/typeEvaluatorTypes.js +15 -15
  44. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  45. package/dist/analyzer/typeGuards.d.ts +5 -1
  46. package/dist/analyzer/typeGuards.js +204 -44
  47. package/dist/analyzer/typeGuards.js.map +1 -1
  48. package/dist/analyzer/typeUtils.d.ts +8 -0
  49. package/dist/analyzer/typeUtils.js +15 -4
  50. package/dist/analyzer/typeUtils.js.map +1 -1
  51. package/dist/analyzer/types.d.ts +3 -0
  52. package/dist/analyzer/types.js +10 -2
  53. package/dist/analyzer/types.js.map +1 -1
  54. package/dist/backgroundAnalysisBase.d.ts +4 -1
  55. package/dist/backgroundAnalysisBase.js +1 -1
  56. package/dist/backgroundAnalysisBase.js.map +1 -1
  57. package/dist/backgroundThreadBase.d.ts +5 -2
  58. package/dist/backgroundThreadBase.js.map +1 -1
  59. package/dist/commands/createTypeStub.js +3 -0
  60. package/dist/commands/createTypeStub.js.map +1 -1
  61. package/dist/commands/quickActionCommand.js +1 -1
  62. package/dist/commands/quickActionCommand.js.map +1 -1
  63. package/dist/common/collectionUtils.d.ts +1 -0
  64. package/dist/common/collectionUtils.js +9 -1
  65. package/dist/common/collectionUtils.js.map +1 -1
  66. package/dist/common/configOptions.d.ts +1 -0
  67. package/dist/common/configOptions.js +4 -0
  68. package/dist/common/configOptions.js.map +1 -1
  69. package/dist/common/diagnosticRules.d.ts +1 -0
  70. package/dist/common/diagnosticRules.js +1 -0
  71. package/dist/common/diagnosticRules.js.map +1 -1
  72. package/dist/common/fileSystem.d.ts +1 -0
  73. package/dist/common/fileSystem.js.map +1 -1
  74. package/dist/common/textEditUtils.d.ts +3 -2
  75. package/dist/common/textEditUtils.js +11 -10
  76. package/dist/common/textEditUtils.js.map +1 -1
  77. package/dist/languageServerBase.d.ts +1 -1
  78. package/dist/languageServerBase.js +2 -2
  79. package/dist/languageServerBase.js.map +1 -1
  80. package/dist/languageService/completionProvider.d.ts +3 -0
  81. package/dist/languageService/completionProvider.js +212 -159
  82. package/dist/languageService/completionProvider.js.map +1 -1
  83. package/dist/languageService/documentSymbolCollector.d.ts +12 -4
  84. package/dist/languageService/documentSymbolCollector.js +103 -22
  85. package/dist/languageService/documentSymbolCollector.js.map +1 -1
  86. package/dist/languageService/documentSymbolProvider.js +6 -0
  87. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  88. package/dist/languageService/hoverProvider.d.ts +0 -1
  89. package/dist/languageService/hoverProvider.js +7 -20
  90. package/dist/languageService/hoverProvider.js.map +1 -1
  91. package/dist/languageService/indentationUtils.d.ts +1 -1
  92. package/dist/languageService/indentationUtils.js +74 -29
  93. package/dist/languageService/indentationUtils.js.map +1 -1
  94. package/dist/languageService/referencesProvider.d.ts +5 -4
  95. package/dist/languageService/referencesProvider.js +15 -10
  96. package/dist/languageService/referencesProvider.js.map +1 -1
  97. package/dist/languageService/renameModuleProvider.js +11 -11
  98. package/dist/languageService/renameModuleProvider.js.map +1 -1
  99. package/dist/languageService/tooltipUtils.d.ts +5 -1
  100. package/dist/languageService/tooltipUtils.js +28 -4
  101. package/dist/languageService/tooltipUtils.js.map +1 -1
  102. package/dist/localization/localize.d.ts +3 -0
  103. package/dist/localization/localize.js +3 -0
  104. package/dist/localization/localize.js.map +1 -1
  105. package/dist/localization/package.nls.en-us.json +3 -0
  106. package/dist/parser/tokenizer.js +6 -2
  107. package/dist/parser/tokenizer.js.map +1 -1
  108. package/dist/tests/checker.test.js +16 -0
  109. package/dist/tests/checker.test.js.map +1 -1
  110. package/dist/tests/completions.test.d.ts +1 -0
  111. package/dist/tests/completions.test.js +331 -0
  112. package/dist/tests/completions.test.js.map +1 -0
  113. package/dist/tests/documentSymbolCollector.test.js +86 -5
  114. package/dist/tests/documentSymbolCollector.test.js.map +1 -1
  115. package/dist/tests/filesystem.test.js +11 -0
  116. package/dist/tests/filesystem.test.js.map +1 -1
  117. package/dist/tests/fourslash/rename.init.fourslash.d.ts +1 -0
  118. package/dist/tests/fourslash/rename.init.fourslash.js +23 -0
  119. package/dist/tests/fourslash/rename.init.fourslash.js.map +1 -0
  120. package/dist/tests/harness/fourslash/testState.d.ts +2 -2
  121. package/dist/tests/harness/fourslash/testState.js +10 -7
  122. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  123. package/dist/tests/harness/vfs/filesystem.d.ts +2 -2
  124. package/dist/tests/harness/vfs/filesystem.js +5 -1
  125. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  126. package/dist/tests/hoverProvider.test.d.ts +1 -0
  127. package/dist/tests/hoverProvider.test.js +247 -0
  128. package/dist/tests/hoverProvider.test.js.map +1 -0
  129. package/dist/tests/indentationUtils.ptvs.test.js +13 -13
  130. package/dist/tests/indentationUtils.ptvs.test.js.map +1 -1
  131. package/dist/tests/indentationUtils.test.js +68 -10
  132. package/dist/tests/indentationUtils.test.js.map +1 -1
  133. package/dist/tests/typeEvaluator1.test.js +24 -0
  134. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  135. package/dist/tests/typeEvaluator2.test.js +5 -1
  136. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  137. package/dist/tests/typeEvaluator3.test.js +10 -2
  138. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  139. package/dist/tests/typeEvaluator4.test.js +4 -0
  140. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  141. package/dist/tests/typeEvaluator5.test.js +6 -0
  142. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  143. package/dist/workspaceMap.js +1 -3
  144. package/dist/workspaceMap.js.map +1 -1
  145. 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 narrowTupleTypeForIsNone(evaluator, type, adjIsPositiveTest, indexValue);
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 classType = evaluator.makeTopLevelTypeVarsConcrete(evaluator.getTypeOfExpression(testExpression.rightExpression).type);
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 narrowTypeForTypeIs(evaluator, type, classType, adjIsPositiveTest);
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 rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
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 narrowTypeForLiteralComparison(evaluator, type, rightType, adjIsPositiveTest,
122
- /* isIsOperator */ true);
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 rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
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 narrowTypeForLiteralComparison(evaluator, type, rightType, adjIsPositiveTest,
135
- /* isIsOperator */ false);
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 leftType = evaluator.getTypeOfExpression(testExpression.leftExpression).type;
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 narrowTypeForLiteralComparison(evaluator, type, leftType, adjIsPositiveTest,
145
- /* isIsOperator */ false);
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 indexType = evaluator.getTypeOfExpression(testExpression.leftExpression.items[0].valueExpression).type;
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 narrowTypeForDiscriminatedDictEntryComparison(evaluator, type, indexType, rightType, adjIsPositiveTest);
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 rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
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 narrowTypeForDiscriminatedTupleComparison(evaluator, type, indexType, rightType, adjIsPositiveTest);
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 callType = evaluator.getTypeOfExpression(testExpression.leftExpression.leftExpression, 2 /* DoNotSpecialize */).type;
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 narrowTypeForTupleLength(evaluator, type, tupleLength, adjIsPositiveTest);
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 rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
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 narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest);
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 rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
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 narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest);
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 narrowTypeForDiscriminatedFieldNoneComparison(evaluator, type, memberName.value, adjIsPositiveTest);
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 rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
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 narrowTypeForContainerType(evaluator, type, rightType, adjIsPositiveTest);
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 leftType = evaluator.getTypeOfExpression(testExpression.leftExpression).type;
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 narrowTypeForTypedDictKey(evaluator, type, types_1.ClassType.cloneAsInstantiable(leftType), adjIsPositiveTest);
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 callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
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 arg1Type = evaluator.getTypeOfExpression(arg1Expr, 8 /* EvaluateStringLiteralAsType */ |
269
- 32 /* ParamSpecDisallowed */ |
270
- 128 /* TypeVarTupleDisallowed */).type;
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 narrowedType;
369
+ return {
370
+ type: narrowedType,
371
+ isIncomplete,
372
+ };
278
373
  }
279
374
  // Try again with intersection types allowed.
280
- return narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck, isPositiveTest,
281
- /* allowIntersections */ true, testExpression);
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 callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
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 callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
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 narrowTypeForTruthiness(evaluator, type, isPositiveTest);
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 callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
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 functionReturnType = evaluator.getTypeOfExpression(testExpression).type;
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 narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPositiveTest, isStrictTypeGuard);
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 narrowTypeForTruthiness(evaluator, type, isPositiveTest);
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) => (0, types_1.isNoneTypeClass)(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
  }