@zzzen/pyright-internal 1.2.0-dev.20221225 → 1.2.0-dev.20230108

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 (104) hide show
  1. package/dist/analyzer/binder.js +5 -3
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.js +17 -11
  4. package/dist/analyzer/checker.js.map +1 -1
  5. package/dist/analyzer/codeFlowEngine.d.ts +16 -1
  6. package/dist/analyzer/codeFlowEngine.js +36 -13
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolver.js +30 -31
  9. package/dist/analyzer/constraintSolver.js.map +1 -1
  10. package/dist/analyzer/importResolver.d.ts +2 -1
  11. package/dist/analyzer/importResolver.js +18 -3
  12. package/dist/analyzer/importResolver.js.map +1 -1
  13. package/dist/analyzer/patternMatching.js +5 -4
  14. package/dist/analyzer/patternMatching.js.map +1 -1
  15. package/dist/analyzer/program.d.ts +1 -0
  16. package/dist/analyzer/program.js +52 -25
  17. package/dist/analyzer/program.js.map +1 -1
  18. package/dist/analyzer/regions.js +14 -5
  19. package/dist/analyzer/regions.js.map +1 -1
  20. package/dist/analyzer/sourceFile.d.ts +1 -1
  21. package/dist/analyzer/sourceFile.js +1 -0
  22. package/dist/analyzer/sourceFile.js.map +1 -1
  23. package/dist/analyzer/sourceMapper.d.ts +2 -2
  24. package/dist/analyzer/sourceMapper.js +14 -5
  25. package/dist/analyzer/sourceMapper.js.map +1 -1
  26. package/dist/analyzer/typeCacheUtils.d.ts +26 -0
  27. package/dist/analyzer/{typeCache.js → typeCacheUtils.js} +9 -19
  28. package/dist/analyzer/typeCacheUtils.js.map +1 -0
  29. package/dist/analyzer/typeDocStringUtils.d.ts +2 -1
  30. package/dist/analyzer/typeDocStringUtils.js +18 -7
  31. package/dist/analyzer/typeDocStringUtils.js.map +1 -1
  32. package/dist/analyzer/typeEvaluator.js +551 -379
  33. package/dist/analyzer/typeEvaluator.js.map +1 -1
  34. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
  35. package/dist/analyzer/typeGuards.d.ts +5 -1
  36. package/dist/analyzer/typeGuards.js +181 -45
  37. package/dist/analyzer/typeGuards.js.map +1 -1
  38. package/dist/analyzer/typeUtils.d.ts +13 -3
  39. package/dist/analyzer/typeUtils.js +288 -135
  40. package/dist/analyzer/typeUtils.js.map +1 -1
  41. package/dist/analyzer/typeVarContext.d.ts +2 -10
  42. package/dist/analyzer/typeVarContext.js +12 -31
  43. package/dist/analyzer/typeVarContext.js.map +1 -1
  44. package/dist/analyzer/types.d.ts +4 -12
  45. package/dist/analyzer/types.js +22 -22
  46. package/dist/analyzer/types.js.map +1 -1
  47. package/dist/commands/dumpFileDebugInfoCommand.js +2 -2
  48. package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
  49. package/dist/commands/quickActionCommand.js +1 -1
  50. package/dist/commands/quickActionCommand.js.map +1 -1
  51. package/dist/common/collectionUtils.d.ts +1 -0
  52. package/dist/common/collectionUtils.js +9 -1
  53. package/dist/common/collectionUtils.js.map +1 -1
  54. package/dist/common/textEditUtils.d.ts +3 -2
  55. package/dist/common/textEditUtils.js +11 -10
  56. package/dist/common/textEditUtils.js.map +1 -1
  57. package/dist/languageServerBase.d.ts +1 -1
  58. package/dist/languageService/completionProvider.d.ts +3 -0
  59. package/dist/languageService/completionProvider.js +212 -159
  60. package/dist/languageService/completionProvider.js.map +1 -1
  61. package/dist/languageService/hoverProvider.d.ts +0 -1
  62. package/dist/languageService/hoverProvider.js +7 -20
  63. package/dist/languageService/hoverProvider.js.map +1 -1
  64. package/dist/languageService/indentationUtils.js +1 -1
  65. package/dist/languageService/indentationUtils.js.map +1 -1
  66. package/dist/languageService/tooltipUtils.d.ts +5 -1
  67. package/dist/languageService/tooltipUtils.js +28 -4
  68. package/dist/languageService/tooltipUtils.js.map +1 -1
  69. package/dist/localization/localize.d.ts +18 -3
  70. package/dist/localization/localize.js +7 -1
  71. package/dist/localization/localize.js.map +1 -1
  72. package/dist/localization/package.nls.en-us.json +7 -1
  73. package/dist/parser/parser.js +3 -1
  74. package/dist/parser/parser.js.map +1 -1
  75. package/dist/tests/completions.test.d.ts +1 -0
  76. package/dist/tests/completions.test.js +331 -0
  77. package/dist/tests/completions.test.js.map +1 -0
  78. package/dist/tests/filesystem.test.js +11 -0
  79. package/dist/tests/filesystem.test.js.map +1 -1
  80. package/dist/tests/harness/fourslash/testState.js +1 -1
  81. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  82. package/dist/tests/harness/vfs/filesystem.d.ts +2 -2
  83. package/dist/tests/harness/vfs/filesystem.js +5 -1
  84. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  85. package/dist/tests/hoverProvider.test.d.ts +1 -0
  86. package/dist/tests/hoverProvider.test.js +247 -0
  87. package/dist/tests/hoverProvider.test.js.map +1 -0
  88. package/dist/tests/indentationUtils.ptvs.test.js +1 -1
  89. package/dist/tests/indentationUtils.test.js +4 -4
  90. package/dist/tests/typeEvaluator1.test.js +16 -0
  91. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  92. package/dist/tests/typeEvaluator2.test.js +6 -2
  93. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  94. package/dist/tests/typeEvaluator3.test.js +9 -1
  95. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  96. package/dist/tests/typeEvaluator4.test.js +8 -0
  97. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  98. package/dist/tests/typeEvaluator5.test.js +54 -6
  99. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  100. package/dist/workspaceMap.js +1 -3
  101. package/dist/workspaceMap.js.map +1 -1
  102. package/package.json +6 -6
  103. package/dist/analyzer/typeCache.d.ts +0 -40
  104. package/dist/analyzer/typeCache.js.map +0 -1
@@ -163,6 +163,7 @@ export interface PrintTypeOptions {
163
163
  export interface TypeEvaluator {
164
164
  runWithCancellationToken<T>(token: CancellationToken, callback: () => T): T;
165
165
  getType: (node: ExpressionNode) => Type | undefined;
166
+ getTypeResult: (node: ExpressionNode) => TypeResult | undefined;
166
167
  getCachedType: (node: ExpressionNode) => Type | undefined;
167
168
  getTypeOfExpression: (node: ExpressionNode, flags?: EvaluatorFlags, expectedType?: Type) => TypeResult;
168
169
  getTypeOfAnnotation: (node: ExpressionNode, options?: AnnotationTypeOptions) => Type;
@@ -237,7 +238,7 @@ export interface TypeEvaluator {
237
238
  addUnusedCode: (node: ParseNode, textRange: TextRange) => void;
238
239
  addUnreachableCode: (node: ParseNode, textRange: TextRange) => void;
239
240
  addDeprecated: (message: string, node: ParseNode) => void;
240
- addDiagnostic: (diagLevel: DiagnosticLevel, rule: string, message: string, node: ParseNode) => Diagnostic | undefined;
241
+ addDiagnostic: (diagLevel: DiagnosticLevel, rule: string, message: string, node: ParseNode, range?: TextRange) => Diagnostic | undefined;
241
242
  addDiagnosticForTextRange: (fileInfo: AnalyzerFileInfo, diagLevel: DiagnosticLevel, rule: string, message: string, range: TextRange) => Diagnostic | undefined;
242
243
  printType: (type: Type, options?: PrintTypeOptions) => string;
243
244
  printFunctionParts: (type: FunctionType) => [string[], string];
@@ -1,7 +1,11 @@
1
1
  import { ExpressionNode } from '../parser/parseNodes';
2
2
  import { TypeEvaluator } from './typeEvaluatorTypes';
3
3
  import { ClassType, Type } from './types';
4
- export declare type TypeNarrowingCallback = (type: Type) => Type | undefined;
4
+ export interface TypeNarrowingResult {
5
+ type: Type;
6
+ isIncomplete: boolean;
7
+ }
8
+ export declare type TypeNarrowingCallback = (type: Type) => TypeNarrowingResult | undefined;
5
9
  export declare function getTypeNarrowingCallback(evaluator: TypeEvaluator, reference: ExpressionNode, testExpression: ExpressionNode, isPositiveTest: boolean, recursionCount?: number): TypeNarrowingCallback | undefined;
6
10
  export declare function isIsinstanceFilterSuperclass(evaluator: TypeEvaluator, varType: ClassType, filterType: Type, concreteFilterType: ClassType, isInstanceCheck: boolean): boolean;
7
11
  export declare function isIsinstanceFilterSubclass(evaluator: TypeEvaluator, varType: ClassType, filterType: Type, concreteFilterType: ClassType, isInstanceCheck: boolean): boolean;
@@ -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,13 +137,17 @@ 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
  }
@@ -128,21 +156,29 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
128
156
  // Look for X == <literal> or X != <literal>
129
157
  const adjIsPositiveTest = testExpression.operator === 12 /* Equals */ ? isPositiveTest : !isPositiveTest;
130
158
  if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
131
- const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
159
+ const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
160
+ const rightType = rightTypeResult.type;
132
161
  if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
133
162
  return (type) => {
134
- return narrowTypeForLiteralComparison(evaluator, type, rightType, adjIsPositiveTest,
135
- /* isIsOperator */ false);
163
+ return {
164
+ type: narrowTypeForLiteralComparison(evaluator, type, rightType, adjIsPositiveTest,
165
+ /* isIsOperator */ false),
166
+ isIncomplete: !!rightTypeResult.isIncomplete,
167
+ };
136
168
  };
137
169
  }
138
170
  }
139
171
  // Look for <literal> == X or <literal> != X
140
172
  if (ParseTreeUtils.isMatchingExpression(reference, testExpression.rightExpression)) {
141
- const leftType = evaluator.getTypeOfExpression(testExpression.leftExpression).type;
173
+ const leftTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression);
174
+ const leftType = leftTypeResult.type;
142
175
  if ((0, types_1.isClassInstance)(leftType) && leftType.literalValue !== undefined) {
143
176
  return (type) => {
144
- return narrowTypeForLiteralComparison(evaluator, type, leftType, adjIsPositiveTest,
145
- /* isIsOperator */ false);
177
+ return {
178
+ type: narrowTypeForLiteralComparison(evaluator, type, leftType, adjIsPositiveTest,
179
+ /* isIsOperator */ false),
180
+ isIncomplete: !!leftTypeResult.isIncomplete,
181
+ };
146
182
  };
147
183
  }
148
184
  }
@@ -152,21 +188,29 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
152
188
  !testExpression.leftExpression.trailingComma &&
153
189
  testExpression.leftExpression.items[0].argumentCategory === 0 /* Simple */ &&
154
190
  ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.baseExpression)) {
155
- const indexType = evaluator.getTypeOfExpression(testExpression.leftExpression.items[0].valueExpression).type;
191
+ const indexTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression.items[0].valueExpression);
192
+ const indexType = indexTypeResult.type;
156
193
  if ((0, types_1.isClassInstance)(indexType) && (0, typeUtils_1.isLiteralType)(indexType)) {
157
194
  if (types_1.ClassType.isBuiltIn(indexType, 'str')) {
158
195
  const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
159
196
  if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
160
197
  return (type) => {
161
- return narrowTypeForDiscriminatedDictEntryComparison(evaluator, type, indexType, rightType, adjIsPositiveTest);
198
+ return {
199
+ type: narrowTypeForDiscriminatedDictEntryComparison(evaluator, type, indexType, rightType, adjIsPositiveTest),
200
+ isIncomplete: !!indexTypeResult.isIncomplete,
201
+ };
162
202
  };
163
203
  }
164
204
  }
165
205
  else if (types_1.ClassType.isBuiltIn(indexType, 'int')) {
166
- const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
206
+ const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
207
+ const rightType = rightTypeResult.type;
167
208
  if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
168
209
  return (type) => {
169
- return narrowTypeForDiscriminatedTupleComparison(evaluator, type, indexType, rightType, adjIsPositiveTest);
210
+ return {
211
+ type: narrowTypeForDiscriminatedTupleComparison(evaluator, type, indexType, rightType, adjIsPositiveTest),
212
+ isIncomplete: !!rightTypeResult.isIncomplete,
213
+ };
170
214
  };
171
215
  }
172
216
  }
@@ -181,12 +225,16 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
181
225
  testExpression.rightExpression.isInteger) {
182
226
  const arg0Expr = testExpression.leftExpression.arguments[0].valueExpression;
183
227
  if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
184
- const callType = evaluator.getTypeOfExpression(testExpression.leftExpression.leftExpression, 2 /* DoNotSpecialize */).type;
228
+ const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression.leftExpression, 2 /* DoNotSpecialize */);
229
+ const callType = callTypeResult.type;
185
230
  if ((0, types_1.isFunction)(callType) && callType.details.fullName === 'builtins.len') {
186
231
  const tupleLength = testExpression.rightExpression.value;
187
232
  if (typeof tupleLength === 'number') {
188
233
  return (type) => {
189
- return narrowTypeForTupleLength(evaluator, type, tupleLength, adjIsPositiveTest);
234
+ return {
235
+ type: narrowTypeForTupleLength(evaluator, type, tupleLength, adjIsPositiveTest),
236
+ isIncomplete: !!callTypeResult.isIncomplete,
237
+ };
190
238
  };
191
239
  }
192
240
  }
@@ -196,11 +244,15 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
196
244
  if (equalsOrNotEqualsOperator &&
197
245
  testExpression.leftExpression.nodeType === 35 /* MemberAccess */ &&
198
246
  ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression)) {
199
- const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
247
+ const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
248
+ const rightType = rightTypeResult.type;
200
249
  const memberName = testExpression.leftExpression.memberName;
201
250
  if ((0, types_1.isClassInstance)(rightType) && rightType.literalValue !== undefined) {
202
251
  return (type) => {
203
- return narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest);
252
+ return {
253
+ type: narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest),
254
+ isIncomplete: !!rightTypeResult.isIncomplete,
255
+ };
204
256
  };
205
257
  }
206
258
  }
@@ -208,13 +260,17 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
208
260
  // an enum or bool literal
209
261
  if (testExpression.leftExpression.nodeType === 35 /* MemberAccess */ &&
210
262
  ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression.leftExpression)) {
211
- const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
263
+ const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
264
+ const rightType = rightTypeResult.type;
212
265
  const memberName = testExpression.leftExpression.memberName;
213
266
  if ((0, types_1.isClassInstance)(rightType) &&
214
267
  (types_1.ClassType.isEnumClass(rightType) || types_1.ClassType.isBuiltIn(rightType, 'bool')) &&
215
268
  rightType.literalValue !== undefined) {
216
269
  return (type) => {
217
- return narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest);
270
+ return {
271
+ type: narrowTypeForDiscriminatedLiteralFieldComparison(evaluator, type, memberName.value, rightType, adjIsPositiveTest),
272
+ isIncomplete: !!rightTypeResult.isIncomplete,
273
+ };
218
274
  };
219
275
  }
220
276
  }
@@ -226,27 +282,38 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
226
282
  testExpression.rightExpression.constType === 26 /* None */) {
227
283
  const memberName = testExpression.leftExpression.memberName;
228
284
  return (type) => {
229
- return narrowTypeForDiscriminatedFieldNoneComparison(evaluator, type, memberName.value, adjIsPositiveTest);
285
+ return {
286
+ type: narrowTypeForDiscriminatedFieldNoneComparison(evaluator, type, memberName.value, adjIsPositiveTest),
287
+ isIncomplete: false,
288
+ };
230
289
  };
231
290
  }
232
291
  }
233
292
  if (testExpression.operator === 41 /* In */ || testExpression.operator === 42 /* NotIn */) {
234
293
  // Look for "x in y" or "x not in y" where y is one of several built-in types.
235
294
  if (ParseTreeUtils.isMatchingExpression(reference, testExpression.leftExpression)) {
236
- const rightType = evaluator.getTypeOfExpression(testExpression.rightExpression).type;
295
+ const rightTypeResult = evaluator.getTypeOfExpression(testExpression.rightExpression);
296
+ const rightType = rightTypeResult.type;
237
297
  const adjIsPositiveTest = testExpression.operator === 41 /* In */ ? isPositiveTest : !isPositiveTest;
238
298
  return (type) => {
239
- return narrowTypeForContainerType(evaluator, type, rightType, adjIsPositiveTest);
299
+ return {
300
+ type: narrowTypeForContainerType(evaluator, type, rightType, adjIsPositiveTest),
301
+ isIncomplete: !!rightTypeResult.isIncomplete,
302
+ };
240
303
  };
241
304
  }
242
305
  if (ParseTreeUtils.isMatchingExpression(reference, testExpression.rightExpression)) {
243
306
  // Look for <string literal> in y where y is a union that contains
244
307
  // one or more TypedDicts.
245
- const leftType = evaluator.getTypeOfExpression(testExpression.leftExpression).type;
308
+ const leftTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression);
309
+ const leftType = leftTypeResult.type;
246
310
  if ((0, types_1.isClassInstance)(leftType) && types_1.ClassType.isBuiltIn(leftType, 'str') && (0, typeUtils_1.isLiteralType)(leftType)) {
247
311
  const adjIsPositiveTest = testExpression.operator === 41 /* In */ ? isPositiveTest : !isPositiveTest;
248
312
  return (type) => {
249
- return narrowTypeForTypedDictKey(evaluator, type, types_1.ClassType.cloneAsInstantiable(leftType), adjIsPositiveTest);
313
+ return {
314
+ type: narrowTypeForTypedDictKey(evaluator, type, types_1.ClassType.cloneAsInstantiable(leftType), adjIsPositiveTest),
315
+ isIncomplete: !!leftTypeResult.isIncomplete,
316
+ };
250
317
  };
251
318
  }
252
319
  }
@@ -261,24 +328,43 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
261
328
  const arg0Expr = testExpression.arguments[0].valueExpression;
262
329
  const arg1Expr = testExpression.arguments[1].valueExpression;
263
330
  if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
264
- const callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
331
+ const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
332
+ const callType = callTypeResult.type;
265
333
  if ((0, types_1.isFunction)(callType) &&
266
334
  (callType.details.builtInName === 'isinstance' || callType.details.builtInName === 'issubclass')) {
267
335
  const isInstanceCheck = callType.details.builtInName === 'isinstance';
268
- const arg1Type = evaluator.getTypeOfExpression(arg1Expr, 8 /* EvaluateStringLiteralAsType */ |
336
+ const arg1TypeResult = evaluator.getTypeOfExpression(arg1Expr, 8 /* EvaluateStringLiteralAsType */ |
269
337
  32 /* ParamSpecDisallowed */ |
270
- 128 /* TypeVarTupleDisallowed */).type;
338
+ 128 /* TypeVarTupleDisallowed */);
339
+ const arg1Type = arg1TypeResult.type;
271
340
  const classTypeList = getIsInstanceClassTypes(arg1Type);
341
+ const isIncomplete = !!callTypeResult.isIncomplete || !!arg1TypeResult.isIncomplete;
272
342
  if (classTypeList) {
273
343
  return (type) => {
274
344
  const narrowedType = narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck, isPositiveTest,
275
345
  /* allowIntersections */ false, testExpression);
276
346
  if (!(0, types_1.isNever)(narrowedType)) {
277
- return narrowedType;
347
+ return {
348
+ type: narrowedType,
349
+ isIncomplete,
350
+ };
278
351
  }
279
352
  // Try again with intersection types allowed.
280
- return narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck, isPositiveTest,
281
- /* allowIntersections */ true, testExpression);
353
+ return {
354
+ type: narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck, isPositiveTest,
355
+ /* allowIntersections */ true, testExpression),
356
+ isIncomplete,
357
+ };
358
+ };
359
+ }
360
+ else if (isIncomplete) {
361
+ // If the type is incomplete, it may include unknowns, which will result
362
+ // in classTypeList being undefined.
363
+ return (type) => {
364
+ return {
365
+ type,
366
+ isIncomplete: true,
367
+ };
282
368
  };
283
369
  }
284
370
  }
@@ -288,7 +374,8 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
288
374
  if (testExpression.arguments.length === 1) {
289
375
  const arg0Expr = testExpression.arguments[0].valueExpression;
290
376
  if (ParseTreeUtils.isMatchingExpression(reference, arg0Expr)) {
291
- const callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
377
+ const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
378
+ const callType = callTypeResult.type;
292
379
  if ((0, types_1.isFunction)(callType) && callType.details.builtInName === 'callable') {
293
380
  return (type) => {
294
381
  let narrowedType = narrowTypeForCallable(evaluator, type, isPositiveTest, testExpression,
@@ -298,7 +385,7 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
298
385
  narrowedType = narrowTypeForCallable(evaluator, type, isPositiveTest, testExpression,
299
386
  /* allowIntersections */ true);
300
387
  }
301
- return narrowedType;
388
+ return { type: narrowedType, isIncomplete: !!callTypeResult.isIncomplete };
302
389
  };
303
390
  }
304
391
  }
@@ -306,10 +393,14 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
306
393
  // Look for "bool(X)"
307
394
  if (testExpression.arguments.length === 1 && !testExpression.arguments[0].name) {
308
395
  if (ParseTreeUtils.isMatchingExpression(reference, testExpression.arguments[0].valueExpression)) {
309
- const callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
396
+ const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
397
+ const callType = callTypeResult.type;
310
398
  if ((0, types_1.isInstantiableClass)(callType) && types_1.ClassType.isBuiltIn(callType, 'bool')) {
311
399
  return (type) => {
312
- return narrowTypeForTruthiness(evaluator, type, isPositiveTest);
400
+ return {
401
+ type: narrowTypeForTruthiness(evaluator, type, isPositiveTest),
402
+ isIncomplete: !!callTypeResult.isIncomplete,
403
+ };
313
404
  };
314
405
  }
315
406
  }
@@ -325,7 +416,8 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
325
416
  (0, types_1.isClassInstance)(type.details.declaredReturnType) &&
326
417
  types_1.ClassType.isBuiltIn(type.details.declaredReturnType, ['TypeGuard', 'StrictTypeGuard']));
327
418
  };
328
- const callType = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */).type;
419
+ const callTypeResult = evaluator.getTypeOfExpression(testExpression.leftExpression, 2 /* DoNotSpecialize */);
420
+ const callType = callTypeResult.type;
329
421
  if ((0, types_1.isFunction)(callType) && isFunctionReturnTypeGuard(callType)) {
330
422
  isPossiblyTypeGuard = true;
331
423
  }
@@ -335,14 +427,19 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
335
427
  }
336
428
  if (isPossiblyTypeGuard) {
337
429
  // Evaluate the type guard call expression.
338
- const functionReturnType = evaluator.getTypeOfExpression(testExpression).type;
430
+ const functionReturnTypeResult = evaluator.getTypeOfExpression(testExpression);
431
+ const functionReturnType = functionReturnTypeResult.type;
339
432
  if ((0, types_1.isClassInstance)(functionReturnType) &&
340
433
  types_1.ClassType.isBuiltIn(functionReturnType, 'bool') &&
341
434
  functionReturnType.typeGuardType) {
342
435
  const isStrictTypeGuard = !!functionReturnType.isStrictTypeGuard;
343
436
  const typeGuardType = functionReturnType.typeGuardType;
437
+ const isIncomplete = !!callTypeResult.isIncomplete || !!functionReturnTypeResult.isIncomplete;
344
438
  return (type) => {
345
- return narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPositiveTest, isStrictTypeGuard);
439
+ return {
440
+ type: narrowTypeForUserDefinedTypeGuard(evaluator, type, typeGuardType, isPositiveTest, isStrictTypeGuard),
441
+ isIncomplete,
442
+ };
346
443
  };
347
444
  }
348
445
  }
@@ -351,7 +448,10 @@ function getTypeNarrowingCallback(evaluator, reference, testExpression, isPositi
351
448
  }
352
449
  if (ParseTreeUtils.isMatchingExpression(reference, testExpression)) {
353
450
  return (type) => {
354
- return narrowTypeForTruthiness(evaluator, type, isPositiveTest);
451
+ return {
452
+ type: narrowTypeForTruthiness(evaluator, type, isPositiveTest),
453
+ isIncomplete: false,
454
+ };
355
455
  };
356
456
  }
357
457
  // Is this a reference to an aliased conditional expression (a local variable
@@ -557,6 +657,38 @@ function narrowTypeForIsNone(evaluator, type, isPositiveTest) {
557
657
  return undefined;
558
658
  });
559
659
  }
660
+ // Handle type narrowing for expressions of the form "x is ..." and "x is not ...".
661
+ function narrowTypeForIsEllipsis(evaluator, type, isPositiveTest) {
662
+ const expandedType = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
663
+ return (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(subtype);
664
+ });
665
+ return evaluator.mapSubtypesExpandTypeVars(expandedType,
666
+ /* conditionFilter */ undefined, (subtype, unexpandedSubtype) => {
667
+ if ((0, types_1.isAnyOrUnknown)(subtype)) {
668
+ // We need to assume that "Any" is always both None and not None,
669
+ // so it matches regardless of whether the test is positive or negative.
670
+ return subtype;
671
+ }
672
+ // If this is a TypeVar that isn't constrained, use the unexpanded
673
+ // TypeVar. For all other cases (including constrained TypeVars),
674
+ // use the expanded subtype.
675
+ const adjustedSubtype = (0, types_1.isTypeVar)(unexpandedSubtype) && unexpandedSubtype.details.constraints.length === 0
676
+ ? unexpandedSubtype
677
+ : subtype;
678
+ // See if it's a match for object.
679
+ if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'object')) {
680
+ return isPositiveTest
681
+ ? (0, typeUtils_1.addConditionToType)(types_1.NoneType.createInstance(), subtype.condition)
682
+ : adjustedSubtype;
683
+ }
684
+ const isEllipsis = (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'ellipsis');
685
+ // See if it's a match for "...".
686
+ if (isEllipsis === isPositiveTest) {
687
+ return subtype;
688
+ }
689
+ return undefined;
690
+ });
691
+ }
560
692
  // The "isinstance" and "issubclass" calls support two forms - a simple form
561
693
  // that accepts a single class, and a more complex form that accepts a tuple
562
694
  // of classes (including arbitrarily-nested tuples). This method determines
@@ -700,8 +832,7 @@ function narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck
700
832
  /* isTypeArgumentExplicit */ false);
701
833
  if ((0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluator, unspecializedFilterType, varType, typeVarContext,
702
834
  /* liveTypeVarScopes */ undefined)) {
703
- specializedFilterType = (0, typeUtils_1.applySolvedTypeVars)(unspecializedFilterType, typeVarContext,
704
- /* unknownIfNotFound */ true);
835
+ specializedFilterType = (0, typeUtils_1.applySolvedTypeVars)(unspecializedFilterType, typeVarContext, { unknownIfNotFound: true });
705
836
  }
706
837
  }
707
838
  }
@@ -882,7 +1013,12 @@ function narrowTypeForIsInstance(evaluator, type, classTypeList, isInstanceCheck
882
1013
  }
883
1014
  if (isInstanceCheck) {
884
1015
  if ((0, types_1.isNoneInstance)(subtype)) {
885
- const containsNoneType = classTypeList.some((t) => (0, types_1.isNoneTypeClass)(t));
1016
+ const containsNoneType = classTypeList.some((t) => {
1017
+ if ((0, types_1.isNoneTypeClass)(t)) {
1018
+ return true;
1019
+ }
1020
+ return (0, types_1.isInstantiableClass)(t) && types_1.ClassType.isBuiltIn(t, 'NoneType');
1021
+ });
886
1022
  if (isPositiveTest) {
887
1023
  return containsNoneType ? subtype : undefined;
888
1024
  }