@zzzen/pyright-internal 1.2.0-dev.2022-07-02 → 1.2.0-dev.20220717

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 (166) hide show
  1. package/README.md +82 -1
  2. package/dist/analyzer/aliasDeclarationUtils.js +2 -2
  3. package/dist/analyzer/analyzerFileInfo.d.ts +2 -1
  4. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  5. package/dist/analyzer/analyzerNodeInfo.d.ts +4 -1
  6. package/dist/analyzer/analyzerNodeInfo.js +12 -1
  7. package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
  8. package/dist/analyzer/binder.d.ts +6 -1
  9. package/dist/analyzer/binder.js +148 -31
  10. package/dist/analyzer/binder.js.map +1 -1
  11. package/dist/analyzer/checker.d.ts +4 -1
  12. package/dist/analyzer/checker.js +176 -90
  13. package/dist/analyzer/checker.js.map +1 -1
  14. package/dist/analyzer/codeFlowEngine.d.ts +0 -1
  15. package/dist/analyzer/codeFlowEngine.js +196 -197
  16. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  17. package/dist/analyzer/codeFlowTypes.d.ts +1 -1
  18. package/dist/analyzer/codeFlowTypes.js.map +1 -1
  19. package/dist/analyzer/constraintSolver.js +9 -6
  20. package/dist/analyzer/constraintSolver.js.map +1 -1
  21. package/dist/analyzer/declaration.d.ts +18 -6
  22. package/dist/analyzer/declaration.js +19 -9
  23. package/dist/analyzer/declaration.js.map +1 -1
  24. package/dist/analyzer/declarationUtils.d.ts +1 -1
  25. package/dist/analyzer/declarationUtils.js +19 -16
  26. package/dist/analyzer/declarationUtils.js.map +1 -1
  27. package/dist/analyzer/functionTransform.js +2 -1
  28. package/dist/analyzer/functionTransform.js.map +1 -1
  29. package/dist/analyzer/importResolver.js +3 -2
  30. package/dist/analyzer/importResolver.js.map +1 -1
  31. package/dist/analyzer/packageTypeVerifier.js +6 -6
  32. package/dist/analyzer/parseTreeUtils.d.ts +6 -3
  33. package/dist/analyzer/parseTreeUtils.js +65 -21
  34. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  35. package/dist/analyzer/parseTreeWalker.d.ts +4 -1
  36. package/dist/analyzer/parseTreeWalker.js +19 -1
  37. package/dist/analyzer/parseTreeWalker.js.map +1 -1
  38. package/dist/analyzer/patternMatching.js +1 -1
  39. package/dist/analyzer/patternMatching.js.map +1 -1
  40. package/dist/analyzer/program.d.ts +2 -2
  41. package/dist/analyzer/program.js +1 -1
  42. package/dist/analyzer/program.js.map +1 -1
  43. package/dist/analyzer/properties.js +2 -0
  44. package/dist/analyzer/properties.js.map +1 -1
  45. package/dist/analyzer/protocols.d.ts +0 -1
  46. package/dist/analyzer/protocols.js +1 -63
  47. package/dist/analyzer/protocols.js.map +1 -1
  48. package/dist/analyzer/service.d.ts +3 -2
  49. package/dist/analyzer/service.js +4 -2
  50. package/dist/analyzer/service.js.map +1 -1
  51. package/dist/analyzer/sourceFile.d.ts +6 -1
  52. package/dist/analyzer/sourceFile.js +57 -14
  53. package/dist/analyzer/sourceFile.js.map +1 -1
  54. package/dist/analyzer/tracePrinter.js +8 -4
  55. package/dist/analyzer/tracePrinter.js.map +1 -1
  56. package/dist/analyzer/typeDocStringUtils.js +1 -1
  57. package/dist/analyzer/typeEvaluator.d.ts +1 -1
  58. package/dist/analyzer/typeEvaluator.js +839 -375
  59. package/dist/analyzer/typeEvaluator.js.map +1 -1
  60. package/dist/analyzer/typeEvaluatorTypes.d.ts +9 -7
  61. package/dist/analyzer/typeEvaluatorWithTracker.js +10 -7
  62. package/dist/analyzer/typeEvaluatorWithTracker.js.map +1 -1
  63. package/dist/analyzer/typeGuards.js +6 -1
  64. package/dist/analyzer/typeGuards.js.map +1 -1
  65. package/dist/analyzer/typePrinter.js +4 -1
  66. package/dist/analyzer/typePrinter.js.map +1 -1
  67. package/dist/analyzer/typeStubWriter.d.ts +4 -1
  68. package/dist/analyzer/typeStubWriter.js +36 -0
  69. package/dist/analyzer/typeStubWriter.js.map +1 -1
  70. package/dist/analyzer/typeUtils.d.ts +3 -2
  71. package/dist/analyzer/typeUtils.js +94 -13
  72. package/dist/analyzer/typeUtils.js.map +1 -1
  73. package/dist/analyzer/typedDicts.d.ts +1 -0
  74. package/dist/analyzer/typedDicts.js +25 -2
  75. package/dist/analyzer/typedDicts.js.map +1 -1
  76. package/dist/analyzer/types.d.ts +21 -5
  77. package/dist/analyzer/types.js +87 -11
  78. package/dist/analyzer/types.js.map +1 -1
  79. package/dist/common/diagnostic.d.ts +2 -1
  80. package/dist/common/diagnostic.js +2 -1
  81. package/dist/common/diagnostic.js.map +1 -1
  82. package/dist/common/diagnosticSink.d.ts +3 -0
  83. package/dist/common/diagnosticSink.js +15 -2
  84. package/dist/common/diagnosticSink.js.map +1 -1
  85. package/dist/languageServerBase.d.ts +5 -8
  86. package/dist/languageServerBase.js +30 -18
  87. package/dist/languageServerBase.js.map +1 -1
  88. package/dist/languageService/autoImporter.js +1 -1
  89. package/dist/languageService/callHierarchyProvider.js +9 -9
  90. package/dist/languageService/completionProvider.d.ts +15 -11
  91. package/dist/languageService/completionProvider.js +95 -18
  92. package/dist/languageService/completionProvider.js.map +1 -1
  93. package/dist/languageService/definitionProvider.js +3 -3
  94. package/dist/languageService/documentSymbolCollector.js +1 -1
  95. package/dist/languageService/documentSymbolProvider.js +10 -7
  96. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  97. package/dist/languageService/hoverProvider.js +19 -5
  98. package/dist/languageService/hoverProvider.js.map +1 -1
  99. package/dist/languageService/indentationUtils.js +3 -2
  100. package/dist/languageService/indentationUtils.js.map +1 -1
  101. package/dist/languageService/insertionPointUtils.d.ts +9 -0
  102. package/dist/languageService/insertionPointUtils.js +110 -0
  103. package/dist/languageService/insertionPointUtils.js.map +1 -0
  104. package/dist/languageService/referencesProvider.js +8 -5
  105. package/dist/languageService/referencesProvider.js.map +1 -1
  106. package/dist/languageService/signatureHelpProvider.js +4 -2
  107. package/dist/languageService/signatureHelpProvider.js.map +1 -1
  108. package/dist/languageService/tooltipUtils.js +2 -4
  109. package/dist/languageService/tooltipUtils.js.map +1 -1
  110. package/dist/localization/localize.d.ts +32 -0
  111. package/dist/localization/localize.js +18 -0
  112. package/dist/localization/localize.js.map +1 -1
  113. package/dist/localization/package.nls.en-us.json +20 -2
  114. package/dist/parser/parseNodes.d.ts +41 -5
  115. package/dist/parser/parseNodes.js +83 -4
  116. package/dist/parser/parseNodes.js.map +1 -1
  117. package/dist/parser/parser.d.ts +5 -1
  118. package/dist/parser/parser.js +140 -14
  119. package/dist/parser/parser.js.map +1 -1
  120. package/dist/parser/tokenizer.d.ts +2 -1
  121. package/dist/parser/tokenizer.js +7 -5
  122. package/dist/parser/tokenizer.js.map +1 -1
  123. package/dist/parser/tokenizerTypes.d.ts +5 -3
  124. package/dist/parser/tokenizerTypes.js +6 -4
  125. package/dist/parser/tokenizerTypes.js.map +1 -1
  126. package/dist/pyright.js +3 -1
  127. package/dist/pyright.js.map +1 -1
  128. package/dist/pyrightFileSystem.d.ts +1 -1
  129. package/dist/pyrightFileSystem.js +11 -1
  130. package/dist/pyrightFileSystem.js.map +1 -1
  131. package/dist/tests/chainedSourceFiles.test.js +4 -1
  132. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  133. package/dist/tests/fourslash/completions.commitChars.fourslash.d.ts +1 -0
  134. package/dist/tests/fourslash/completions.commitChars.fourslash.js +47 -0
  135. package/dist/tests/fourslash/completions.commitChars.fourslash.js.map +1 -0
  136. package/dist/tests/fourslash/completions.triggers.fourslash.d.ts +1 -0
  137. package/dist/tests/fourslash/completions.triggers.fourslash.js +29 -0
  138. package/dist/tests/fourslash/completions.triggers.fourslash.js.map +1 -0
  139. package/dist/tests/fourslash/fourslash.d.ts +1 -0
  140. package/dist/tests/fourslash/import.multipart.fourslash.d.ts +1 -0
  141. package/dist/tests/fourslash/import.multipart.fourslash.js +18 -0
  142. package/dist/tests/fourslash/import.multipart.fourslash.js.map +1 -0
  143. package/dist/tests/fourslash/signature.simple.fourslash.js +16 -0
  144. package/dist/tests/fourslash/signature.simple.fourslash.js.map +1 -1
  145. package/dist/tests/harness/fourslash/testState.js +11 -2
  146. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  147. package/dist/tests/insertionPointUtils.test.d.ts +1 -0
  148. package/dist/tests/insertionPointUtils.test.js +74 -0
  149. package/dist/tests/insertionPointUtils.test.js.map +1 -0
  150. package/dist/tests/pyrightFileSystem.test.js +28 -0
  151. package/dist/tests/pyrightFileSystem.test.js.map +1 -1
  152. package/dist/tests/testUtils.d.ts +2 -1
  153. package/dist/tests/testUtils.js +10 -6
  154. package/dist/tests/testUtils.js.map +1 -1
  155. package/dist/tests/typeEvaluator1.test.js +2 -2
  156. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  157. package/dist/tests/typeEvaluator2.test.js +12 -4
  158. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  159. package/dist/tests/typeEvaluator3.test.js +9 -1
  160. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  161. package/dist/tests/typeEvaluator4.test.js +18 -0
  162. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  163. package/dist/tests/typeEvaluator5.test.d.ts +1 -0
  164. package/dist/tests/typeEvaluator5.test.js +118 -0
  165. package/dist/tests/typeEvaluator5.test.js.map +1 -0
  166. package/package.json +3 -2
@@ -182,6 +182,9 @@ const maxReturnTypeInferenceArgumentCount = 6;
182
182
  // when its parameters are unannotated? We want to keep this
183
183
  // pretty low because this can be very costly.
184
184
  const maxReturnTypeInferenceCodeFlowComplexity = 8;
185
+ // What is the max number of return types cached per function
186
+ // when using call-site inference?
187
+ const maxCallSiteReturnTypeCacheSize = 8;
185
188
  // How many entries in a list, set, or dict should we examine
186
189
  // when inferring the type? We need to cut it off at some point
187
190
  // to avoid excessive computation.
@@ -209,7 +212,7 @@ const maxLiteralMathSubtypeCount = 64;
209
212
  // off code flow analysis at some point for code flow graphs that are too
210
213
  // complex. Otherwise we risk overflowing the stack or incurring extremely
211
214
  // long analysis times. This number has been tuned empirically.
212
- exports.maxCodeComplexity = 1024;
215
+ exports.maxCodeComplexity = 768;
213
216
  function createTypeEvaluator(importLookup, evaluatorOptions) {
214
217
  const symbolResolutionStack = [];
215
218
  const typeCacheFlags = new Map();
@@ -231,6 +234,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
231
234
  let functionObj;
232
235
  let tupleClassType;
233
236
  let boolClassType;
237
+ let intClassType;
234
238
  let strClassType;
235
239
  let dictClassType;
236
240
  let typedDictClassType;
@@ -452,6 +456,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
452
456
  noneType = getTypeshedType(node, 'NoneType') || types_1.AnyType.create();
453
457
  tupleClassType = getBuiltInType(node, 'tuple');
454
458
  boolClassType = getBuiltInType(node, 'bool');
459
+ intClassType = getBuiltInType(node, 'int');
455
460
  strClassType = getBuiltInType(node, 'str');
456
461
  dictClassType = getBuiltInType(node, 'dict');
457
462
  typedDictClassType = getTypingType(node, '_TypedDict');
@@ -660,15 +665,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
660
665
  typeResult.type.details.illegalRecursionDetected = true;
661
666
  }
662
667
  }
663
- // Don't update the type cache with an unbound type that results from
664
- // a resolution cycle. The cache will be updated when the stack unwinds
665
- // and the type is fully evaluated.
666
- if (!(0, typeUtils_1.isTypeAliasPlaceholder)(typeResult.type)) {
667
- writeTypeCache(node, typeResult.type, flags, !!typeResult.isIncomplete, expectedType,
668
- /* allowSpeculativeCaching */ true);
669
- if (expectedType && !(0, types_1.isAnyOrUnknown)(expectedType) && !(0, types_1.isNever)(expectedType)) {
670
- expectedTypeCache.set(node.id, expectedType);
671
- }
668
+ writeTypeCache(node, typeResult.type, flags, !!typeResult.isIncomplete, expectedType,
669
+ /* allowSpeculativeCaching */ true);
670
+ if (expectedType && !(0, types_1.isAnyOrUnknown)(expectedType) && !(0, types_1.isNever)(expectedType)) {
671
+ expectedTypeCache.set(node.id, expectedType);
672
672
  }
673
673
  if (printExpressionTypes) {
674
674
  printExpressionSpaceCount--;
@@ -920,7 +920,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
920
920
  const argList = [
921
921
  {
922
922
  argumentCategory: 0 /* Simple */,
923
- type: functionOrClassType,
923
+ typeResult: { type: functionOrClassType },
924
924
  },
925
925
  ];
926
926
  const returnType = validateCallArguments(node.expression, argList, decoratorTypeResult,
@@ -1235,7 +1235,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1235
1235
  function addFakeArg() {
1236
1236
  argList.push({
1237
1237
  argumentCategory: previousCategory,
1238
- type: types_1.UnknownType.create(),
1238
+ typeResult: { type: types_1.UnknownType.create() },
1239
1239
  active: true,
1240
1240
  });
1241
1241
  }
@@ -1277,10 +1277,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1277
1277
  addOneFunctionToSignature(type);
1278
1278
  }
1279
1279
  else {
1280
- type.overloads.forEach((func) => {
1281
- if (types_1.FunctionType.isOverloaded(func)) {
1282
- addOneFunctionToSignature(func);
1283
- }
1280
+ types_1.OverloadedFunctionType.getOverloads(type).forEach((func) => {
1281
+ addOneFunctionToSignature(func);
1284
1282
  });
1285
1283
  }
1286
1284
  }
@@ -1368,7 +1366,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1368
1366
  // Handle the case where the symbol is a class-level variable
1369
1367
  // where the type isn't declared in this class but is in
1370
1368
  // a parent class.
1371
- if (getDeclaredTypeOfSymbol(symbol) === undefined &&
1369
+ if (getDeclaredTypeOfSymbol(symbol, expression) === undefined &&
1372
1370
  symbolWithScope.scope.type === 2 /* Class */) {
1373
1371
  const enclosingClass = ParseTreeUtils.getEnclosingClassOrFunction(expression);
1374
1372
  if (enclosingClass && enclosingClass.nodeType === 10 /* Class */) {
@@ -1386,7 +1384,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1386
1384
  break;
1387
1385
  }
1388
1386
  case 54 /* TypeAnnotation */: {
1389
- return getDeclaredTypeForExpression(expression.valueExpression);
1387
+ return getDeclaredTypeForExpression(expression.valueExpression, usage);
1390
1388
  }
1391
1389
  case 35 /* MemberAccess */: {
1392
1390
  const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.leftExpression, 2 /* DoNotSpecialize */).type);
@@ -1482,13 +1480,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1482
1480
  return subtype;
1483
1481
  }
1484
1482
  if ((0, types_1.isClassInstance)(subtype)) {
1485
- const awaitReturnType = getSpecializedReturnType(subtype, '__await__', errorNode);
1483
+ const awaitReturnType = getSpecializedReturnType(subtype, '__await__', [], errorNode);
1486
1484
  if (awaitReturnType) {
1487
1485
  if ((0, types_1.isAnyOrUnknown)(awaitReturnType)) {
1488
1486
  return awaitReturnType;
1489
1487
  }
1490
1488
  if ((0, types_1.isClassInstance)(awaitReturnType)) {
1491
- const iterReturnType = getSpecializedReturnType(awaitReturnType, '__iter__', errorNode);
1489
+ const iterReturnType = getSpecializedReturnType(awaitReturnType, '__iter__', [], errorNode);
1492
1490
  if (iterReturnType) {
1493
1491
  const generatorReturnType = getReturnTypeFromGenerator(awaitReturnType);
1494
1492
  if (generatorReturnType) {
@@ -1533,18 +1531,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1533
1531
  subtype.tupleTypeArguments.length === 0) {
1534
1532
  return types_1.NeverType.createNever();
1535
1533
  }
1536
- iterReturnType = getSpecializedReturnType(subtype, iterMethodName, errorNode);
1534
+ iterReturnType = getSpecializedReturnType(subtype, iterMethodName, [], errorNode);
1537
1535
  }
1538
1536
  else if (types_1.TypeBase.isInstantiable(subtype) &&
1539
1537
  subtype.details.effectiveMetaclass &&
1540
1538
  (0, types_1.isInstantiableClass)(subtype.details.effectiveMetaclass)) {
1541
- iterReturnType = getSpecializedReturnType(types_1.ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), iterMethodName, errorNode, subtype);
1539
+ iterReturnType = getSpecializedReturnType(types_1.ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), iterMethodName, [], errorNode, subtype);
1542
1540
  }
1543
1541
  if (!iterReturnType) {
1544
1542
  // There was no __iter__. See if we can fall back to
1545
1543
  // the __getitem__ method instead.
1546
- if ((0, types_1.isClassInstance)(subtype)) {
1547
- const getItemReturnType = getSpecializedReturnType(subtype, '__getitem__', errorNode);
1544
+ if (!isAsync && (0, types_1.isClassInstance)(subtype)) {
1545
+ const getItemReturnType = getSpecializedReturnType(subtype, '__getitem__', [
1546
+ {
1547
+ argumentCategory: 0 /* Simple */,
1548
+ typeResult: {
1549
+ type: intClassType && (0, types_1.isInstantiableClass)(intClassType)
1550
+ ? types_1.ClassType.cloneAsInstance(intClassType)
1551
+ : types_1.UnknownType.create(),
1552
+ },
1553
+ },
1554
+ ], errorNode);
1548
1555
  if (getItemReturnType) {
1549
1556
  return getItemReturnType;
1550
1557
  }
@@ -1559,7 +1566,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1559
1566
  return subtype;
1560
1567
  }
1561
1568
  if ((0, types_1.isClassInstance)(subtype)) {
1562
- const nextReturnType = getSpecializedReturnType(subtype, nextMethodName, errorNode);
1569
+ const nextReturnType = getSpecializedReturnType(subtype, nextMethodName, [], errorNode);
1563
1570
  if (!nextReturnType) {
1564
1571
  iterReturnTypeDiag.addMessage(localize_1.Localizer.Diagnostic.methodNotDefinedOnType().format({
1565
1572
  name: nextMethodName,
@@ -1612,12 +1619,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1612
1619
  if ((0, types_1.isClass)(subtype)) {
1613
1620
  let iterReturnType;
1614
1621
  if (types_1.TypeBase.isInstance(subtype)) {
1615
- iterReturnType = getSpecializedReturnType(subtype, iterMethodName, errorNode);
1622
+ iterReturnType = getSpecializedReturnType(subtype, iterMethodName, [], errorNode);
1616
1623
  }
1617
1624
  else if (types_1.TypeBase.isInstantiable(subtype) &&
1618
1625
  subtype.details.effectiveMetaclass &&
1619
1626
  (0, types_1.isInstantiableClass)(subtype.details.effectiveMetaclass)) {
1620
- iterReturnType = getSpecializedReturnType(types_1.ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), iterMethodName, errorNode, subtype);
1627
+ iterReturnType = getSpecializedReturnType(types_1.ClassType.cloneAsInstance(subtype.details.effectiveMetaclass), iterMethodName, [], errorNode, subtype);
1621
1628
  }
1622
1629
  if (iterReturnType) {
1623
1630
  return makeTopLevelTypeVarsConcrete(iterReturnType);
@@ -1765,6 +1772,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1765
1772
  fileInfo.diagnosticSink.addUnusedCodeWithTextRange(localize_1.Localizer.Diagnostic.unreachableCode(), textRange);
1766
1773
  }
1767
1774
  }
1775
+ function addUnreachableCode(node, textRange) {
1776
+ if (!isDiagnosticSuppressedForNode(node)) {
1777
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
1778
+ fileInfo.diagnosticSink.addUnreachableCodeWithTextRange(localize_1.Localizer.Diagnostic.unreachableCode(), textRange);
1779
+ }
1780
+ }
1768
1781
  function addDeprecated(message, node) {
1769
1782
  if (!isDiagnosticSuppressedForNode(node)) {
1770
1783
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
@@ -2519,7 +2532,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2519
2532
  }
2520
2533
  return undefined;
2521
2534
  }
2522
- function getSpecializedReturnType(objType, memberName, errorNode, bindToClass) {
2535
+ function getSpecializedReturnType(objType, memberName, argList, errorNode, bindToClass) {
2523
2536
  const classMember = (0, typeUtils_1.lookUpObjectMember)(objType, memberName, 8 /* SkipInstanceVariables */);
2524
2537
  if (!classMember) {
2525
2538
  return undefined;
@@ -2528,21 +2541,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2528
2541
  if ((0, types_1.isAnyOrUnknown)(memberType)) {
2529
2542
  return memberType;
2530
2543
  }
2531
- if ((0, types_1.isFunction)(memberType)) {
2544
+ if ((0, types_1.isFunction)(memberType) || (0, types_1.isOverloadedFunction)(memberType)) {
2532
2545
  const methodType = bindFunctionToClassOrObject(bindToClass || objType, memberType, classMember && (0, types_1.isInstantiableClass)(classMember.classType) ? classMember.classType : undefined, errorNode,
2533
2546
  /* recursionCount */ undefined,
2534
2547
  /* treatConstructorAsClassMember */ false,
2535
2548
  /* firstParamType */ bindToClass);
2536
2549
  if (methodType) {
2537
- return getFunctionEffectiveReturnType(methodType);
2550
+ if ((0, types_1.isOverloadedFunction)(methodType)) {
2551
+ if (errorNode) {
2552
+ const bestOverload = getBestOverloadForArguments(errorNode, methodType, argList);
2553
+ if (bestOverload) {
2554
+ return getFunctionEffectiveReturnType(bestOverload);
2555
+ }
2556
+ }
2557
+ }
2558
+ else {
2559
+ return getFunctionEffectiveReturnType(methodType);
2560
+ }
2538
2561
  }
2539
2562
  }
2540
2563
  return undefined;
2541
2564
  }
2542
2565
  function getTypeOfName(node, flags) {
2543
- var _a;
2566
+ var _a, _b;
2544
2567
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2545
2568
  const name = node.value;
2569
+ let symbol;
2546
2570
  let type;
2547
2571
  let isIncomplete = false;
2548
2572
  const allowForwardReferences = (flags & 4 /* AllowForwardReferences */) !== 0 || fileInfo.isStubFile;
@@ -2556,96 +2580,104 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2556
2580
  };
2557
2581
  }
2558
2582
  }
2559
- // Look for the scope that contains the value definition and
2560
- // see if it has a declared type.
2561
- const symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags & 1024 /* ExpectingTypeAnnotation */) !== 0);
2562
- if (symbolWithScope) {
2563
- let useCodeFlowAnalysis = !allowForwardReferences;
2564
- // If the symbol is implicitly imported from the builtin
2565
- // scope, there's no need to use code flow analysis.
2566
- if (symbolWithScope.scope.type === 4 /* Builtin */) {
2567
- useCodeFlowAnalysis = false;
2568
- }
2569
- const symbol = symbolWithScope.symbol;
2570
- // Get the effective type (either the declared type or the inferred type).
2571
- // If we're using code flow analysis, pass the usage node so we consider
2572
- // only the assignment nodes that are reachable from this usage.
2573
- const effectiveTypeInfo = getEffectiveTypeOfSymbolForUsage(symbol, useCodeFlowAnalysis ? node : undefined);
2574
- let effectiveType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(effectiveTypeInfo.type);
2575
- if (effectiveTypeInfo.isIncomplete) {
2576
- if ((0, types_1.isUnbound)(effectiveType)) {
2577
- effectiveType = types_1.UnknownType.create(/* isIncomplete */ true);
2578
- }
2579
- isIncomplete = true;
2580
- }
2581
- if (effectiveTypeInfo.isRecursiveDefinition && isNodeReachable(node)) {
2582
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.recursiveDefinition().format({ name }), node);
2583
- }
2584
- const isSpecialBuiltIn = !!effectiveType && (0, types_1.isInstantiableClass)(effectiveType) && types_1.ClassType.isSpecialBuiltIn(effectiveType);
2585
- type = effectiveType;
2586
- if (useCodeFlowAnalysis && !isSpecialBuiltIn) {
2587
- // See if code flow analysis can tell us anything more about the type.
2588
- // If the symbol is declared outside of our execution scope, use its effective
2589
- // type. If it's declared inside our execution scope, it generally starts
2590
- // as unbound at the start of the code flow.
2591
- const typeAtStart = symbolWithScope.isBeyondExecutionScope || !symbol.isInitiallyUnbound()
2592
- ? effectiveType
2593
- : types_1.UnboundType.create();
2594
- const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
2595
- /* isInitialTypeIncomplete */ false,
2596
- /* startNode */ undefined);
2597
- if (codeFlowTypeResult.type) {
2598
- type = codeFlowTypeResult.type;
2599
- }
2600
- if (codeFlowTypeResult.isIncomplete) {
2583
+ const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
2584
+ if (typeParamSymbol) {
2585
+ symbol = typeParamSymbol;
2586
+ type = (_a = getDeclaredTypeOfSymbol(typeParamSymbol)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
2587
+ setSymbolAccessed(fileInfo, symbol, node);
2588
+ }
2589
+ else {
2590
+ // Look for the scope that contains the value definition and
2591
+ // see if it has a declared type.
2592
+ const symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags & 1024 /* ExpectingTypeAnnotation */) !== 0);
2593
+ if (symbolWithScope) {
2594
+ let useCodeFlowAnalysis = !allowForwardReferences;
2595
+ // If the symbol is implicitly imported from the builtin
2596
+ // scope, there's no need to use code flow analysis.
2597
+ if (symbolWithScope.scope.type === 4 /* Builtin */) {
2598
+ useCodeFlowAnalysis = false;
2599
+ }
2600
+ symbol = symbolWithScope.symbol;
2601
+ // Get the effective type (either the declared type or the inferred type).
2602
+ // If we're using code flow analysis, pass the usage node so we consider
2603
+ // only the assignment nodes that are reachable from this usage.
2604
+ const effectiveTypeInfo = getEffectiveTypeOfSymbolForUsage(symbol, useCodeFlowAnalysis ? node : undefined);
2605
+ let effectiveType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(effectiveTypeInfo.type);
2606
+ if (effectiveTypeInfo.isIncomplete) {
2607
+ if ((0, types_1.isUnbound)(effectiveType)) {
2608
+ effectiveType = types_1.UnknownType.create(/* isIncomplete */ true);
2609
+ }
2601
2610
  isIncomplete = true;
2602
2611
  }
2603
- if (!codeFlowTypeResult.type && symbolWithScope.isBeyondExecutionScope) {
2604
- const outerScopeTypeResult = getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType);
2605
- if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.type) {
2606
- type = outerScopeTypeResult.type;
2607
- }
2608
- if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.isIncomplete) {
2612
+ if (effectiveTypeInfo.isRecursiveDefinition && isNodeReachable(node)) {
2613
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.recursiveDefinition().format({ name }), node);
2614
+ }
2615
+ const isSpecialBuiltIn = !!effectiveType && (0, types_1.isInstantiableClass)(effectiveType) && types_1.ClassType.isSpecialBuiltIn(effectiveType);
2616
+ type = effectiveType;
2617
+ if (useCodeFlowAnalysis && !isSpecialBuiltIn) {
2618
+ // See if code flow analysis can tell us anything more about the type.
2619
+ // If the symbol is declared outside of our execution scope, use its effective
2620
+ // type. If it's declared inside our execution scope, it generally starts
2621
+ // as unbound at the start of the code flow.
2622
+ const typeAtStart = symbolWithScope.isBeyondExecutionScope || !symbol.isInitiallyUnbound()
2623
+ ? effectiveType
2624
+ : types_1.UnboundType.create();
2625
+ const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
2626
+ /* isInitialTypeIncomplete */ false,
2627
+ /* startNode */ undefined);
2628
+ if (codeFlowTypeResult.type) {
2629
+ type = codeFlowTypeResult.type;
2630
+ }
2631
+ if (codeFlowTypeResult.isIncomplete) {
2609
2632
  isIncomplete = true;
2610
2633
  }
2634
+ if (!codeFlowTypeResult.type && symbolWithScope.isBeyondExecutionScope) {
2635
+ const outerScopeTypeResult = getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType);
2636
+ if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.type) {
2637
+ type = outerScopeTypeResult.type;
2638
+ }
2639
+ if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.isIncomplete) {
2640
+ isIncomplete = true;
2641
+ }
2642
+ }
2611
2643
  }
2612
- }
2613
- // Detect, report, and fill in missing type arguments if appropriate.
2614
- type = reportMissingTypeArguments(node, type, flags);
2615
- setSymbolAccessed(fileInfo, symbol, node);
2616
- if ((flags & 1024 /* ExpectingTypeAnnotation */) !== 0) {
2617
- // Verify that the name does not refer to a (non type alias) variable.
2618
- if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
2619
- let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
2620
- if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
2621
- // This check exempts class types that are created by calling
2622
- // NewType, NamedTuple, and by invoking a metaclass directly.
2623
- isAllowedTypeForVariable = true;
2624
- }
2625
- // Disable for assignments in the typings.pyi file, since it defines special forms.
2626
- if (!isAllowedTypeForVariable && !fileInfo.isTypingStubFile) {
2627
- // This might be a union that was previously a type alias
2628
- // but was reconstituted in such a way that we lost the
2629
- // typeAliasInfo. Avoid the false positive error by suppressing
2630
- // the error when it looks like a plausible type alias type.
2631
- if (effectiveTypeInfo.includesIllegalTypeAliasDecl ||
2632
- !types_1.TypeBase.isInstantiable(type) ||
2633
- (flags & 2 /* DoNotSpecialize */) !== 0) {
2634
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationVariable(), node);
2635
- type = types_1.UnknownType.create();
2644
+ // Detect, report, and fill in missing type arguments if appropriate.
2645
+ type = reportMissingTypeArguments(node, type, flags);
2646
+ setSymbolAccessed(fileInfo, symbol, node);
2647
+ if ((flags & 1024 /* ExpectingTypeAnnotation */) !== 0) {
2648
+ // Verify that the name does not refer to a (non type alias) variable.
2649
+ if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
2650
+ let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
2651
+ if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
2652
+ // This check exempts class types that are created by calling
2653
+ // NewType, NamedTuple, and by invoking a metaclass directly.
2654
+ isAllowedTypeForVariable = true;
2655
+ }
2656
+ // Disable for assignments in the typings.pyi file, since it defines special forms.
2657
+ if (!isAllowedTypeForVariable && !fileInfo.isTypingStubFile) {
2658
+ // This might be a union that was previously a type alias
2659
+ // but was reconstituted in such a way that we lost the
2660
+ // typeAliasInfo. Avoid the false positive error by suppressing
2661
+ // the error when it looks like a plausible type alias type.
2662
+ if (effectiveTypeInfo.includesIllegalTypeAliasDecl ||
2663
+ !types_1.TypeBase.isInstantiable(type) ||
2664
+ (flags & 2 /* DoNotSpecialize */) !== 0) {
2665
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationVariable(), node);
2666
+ type = types_1.UnknownType.create();
2667
+ }
2636
2668
  }
2637
2669
  }
2638
2670
  }
2639
2671
  }
2640
- }
2641
- else {
2642
- // Handle the special case of "reveal_type" and "reveal_locals".
2643
- if (name === 'reveal_type' || name === 'reveal_locals') {
2644
- type = types_1.AnyType.create();
2645
- }
2646
2672
  else {
2647
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUndefinedVariable, diagnosticRules_1.DiagnosticRule.reportUndefinedVariable, localize_1.Localizer.Diagnostic.symbolIsUndefined().format({ name }), node);
2648
- type = types_1.UnknownType.create();
2673
+ // Handle the special case of "reveal_type" and "reveal_locals".
2674
+ if (name === 'reveal_type' || name === 'reveal_locals') {
2675
+ type = types_1.AnyType.create();
2676
+ }
2677
+ else {
2678
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportUndefinedVariable, diagnosticRules_1.DiagnosticRule.reportUndefinedVariable, localize_1.Localizer.Diagnostic.symbolIsUndefined().format({ name }), node);
2679
+ type = types_1.UnknownType.create();
2680
+ }
2649
2681
  }
2650
2682
  }
2651
2683
  if ((0, types_1.isParamSpec)(type)) {
@@ -2660,7 +2692,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2660
2692
  type.details.name === name) {
2661
2693
  // Handle the special case of a PEP 604 union. These can appear within
2662
2694
  // an implied type alias where we are not expecting a type.
2663
- const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
2695
+ const isPep604Union = ((_b = node.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 7 /* BinaryOperation */ &&
2664
2696
  node.parent.operator === 6 /* BitwiseOr */;
2665
2697
  if (!isPep604Union) {
2666
2698
  // A TypeVar in contexts where we're not expecting a type is
@@ -2748,6 +2780,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2748
2780
  type = scopedTypeVarInfo.type;
2749
2781
  if ((flags & 2048 /* DisallowTypeVarsWithScopeId */) !== 0 && type.scopeId !== undefined) {
2750
2782
  if (!type.details.isSynthesized && !type.details.isParamSpec) {
2783
+ // This TypeVar already has a scope ID assigned to it. See if it
2784
+ // originates from type parameter syntax. If so, allow it.
2785
+ if (type.details.isTypeParamSyntax) {
2786
+ return type;
2787
+ }
2788
+ // If this type variable expression is used within a generic class,
2789
+ // function, or type alias that uses type parameter syntax, there is
2790
+ // no need to report an error here.
2791
+ const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(node);
2792
+ if (typeVarScopeNode &&
2793
+ typeVarScopeNode.typeParameters &&
2794
+ !typeVarScopeNode.typeParameters.parameters.some((t) => t.name === node)) {
2795
+ return type;
2796
+ }
2751
2797
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarUsedByOuterScope().format({ name: type.details.name }), node);
2752
2798
  }
2753
2799
  }
@@ -2773,6 +2819,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2773
2819
  }
2774
2820
  }
2775
2821
  if (enclosingScope) {
2822
+ // If the enclosing scope is using type parameter syntax, traditional
2823
+ // type variables can't be used in this context.
2824
+ if (enclosingScope.typeParameters) {
2825
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeParameterNotDeclared().format({
2826
+ name: type.details.name,
2827
+ container: enclosingScope.name.value,
2828
+ }), node);
2829
+ }
2776
2830
  type = types_1.TypeVarType.cloneForScopeId(type, getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
2777
2831
  ? 1 /* Function */
2778
2832
  : 0 /* Class */);
@@ -2866,50 +2920,48 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2866
2920
  // Walks up the parse tree to find a function, class, or type alias
2867
2921
  // assignment that provides the context for a type variable.
2868
2922
  function findScopedTypeVar(node, type) {
2869
- var _a;
2870
2923
  let curNode = node;
2871
2924
  let nestedClassCount = 0;
2872
2925
  (0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
2873
2926
  while (curNode) {
2874
- // Generally, getTypeVarScopeNode should not include the function
2875
- // that contains the TypeVar in its signature, but we make an exception
2876
- // for TypeVars that are used in a member access expression to accommodate
2877
- // ParamSpecs (P.args and P.kwargs).
2878
- curNode = ParseTreeUtils.getTypeVarScopeNode(curNode, ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 35 /* MemberAccess */);
2927
+ curNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
2879
2928
  if (!curNode) {
2880
2929
  break;
2881
2930
  }
2882
- let typeVarsForScope;
2931
+ let typeParametersForScope;
2932
+ let scopeUsesTypeParameterSyntax = false;
2883
2933
  if (curNode.nodeType === 10 /* Class */) {
2884
2934
  const classTypeInfo = getTypeOfClass(curNode);
2885
- if (classTypeInfo) {
2886
- typeVarsForScope = classTypeInfo.classType.details.typeParameters;
2935
+ if (classTypeInfo && !types_1.ClassType.isPartiallyEvaluated(classTypeInfo.classType)) {
2936
+ typeParametersForScope = classTypeInfo.classType.details.typeParameters;
2887
2937
  }
2938
+ scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
2888
2939
  nestedClassCount++;
2889
2940
  }
2890
2941
  else if (curNode.nodeType === 28 /* Function */) {
2891
2942
  const functionTypeInfo = getTypeOfFunction(curNode);
2892
2943
  if (functionTypeInfo) {
2893
- typeVarsForScope = [];
2944
+ typeParametersForScope = [];
2894
2945
  functionTypeInfo.functionType.details.parameters.forEach((param) => {
2895
2946
  if (param.hasDeclaredType) {
2896
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeVarsForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
2947
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
2897
2948
  }
2898
2949
  });
2899
2950
  if (functionTypeInfo.functionType.details.declaredReturnType) {
2900
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeVarsForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
2951
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
2901
2952
  }
2902
2953
  }
2954
+ scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
2903
2955
  }
2904
- else if (curNode.nodeType === 36 /* Module */) {
2905
- break;
2956
+ else if (curNode.nodeType === 77 /* TypeAlias */) {
2957
+ scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
2906
2958
  }
2907
- if (typeVarsForScope) {
2908
- const match = typeVarsForScope.find((typeVar) => typeVar.details.name === type.details.name);
2959
+ if (typeParametersForScope) {
2960
+ const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
2909
2961
  if (match === null || match === void 0 ? void 0 : match.scopeId) {
2910
2962
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
2911
2963
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
2912
- return { type, foundInterveningClass: nestedClassCount > 1 };
2964
+ return { type, foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax };
2913
2965
  }
2914
2966
  }
2915
2967
  curNode = curNode.parent;
@@ -2917,14 +2969,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2917
2969
  // See if this is part of an assignment statement that is defining a type alias.
2918
2970
  curNode = node;
2919
2971
  while (curNode) {
2920
- if (curNode.nodeType === 3 /* Assignment */) {
2921
- const leftType = readTypeCache(curNode.leftExpression, 0 /* None */);
2972
+ let leftType;
2973
+ let typeAliasNode = undefined;
2974
+ if (curNode.nodeType === 77 /* TypeAlias */) {
2975
+ leftType = readTypeCache(curNode.name, 0 /* None */);
2976
+ typeAliasNode = curNode;
2977
+ }
2978
+ else if (curNode.nodeType === 3 /* Assignment */) {
2979
+ leftType = readTypeCache(curNode.leftExpression, 0 /* None */);
2980
+ }
2981
+ if (leftType) {
2922
2982
  // Is this a placeholder that was temporarily written to the cache for
2923
2983
  // purposes of resolving type aliases?
2924
2984
  if (leftType &&
2925
2985
  (0, types_1.isTypeVar)(leftType) &&
2926
2986
  leftType.details.recursiveTypeAliasScopeId &&
2927
2987
  leftType.details.recursiveTypeAliasName) {
2988
+ // Type alias statements cannot be used with old-style type variables.
2989
+ if (typeAliasNode && !type.details.isTypeParamSyntax) {
2990
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeParameterNotDeclared().format({
2991
+ name: type.details.name,
2992
+ container: typeAliasNode.name.value,
2993
+ }), node);
2994
+ }
2928
2995
  return {
2929
2996
  type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
2930
2997
  foundInterveningClass: false,
@@ -3530,25 +3597,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3530
3597
  {
3531
3598
  // Provide "obj" argument.
3532
3599
  argumentCategory: 0 /* Simple */,
3533
- type: types_1.ClassType.isClassProperty(lookupClass)
3534
- ? baseTypeClass
3535
- : isAccessedThroughObject
3536
- ? bindToType || types_1.ClassType.cloneAsInstance(baseTypeClass)
3537
- : types_1.NoneType.createInstance(),
3600
+ typeResult: {
3601
+ type: types_1.ClassType.isClassProperty(lookupClass)
3602
+ ? baseTypeClass
3603
+ : isAccessedThroughObject
3604
+ ? bindToType || types_1.ClassType.cloneAsInstance(baseTypeClass)
3605
+ : types_1.NoneType.createInstance(),
3606
+ },
3538
3607
  },
3539
3608
  ];
3540
3609
  if (usage.method === 'get') {
3541
3610
  // Provide "objtype" argument.
3542
3611
  argList.push({
3543
3612
  argumentCategory: 0 /* Simple */,
3544
- type: baseTypeClass,
3613
+ typeResult: { type: baseTypeClass },
3545
3614
  });
3546
3615
  }
3547
3616
  else if (usage.method === 'set') {
3548
3617
  // Provide "value" argument.
3549
3618
  argList.push({
3550
3619
  argumentCategory: 0 /* Simple */,
3551
- type: (_a = usage.setType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(),
3620
+ typeResult: { type: (_a = usage.setType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create() },
3552
3621
  });
3553
3622
  }
3554
3623
  if (types_1.ClassType.isPropertyClass(lookupClass) &&
@@ -3660,7 +3729,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3660
3729
  isFinal = types_1.FunctionType.isFinal(concreteSubtype);
3661
3730
  }
3662
3731
  else {
3663
- const impl = concreteSubtype.overloads.find((f) => !types_1.FunctionType.isOverloaded(f));
3732
+ const impl = types_1.OverloadedFunctionType.getImplementation(concreteSubtype);
3664
3733
  if (impl) {
3665
3734
  isFinal = types_1.FunctionType.isFinal(impl);
3666
3735
  }
@@ -3782,55 +3851,57 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3782
3851
  }
3783
3852
  // Applies the __getattr__, __setattr__ or __delattr__ method if present.
3784
3853
  function applyAttributeAccessOverride(classType, errorNode, usage, memberName) {
3785
- var _a, _b, _c, _d;
3786
- if (usage.method === 'get') {
3854
+ var _a, _b, _c;
3855
+ const getAttributeAccessMember = (name) => {
3856
+ var _a;
3787
3857
  // See if the class has a "__getattribute__" or "__getattr__" method.
3788
3858
  // If so, arbitrary members are supported.
3789
- let getAttrType = (_a = getTypeOfClassMember(errorNode, classType, '__getattribute__', { method: 'get' },
3859
+ return (_a = getTypeOfClassMember(errorNode, classType, name, { method: 'get' },
3790
3860
  /* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
3791
- if (!getAttrType) {
3792
- getAttrType = (_b = getTypeOfClassMember(errorNode, classType, '__getattr__', { method: 'get' },
3793
- /* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _b === void 0 ? void 0 : _b.type;
3794
- }
3795
- // If it's an overload, it might be based on the member name. Create
3796
- // a literal str type based on the member name and find the best overload.
3797
- if (getAttrType && (0, types_1.isOverloadedFunction)(getAttrType)) {
3798
- let nameLiteralType = types_1.AnyType.create();
3799
- if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
3800
- nameLiteralType = types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName);
3801
- }
3802
- getAttrType = getBestOverloadForArguments(errorNode, getAttrType, [
3803
- {
3804
- argumentCategory: 0 /* Simple */,
3805
- type: types_1.AnyType.create(),
3806
- },
3807
- {
3808
- argumentCategory: 0 /* Simple */,
3809
- type: nameLiteralType,
3810
- },
3811
- ]);
3812
- }
3813
- if (getAttrType && (0, types_1.isFunction)(getAttrType)) {
3814
- return getFunctionEffectiveReturnType(getAttrType);
3815
- }
3861
+ };
3862
+ let accessMemberType;
3863
+ if (usage.method === 'get') {
3864
+ accessMemberType = (_a = getAttributeAccessMember('__getattribute__')) !== null && _a !== void 0 ? _a : getAttributeAccessMember('__getattr__');
3816
3865
  }
3817
3866
  else if (usage.method === 'set') {
3818
- const setAttrType = (_c = getTypeOfClassMember(errorNode, classType, '__setattr__', { method: 'get' },
3819
- /* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _c === void 0 ? void 0 : _c.type;
3820
- if (setAttrType) {
3821
- // The type doesn't matter for a set usage. We just need
3822
- // to return a defined type.
3823
- return types_1.AnyType.create();
3824
- }
3867
+ accessMemberType = getAttributeAccessMember('__setattr__');
3825
3868
  }
3826
3869
  else {
3827
3870
  (0, debug_1.assert)(usage.method === 'del');
3828
- const delAttrType = (_d = getTypeOfClassMember(errorNode, classType, '__detattr__', { method: 'get' },
3829
- /* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _d === void 0 ? void 0 : _d.type;
3830
- if (delAttrType) {
3831
- // The type doesn't matter for a delete usage. We just need
3832
- // to return a defined type.
3833
- return types_1.AnyType.create();
3871
+ accessMemberType = getAttributeAccessMember('__delattr__');
3872
+ }
3873
+ if (accessMemberType) {
3874
+ let nameLiteralType = types_1.AnyType.create();
3875
+ if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
3876
+ nameLiteralType = types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName);
3877
+ }
3878
+ const argList = [
3879
+ {
3880
+ // Provide "self" argument.
3881
+ argumentCategory: 0 /* Simple */,
3882
+ typeResult: { type: types_1.ClassType.cloneAsInstance(classType) },
3883
+ },
3884
+ {
3885
+ // Provide "name" argument.
3886
+ argumentCategory: 0 /* Simple */,
3887
+ typeResult: { type: nameLiteralType },
3888
+ },
3889
+ ];
3890
+ if (usage.method === 'set') {
3891
+ argList.push({
3892
+ // Provide "value" argument.
3893
+ argumentCategory: 0 /* Simple */,
3894
+ typeResult: { type: (_b = usage.setType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create() },
3895
+ });
3896
+ }
3897
+ if ((0, types_1.isFunction)(accessMemberType) || (0, types_1.isOverloadedFunction)(accessMemberType)) {
3898
+ const boundMethodType = bindFunctionToClassOrObject(classType, accessMemberType, classType, errorNode);
3899
+ if (boundMethodType && ((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
3900
+ const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
3901
+ const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
3902
+ /* skipUnknownArgCheck */ true);
3903
+ return (_c = callResult.returnType) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
3904
+ }
3834
3905
  }
3835
3906
  }
3836
3907
  return undefined;
@@ -4130,7 +4201,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4130
4201
  }
4131
4202
  if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4132
4203
  const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
4133
- const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, undefined, typeArgTypes);
4204
+ const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4134
4205
  return { type, node };
4135
4206
  }
4136
4207
  let isIncomplete = false;
@@ -4369,9 +4440,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4369
4440
  const keywordArgs = node.items.filter((item) => item.argumentCategory === 0 /* Simple */ && !!item.name);
4370
4441
  const unpackedDictArgs = node.items.filter((item) => item.argumentCategory === 2 /* UnpackedDictionary */);
4371
4442
  let positionalIndexType;
4443
+ let isPositionalIndexTypeIncomplete = false;
4372
4444
  if (positionalArgs.length === 1 && unpackedListArgs.length === 0 && !node.trailingComma) {
4373
4445
  // Handle the common case where there is a single positional argument.
4374
- positionalIndexType = getTypeOfExpression(positionalArgs[0].valueExpression).type;
4446
+ const typeResult = getTypeOfExpression(positionalArgs[0].valueExpression);
4447
+ positionalIndexType = typeResult.type;
4448
+ if (typeResult.isIncomplete) {
4449
+ isPositionalIndexTypeIncomplete = true;
4450
+ }
4375
4451
  }
4376
4452
  else if (positionalArgs.length === 0 && unpackedListArgs.length === 0) {
4377
4453
  // Handle the case where there are no positionals provided but there are keywords.
@@ -4384,11 +4460,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4384
4460
  // Package up all of the positionals into a tuple.
4385
4461
  const tupleEntries = [];
4386
4462
  positionalArgs.forEach((arg) => {
4387
- tupleEntries.push(getTypeOfExpression(arg.valueExpression).type);
4463
+ const typeResult = getTypeOfExpression(arg.valueExpression);
4464
+ tupleEntries.push(typeResult.type);
4465
+ if (typeResult.isIncomplete) {
4466
+ isPositionalIndexTypeIncomplete = true;
4467
+ }
4388
4468
  });
4389
4469
  unpackedListArgs.forEach((arg) => {
4390
- const exprType = getTypeOfExpression(arg.valueExpression).type;
4391
- const iterableType = getTypeOfIterator(exprType, /* isAsync */ false, arg) || types_1.UnknownType.create();
4470
+ const typeResult = getTypeOfExpression(arg.valueExpression);
4471
+ const exprType = typeResult.type;
4472
+ if (typeResult.isIncomplete) {
4473
+ isPositionalIndexTypeIncomplete = true;
4474
+ }
4475
+ const iterableType = getTypeOfIterator(exprType, /* isAsync */ false, arg.valueExpression) || types_1.UnknownType.create();
4392
4476
  tupleEntries.push(iterableType);
4393
4477
  });
4394
4478
  positionalIndexType = makeTupleObject(tupleEntries, unpackedListArgs.length > 0);
@@ -4396,7 +4480,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4396
4480
  let argList = [
4397
4481
  {
4398
4482
  argumentCategory: 0 /* Simple */,
4399
- type: positionalIndexType,
4483
+ typeResult: { type: positionalIndexType, isIncomplete: isPositionalIndexTypeIncomplete },
4400
4484
  },
4401
4485
  ];
4402
4486
  if (usage.method === 'set') {
@@ -4408,7 +4492,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4408
4492
  }
4409
4493
  argList.push({
4410
4494
  argumentCategory: 0 /* Simple */,
4411
- type: setType,
4495
+ typeResult: { type: setType, isIncomplete: isPositionalIndexTypeIncomplete },
4412
4496
  });
4413
4497
  }
4414
4498
  keywordArgs.forEach((arg) => {
@@ -4430,29 +4514,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4430
4514
  // Speculatively attempt the call. We may need to replace the index
4431
4515
  // type with 'int', and we don't want to emit errors before we know
4432
4516
  // which type to use.
4433
- useSpeculativeMode(node, () => {
4434
- callResult = validateCallArguments(node, argList, { type: itemMethodType });
4435
- if (callResult.argumentErrors) {
4436
- // If the object supports "__index__" magic method, convert
4437
- // the index it to an int and try again.
4438
- if ((0, types_1.isClassInstance)(positionalIndexType) && keywordArgs.length === 0 && unpackedDictArgs.length === 0) {
4439
- const altArgList = [...argList];
4440
- altArgList[0] = { ...altArgList[0] };
4441
- const indexMethod = getTypeOfObjectMember(node, positionalIndexType, '__index__');
4442
- if (indexMethod) {
4443
- const intType = getBuiltInObject(node, 'int');
4444
- if ((0, types_1.isClassInstance)(intType)) {
4445
- altArgList[0].type = intType;
4517
+ if (keywordArgs.length === 0 && unpackedDictArgs.length === 0 && positionalArgs.length === 1) {
4518
+ useSpeculativeMode(node, () => {
4519
+ callResult = validateCallArguments(node, argList, { type: itemMethodType });
4520
+ if (callResult.argumentErrors) {
4521
+ // If the object supports "__index__" magic method, convert
4522
+ // the index to an int and try again.
4523
+ if ((0, types_1.isClassInstance)(positionalIndexType)) {
4524
+ const altArgList = [...argList];
4525
+ altArgList[0] = { ...altArgList[0] };
4526
+ const indexMethod = getTypeOfObjectMember(node, positionalIndexType, '__index__');
4527
+ if (indexMethod) {
4528
+ const intType = getBuiltInObject(node, 'int');
4529
+ if ((0, types_1.isClassInstance)(intType)) {
4530
+ altArgList[0].typeResult = { type: intType };
4531
+ }
4532
+ }
4533
+ callResult = validateCallArguments(node, altArgList, { type: itemMethodType });
4534
+ // We were successful, so replace the arg list.
4535
+ if (!callResult.argumentErrors) {
4536
+ argList = altArgList;
4446
4537
  }
4447
- }
4448
- callResult = validateCallArguments(node, altArgList, { type: itemMethodType });
4449
- // We were successful, so replace the arg list.
4450
- if (!callResult.argumentErrors) {
4451
- argList = altArgList;
4452
4538
  }
4453
4539
  }
4454
- }
4455
- });
4540
+ });
4541
+ }
4456
4542
  callResult = validateCallArguments(node, argList, { type: itemMethodType });
4457
4543
  return {
4458
4544
  node,
@@ -5028,7 +5114,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5028
5114
  bindToType: resultIsInstance && bindToType && (0, types_1.isInstantiableClass)(bindToType)
5029
5115
  ? types_1.ClassType.cloneAsInstance(bindToType)
5030
5116
  : bindToType,
5031
- isSuperCall: true,
5032
5117
  };
5033
5118
  }
5034
5119
  }
@@ -5040,7 +5125,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5040
5125
  if (targetClassType.details.mro.some((mroBase) => (0, types_1.isAnyOrUnknown)(mroBase))) {
5041
5126
  return {
5042
5127
  type: types_1.UnknownType.create(),
5043
- isSuperCall: true,
5044
5128
  node,
5045
5129
  };
5046
5130
  }
@@ -5050,7 +5134,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5050
5134
  if ((0, types_1.isInstantiableClass)(baseClassType)) {
5051
5135
  return {
5052
5136
  type: resultIsInstance ? types_1.ClassType.cloneAsInstance(baseClassType) : baseClassType,
5053
- isSuperCall: true,
5054
5137
  node,
5055
5138
  };
5056
5139
  }
@@ -5058,7 +5141,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5058
5141
  }
5059
5142
  return {
5060
5143
  type: types_1.UnknownType.create(),
5061
- isSuperCall: true,
5062
5144
  node,
5063
5145
  };
5064
5146
  }
@@ -5152,15 +5234,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5152
5234
  let overloadIndex = 0;
5153
5235
  let matches = [];
5154
5236
  // Create a list of potential overload matches based on arguments.
5155
- type.overloads.forEach((overload) => {
5237
+ types_1.OverloadedFunctionType.getOverloads(type).forEach((overload) => {
5156
5238
  useSpeculativeMode(errorNode, () => {
5157
- if (types_1.FunctionType.isOverloaded(overload)) {
5158
- const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, overload, overloadIndex);
5159
- if (!matchResults.argumentErrors) {
5160
- matches.push(matchResults);
5161
- }
5162
- overloadIndex++;
5239
+ const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, overload, overloadIndex);
5240
+ if (!matchResults.argumentErrors) {
5241
+ matches.push(matchResults);
5163
5242
  }
5243
+ overloadIndex++;
5164
5244
  });
5165
5245
  });
5166
5246
  matches = sortOverloadsByBestMatch(matches);
@@ -5197,17 +5277,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5197
5277
  // cache or record any diagnostics at this stage.
5198
5278
  useSpeculativeMode(errorNode, () => {
5199
5279
  let overloadIndex = 0;
5200
- type.overloads.forEach((overload) => {
5280
+ types_1.OverloadedFunctionType.getOverloads(type).forEach((overload) => {
5201
5281
  // Consider only the functions that have the @overload decorator,
5202
5282
  // not the final function that omits the overload. This is the
5203
5283
  // intended behavior according to PEP 484.
5204
- if (types_1.FunctionType.isOverloaded(overload)) {
5205
- const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, overload, overloadIndex);
5206
- if (!matchResults.argumentErrors) {
5207
- filteredMatchResults.push(matchResults);
5208
- }
5209
- overloadIndex++;
5284
+ const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, overload, overloadIndex);
5285
+ if (!matchResults.argumentErrors) {
5286
+ filteredMatchResults.push(matchResults);
5210
5287
  }
5288
+ overloadIndex++;
5211
5289
  });
5212
5290
  });
5213
5291
  filteredMatchResults = sortOverloadsByBestMatch(filteredMatchResults);
@@ -5262,8 +5340,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5262
5340
  // the expectedType. We'll use this to determine whether we need to do
5263
5341
  // union expansion.
5264
5342
  contextFreeArgTypes = argList.map((arg) => {
5265
- if (arg.type) {
5266
- return arg.type;
5343
+ if (arg.typeResult) {
5344
+ return arg.typeResult.type;
5267
5345
  }
5268
5346
  if (arg.valueExpression) {
5269
5347
  const valueExpressionNode = arg.valueExpression;
@@ -5673,6 +5751,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5673
5751
  return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
5674
5752
  /* includesTypes */ false);
5675
5753
  }
5754
+ // Handle the NewType specially, replacing the normal return type.
5755
+ if (expandedSubtype.details.builtInName === 'NewType') {
5756
+ return createNewType(errorNode, argList);
5757
+ }
5676
5758
  let effectiveTypeVarContext = typeVarContext;
5677
5759
  if (!effectiveTypeVarContext) {
5678
5760
  // If a typeVarContext wasn't provided by the caller, allocate one here.
@@ -5709,10 +5791,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5709
5791
  argumentErrors = true;
5710
5792
  }
5711
5793
  }
5712
- // Handle the NewType specially, replacing the normal return type.
5713
- if (!functionResult.argumentErrors && expandedSubtype.details.builtInName === 'NewType') {
5714
- return createNewType(errorNode, argList);
5715
- }
5716
5794
  if (expandedSubtype.details.builtInName === '__import__') {
5717
5795
  // For the special __import__ type, we'll override the return type to be "Any".
5718
5796
  // This is required because we don't know what module was imported, and we don't
@@ -6165,7 +6243,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6165
6243
  const funcArg = listElementType
6166
6244
  ? {
6167
6245
  argumentCategory: 0 /* Simple */,
6168
- type: listElementType,
6246
+ typeResult: { type: listElementType, isIncomplete: argTypeResult.isIncomplete },
6169
6247
  }
6170
6248
  : undefined;
6171
6249
  if (funcArg && argTypeResult.isIncomplete) {
@@ -6330,7 +6408,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6330
6408
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
6331
6409
  argument: {
6332
6410
  argumentCategory: 0 /* Simple */,
6333
- type: entry.valueType,
6411
+ typeResult: { type: entry.valueType },
6334
6412
  },
6335
6413
  errorNode: argList[argIndex].valueExpression || errorNode,
6336
6414
  paramName: name,
@@ -6345,7 +6423,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6345
6423
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
6346
6424
  argument: {
6347
6425
  argumentCategory: 0 /* Simple */,
6348
- type: entry.valueType,
6426
+ typeResult: { type: entry.valueType },
6349
6427
  },
6350
6428
  errorNode: argList[argIndex].valueExpression || errorNode,
6351
6429
  paramName: name,
@@ -6535,7 +6613,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6535
6613
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
6536
6614
  argument: {
6537
6615
  argumentCategory: 0 /* Simple */,
6538
- type: unpackedDictionaryArgType,
6616
+ typeResult: { type: unpackedDictionaryArgType },
6539
6617
  },
6540
6618
  errorNode: (_b = (_a = argList.find((arg) => arg.argumentCategory === 2 /* UnpackedDictionary */)) === null || _a === void 0 ? void 0 : _a.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
6541
6619
  paramName: param.name,
@@ -6582,7 +6660,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6582
6660
  requiresTypeVarMatching: true,
6583
6661
  argument: {
6584
6662
  argumentCategory: 0 /* Simple */,
6585
- type: defaultArgType,
6663
+ typeResult: { type: defaultArgType },
6586
6664
  },
6587
6665
  errorNode: errorNode,
6588
6666
  paramName: param.name,
@@ -6636,7 +6714,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6636
6714
  paramCategory: 1 /* VarArgList */,
6637
6715
  paramType,
6638
6716
  requiresTypeVarMatching: true,
6639
- argument: { argumentCategory: 0 /* Simple */, type: specializedTuple },
6717
+ argument: {
6718
+ argumentCategory: 0 /* Simple */,
6719
+ typeResult: { type: specializedTuple },
6720
+ },
6640
6721
  errorNode,
6641
6722
  paramName: paramDetails.params[paramDetails.argsIndex].param.name,
6642
6723
  isParamNameSynthesized: paramDetails.params[paramDetails.argsIndex].param.isNameSynthesized,
@@ -6881,7 +6962,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6881
6962
  // scope.
6882
6963
  let eliminateUnsolvedInUnions = true;
6883
6964
  let curNode = errorNode;
6884
- while (true) {
6965
+ while (curNode) {
6885
6966
  const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
6886
6967
  if (!typeVarScopeNode) {
6887
6968
  break;
@@ -6890,7 +6971,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6890
6971
  if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
6891
6972
  eliminateUnsolvedInUnions = false;
6892
6973
  }
6893
- curNode = typeVarScopeNode;
6974
+ curNode = typeVarScopeNode.parent;
6894
6975
  }
6895
6976
  // If the function is returning a callable, don't eliminate unsolved
6896
6977
  // type vars within a union. There are legit uses for unsolved type vars
@@ -7138,7 +7219,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7138
7219
  if (argParam.argType) {
7139
7220
  argType = argParam.argType;
7140
7221
  }
7141
- else if (argParam.expectingType && !argParam.argument.type && argParam.argument.valueExpression) {
7222
+ else if (argParam.expectingType && !argParam.argument.typeResult && argParam.argument.valueExpression) {
7142
7223
  const argTypeResult = getTypeOfExpression(argParam.argument.valueExpression, 8 /* EvaluateStringLiteralAsType */ |
7143
7224
  32 /* ParamSpecDisallowed */ |
7144
7225
  128 /* TypeVarTupleDisallowed */);
@@ -7317,7 +7398,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7317
7398
  return { isCompatible, argType, isTypeIncomplete, condition };
7318
7399
  }
7319
7400
  function createTypeVarType(errorNode, argList) {
7320
- var _a, _b, _c;
7401
+ var _a, _b, _c, _d, _e;
7321
7402
  let typeVarName = '';
7322
7403
  let firstConstraintArg;
7323
7404
  if (argList.length === 0) {
@@ -7346,7 +7427,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7346
7427
  addError(localize_1.Localizer.Diagnostic.typeVarBoundAndConstrained(), argList[i].valueExpression || errorNode);
7347
7428
  }
7348
7429
  else {
7349
- const argType = (_a = argList[i].type) !== null && _a !== void 0 ? _a : getTypeOfExpressionExpectingType(argList[i].valueExpression,
7430
+ const argType = (_b = (_a = argList[i].typeResult) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : getTypeOfExpressionExpectingType(argList[i].valueExpression,
7350
7431
  /* allowFinal */ undefined,
7351
7432
  /* allowRequired */ undefined).type;
7352
7433
  if ((0, typeUtils_1.requiresSpecialization)(argType, /* ignorePseudoGeneric */ true)) {
@@ -7357,26 +7438,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7357
7438
  }
7358
7439
  else if (paramName === 'covariant') {
7359
7440
  if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
7360
- if (typeVar.details.variance === 2 /* Contravariant */) {
7441
+ if (typeVar.details.declaredVariance === 4 /* Contravariant */) {
7361
7442
  addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
7362
7443
  }
7363
7444
  else {
7364
- typeVar.details.variance = 1 /* Covariant */;
7445
+ typeVar.details.declaredVariance = 3 /* Covariant */;
7365
7446
  }
7366
7447
  }
7367
7448
  }
7368
7449
  else if (paramName === 'contravariant') {
7369
7450
  if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
7370
- if (typeVar.details.variance === 1 /* Covariant */) {
7451
+ if (typeVar.details.declaredVariance === 3 /* Covariant */) {
7371
7452
  addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
7372
7453
  }
7373
7454
  else {
7374
- typeVar.details.variance = 2 /* Contravariant */;
7455
+ typeVar.details.declaredVariance = 4 /* Contravariant */;
7375
7456
  }
7376
7457
  }
7377
7458
  }
7378
7459
  else {
7379
- addError(localize_1.Localizer.Diagnostic.typeVarUnknownParam().format({ name: paramName }), ((_b = argList[i].node) === null || _b === void 0 ? void 0 : _b.name) || argList[i].valueExpression || errorNode);
7460
+ addError(localize_1.Localizer.Diagnostic.typeVarUnknownParam().format({ name: paramName }), ((_c = argList[i].node) === null || _c === void 0 ? void 0 : _c.name) || argList[i].valueExpression || errorNode);
7380
7461
  }
7381
7462
  paramNameMap.set(paramName, paramName);
7382
7463
  }
@@ -7385,7 +7466,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7385
7466
  addError(localize_1.Localizer.Diagnostic.typeVarBoundAndConstrained(), argList[i].valueExpression || errorNode);
7386
7467
  }
7387
7468
  else {
7388
- const argType = (_c = argList[i].type) !== null && _c !== void 0 ? _c : getTypeOfExpressionExpectingType(argList[i].valueExpression,
7469
+ const argType = (_e = (_d = argList[i].typeResult) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : getTypeOfExpressionExpectingType(argList[i].valueExpression,
7389
7470
  /* allowFinal */ undefined,
7390
7471
  /* allowRequired */ undefined).type;
7391
7472
  if ((0, typeUtils_1.requiresSpecialization)(argType, /* ignorePseudoGeneric */ true)) {
@@ -7880,7 +7961,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7880
7961
  // incomplete because we may be evaluating types within a loop,
7881
7962
  // so the literal values may change each time.
7882
7963
  const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node);
7883
- let type = validateBinaryOperation(node.operator, leftType, rightType, node, expectedType, diag, isLiteralMathAllowed);
7964
+ let type = validateBinaryOperation(node.operator, { type: leftType, isIncomplete: leftTypeResult.isIncomplete }, { type: rightType, isIncomplete: rightTypeResult.isIncomplete }, node, expectedType, diag, isLiteralMathAllowed);
7884
7965
  if (!diag.isEmpty() || !type) {
7885
7966
  if (!isIncomplete) {
7886
7967
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
@@ -7966,14 +8047,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7966
8047
  return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
7967
8048
  }
7968
8049
  const magicMethodName = operatorMap[node.operator][0];
7969
- let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [rightSubtypeUnexpanded], magicMethodName, node, expectedType);
8050
+ let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, expectedType);
7970
8051
  if (!returnType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
7971
8052
  // Try with the expanded left type.
7972
- returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [rightSubtypeUnexpanded], magicMethodName, node, expectedType);
8053
+ returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, expectedType);
7973
8054
  }
7974
8055
  if (!returnType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
7975
8056
  // Try with the expanded left and right type.
7976
- returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [rightSubtypeExpanded], magicMethodName, node, expectedType);
8057
+ returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, expectedType);
7977
8058
  }
7978
8059
  if (!returnType) {
7979
8060
  // If the LHS class didn't support the magic method for augmented
@@ -7986,7 +8067,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7986
8067
  !rightTypeResult.isIncomplete &&
7987
8068
  (0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) <
7988
8069
  maxLiteralMathSubtypeCount;
7989
- returnType = validateBinaryOperation(binaryOperator, leftSubtypeUnexpanded, rightSubtypeUnexpanded, node, expectedType, diag, isLiteralMathAllowed);
8070
+ returnType = validateBinaryOperation(binaryOperator, { type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }, { type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }, node, expectedType, diag, isLiteralMathAllowed);
7990
8071
  }
7991
8072
  return returnType;
7992
8073
  });
@@ -8009,7 +8090,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8009
8090
  assignTypeToExpression(node.destExpression, typeResult.type, !!typeResult.isIncomplete, node.rightExpression);
8010
8091
  return typeResult;
8011
8092
  }
8012
- function validateBinaryOperation(operator, leftType, rightType, errorNode, expectedType, diag, isLiteralMathAllowed) {
8093
+ function validateBinaryOperation(operator, leftTypeResult, rightTypeResult, errorNode, expectedType, diag, isLiteralMathAllowed) {
8094
+ const leftType = leftTypeResult.type;
8095
+ const rightType = rightTypeResult.type;
8013
8096
  let type;
8014
8097
  let concreteLeftType = makeTopLevelTypeVarsConcrete(leftType);
8015
8098
  if (booleanOperatorMap[operator] !== undefined) {
@@ -8059,7 +8142,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8059
8142
  if ((0, types_1.isAnyOrUnknown)(leftSubtype) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
8060
8143
  return (0, typeUtils_1.preserveUnknown)(leftSubtype, rightSubtypeExpanded);
8061
8144
  }
8062
- let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [leftSubtype], '__contains__', errorNode,
8145
+ let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], '__contains__', errorNode,
8063
8146
  /* expectedType */ undefined);
8064
8147
  if (!returnType) {
8065
8148
  // If __contains__ was not supported, fall back
@@ -8216,26 +8299,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8216
8299
  ]));
8217
8300
  }
8218
8301
  const magicMethodName = binaryOperatorMap[operator][0];
8219
- let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [rightSubtypeUnexpanded], magicMethodName, errorNode, expectedType);
8302
+ let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, expectedType);
8220
8303
  if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
8221
8304
  // Try the expanded left type.
8222
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [rightSubtypeUnexpanded], magicMethodName, errorNode, expectedType);
8305
+ resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, expectedType);
8223
8306
  }
8224
8307
  if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
8225
8308
  // Try the expanded left and right type.
8226
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [rightSubtypeExpanded], magicMethodName, errorNode, expectedType);
8309
+ resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, expectedType);
8227
8310
  }
8228
8311
  if (!resultType) {
8229
8312
  // Try the alternate form (swapping right and left).
8230
8313
  const altMagicMethodName = binaryOperatorMap[operator][1];
8231
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [leftSubtypeUnexpanded], altMagicMethodName, errorNode, expectedType);
8314
+ resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, expectedType);
8232
8315
  if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
8233
8316
  // Try the expanded right type.
8234
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [leftSubtypeUnexpanded], altMagicMethodName, errorNode, expectedType);
8317
+ resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [
8318
+ {
8319
+ type: leftSubtypeUnexpanded,
8320
+ isIncomplete: leftTypeResult.isIncomplete,
8321
+ },
8322
+ ], altMagicMethodName, errorNode, expectedType);
8235
8323
  }
8236
8324
  if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
8237
8325
  // Try the expanded right and left type.
8238
- resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [leftSubtypeExpanded], altMagicMethodName, errorNode, expectedType);
8326
+ resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, expectedType);
8239
8327
  }
8240
8328
  }
8241
8329
  if (!resultType) {
@@ -8283,7 +8371,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8283
8371
  const functionArgs = args.map((arg) => {
8284
8372
  return {
8285
8373
  argumentCategory: 0 /* Simple */,
8286
- type: arg,
8374
+ typeResult: arg,
8287
8375
  };
8288
8376
  });
8289
8377
  let callResult;
@@ -9079,15 +9167,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9079
9167
  return { type, node, isIncomplete };
9080
9168
  }
9081
9169
  function getTypeOfSlice(node) {
9082
- // Evaluate the expressions to report errors and record symbol references.
9083
- if (node.startValue) {
9084
- getTypeOfExpression(node.startValue);
9085
- }
9086
- if (node.endValue) {
9087
- getTypeOfExpression(node.endValue);
9088
- }
9089
- if (node.stepValue) {
9090
- getTypeOfExpression(node.stepValue);
9170
+ // Evaluate the expressions to report errors and record symbol
9171
+ // references. We can skip this if we're executing speculatively.
9172
+ if (!speculativeTypeTracker.isSpeculative(node)) {
9173
+ if (node.startValue) {
9174
+ getTypeOfExpression(node.startValue);
9175
+ }
9176
+ if (node.endValue) {
9177
+ getTypeOfExpression(node.endValue);
9178
+ }
9179
+ if (node.stepValue) {
9180
+ getTypeOfExpression(node.stepValue);
9181
+ }
9091
9182
  }
9092
9183
  return { type: getBuiltInObject(node, 'slice'), node };
9093
9184
  }
@@ -9832,7 +9923,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9832
9923
  }
9833
9924
  return undefined;
9834
9925
  }
9835
- function transformTypeForTypeAlias(type, name, errorNode) {
9926
+ function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
9836
9927
  if (!types_1.TypeBase.isInstantiable(type)) {
9837
9928
  return type;
9838
9929
  }
@@ -9841,17 +9932,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9841
9932
  if ((0, typeUtils_1.isTypeAliasPlaceholder)(type)) {
9842
9933
  return type;
9843
9934
  }
9844
- // Determine if there are any generic type parameters associated
9845
- // with this type alias.
9846
- let typeParameters = [];
9847
- // Skip this for a simple TypeVar (one that's not part of a union).
9848
- if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
9849
- (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
9850
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
9851
- });
9935
+ if (!typeParameters) {
9936
+ // Determine if there are any generic type parameters associated
9937
+ // with this type alias.
9938
+ typeParameters = [];
9939
+ // Skip this for a simple TypeVar (one that's not part of a union).
9940
+ if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
9941
+ (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
9942
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
9943
+ });
9944
+ }
9945
+ // Don't include any synthesized type variables.
9946
+ typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
9852
9947
  }
9853
- // Don't include any synthesized type variables.
9854
- typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
9855
9948
  // Convert all type variables to instances.
9856
9949
  typeParameters = typeParameters.map((typeVar) => {
9857
9950
  if (types_1.TypeBase.isInstance(typeVar)) {
@@ -10052,7 +10145,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10052
10145
  }
10053
10146
  if (!rightHandType) {
10054
10147
  // Determine whether there is a declared type.
10055
- const declaredType = getDeclaredTypeForExpression(node.leftExpression, { method: 'set' });
10148
+ const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
10149
+ method: 'set',
10150
+ });
10056
10151
  let typeAliasNameNode;
10057
10152
  let isSpeculativeTypeAlias = false;
10058
10153
  if (isDeclaredTypeAlias(node.leftExpression)) {
@@ -10158,6 +10253,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10158
10253
  /* allowAssignmentToFinalVar */ true, expectedTypeDiagAddendum);
10159
10254
  writeTypeCache(node, rightHandType, 0 /* None */, isIncomplete);
10160
10255
  }
10256
+ // Evaluates the type of a type alias (i.e. "type") statement. This code
10257
+ // path does not handle traditional type aliases, which are treated as
10258
+ // variables since they use normal variable assignment syntax.
10259
+ function getTypeOfTypeAlias(node) {
10260
+ const cachedType = readTypeCache(node.name, 0 /* None */);
10261
+ if (cachedType) {
10262
+ return cachedType;
10263
+ }
10264
+ // Synthesize a type variable that represents the type alias while we're
10265
+ // evaluating it. This allows us to handle recursive definitions.
10266
+ const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${node.name.value}`);
10267
+ typeAliasTypeVar.details.isSynthesized = true;
10268
+ typeAliasTypeVar.details.recursiveTypeAliasName = node.name.value;
10269
+ const scopeId = getScopeIdForNode(node.name);
10270
+ typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
10271
+ typeAliasTypeVar.scopeId = scopeId;
10272
+ // Write the type to the type cache. It will be replaced below.
10273
+ writeTypeCache(node.name, typeAliasTypeVar, /* flags */ undefined, /* isIncomplete */ false);
10274
+ // Set a partial type to handle recursive (self-referential) type aliases.
10275
+ const scope = ScopeUtils.getScopeForNode(node);
10276
+ const typeAliasSymbol = scope === null || scope === void 0 ? void 0 : scope.lookUpSymbolRecursive(node.name.value);
10277
+ const typeAliasDecl = AnalyzerNodeInfo.getDeclaration(node);
10278
+ if (typeAliasDecl && typeAliasSymbol) {
10279
+ setSymbolResolutionPartialType(typeAliasSymbol.symbol, typeAliasDecl, typeAliasTypeVar);
10280
+ }
10281
+ let typeParameters = [];
10282
+ if (node.typeParameters) {
10283
+ typeParameters = evaluateTypeParameterList(node.typeParameters);
10284
+ typeAliasTypeVar.details.recursiveTypeParameters = typeParameters;
10285
+ }
10286
+ const aliasTypeResult = getTypeOfExpressionExpectingType(node.expression);
10287
+ let isIncomplete = false;
10288
+ let aliasType = aliasTypeResult.type;
10289
+ if (aliasTypeResult.isIncomplete) {
10290
+ isIncomplete = true;
10291
+ }
10292
+ // Clear the temporary type we wrote above.
10293
+ deleteTypeCacheEntry(node.name);
10294
+ aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters);
10295
+ if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
10296
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10297
+ name: node.name.value,
10298
+ }), node.expression);
10299
+ aliasType = types_1.UnknownType.create();
10300
+ }
10301
+ // Set the resulting type to the boundType of the original type alias
10302
+ // to support recursive type aliases.
10303
+ typeAliasTypeVar.details.boundType = aliasType;
10304
+ if (typeAliasTypeVar.details.illegalRecursionDetected) {
10305
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveIndirect().format({
10306
+ name: node.name.value,
10307
+ }), node.name);
10308
+ }
10309
+ writeTypeCache(node.name, aliasType, 0 /* None */, isIncomplete);
10310
+ return aliasType;
10311
+ }
10161
10312
  function evaluateTypesForAugmentedAssignment(node) {
10162
10313
  if (readTypeCache(node, 0 /* None */)) {
10163
10314
  return;
@@ -10223,7 +10374,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10223
10374
  writeTypeCache(node.name, classType, /* flags */ undefined, /* isIncomplete */ false);
10224
10375
  // Keep a list of unique type parameters that are used in the
10225
10376
  // base class arguments.
10226
- const typeParameters = [];
10377
+ let typeParameters = [];
10378
+ if (node.typeParameters) {
10379
+ typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
10380
+ }
10227
10381
  // If the class derives from "Generic" directly, it will provide
10228
10382
  // all of the type parameters in the specified order.
10229
10383
  let genericTypeParameters;
@@ -10344,12 +10498,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10344
10498
  (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10345
10499
  if ((0, types_1.isInstantiableClass)(argType)) {
10346
10500
  if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
10347
- if (!genericTypeParameters) {
10348
- if (protocolTypeParameters) {
10349
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
10501
+ // 'Generic' is implicitly added if type parameter syntax is used.
10502
+ if (node.typeParameters) {
10503
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
10504
+ }
10505
+ else {
10506
+ if (!genericTypeParameters) {
10507
+ if (protocolTypeParameters) {
10508
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
10509
+ }
10510
+ genericTypeParameters = [];
10511
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10350
10512
  }
10351
- genericTypeParameters = [];
10352
- (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10353
10513
  }
10354
10514
  }
10355
10515
  else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
@@ -10361,6 +10521,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10361
10521
  }
10362
10522
  protocolTypeParameters = [];
10363
10523
  (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10524
+ if (node.typeParameters && protocolTypeParameters.length > 0) {
10525
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
10526
+ protocolTypeParameters = [];
10527
+ }
10364
10528
  }
10365
10529
  }
10366
10530
  }
@@ -10423,10 +10587,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10423
10587
  // If genericTypeParameters or protocolTypeParameters are provided,
10424
10588
  // make sure that typeParameters is a proper subset.
10425
10589
  genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
10426
- if (genericTypeParameters) {
10590
+ if (genericTypeParameters && !node.typeParameters) {
10427
10591
  verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
10428
10592
  }
10429
- classType.details.typeParameters = genericTypeParameters || typeParameters;
10593
+ classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
10594
+ // Determine if one or more type parameters is autovariance.
10595
+ if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
10596
+ classType.details.requiresVarianceInference = true;
10597
+ }
10430
10598
  // Make sure there's at most one variadic type parameter.
10431
10599
  const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
10432
10600
  if (variadics.length > 1) {
@@ -10456,7 +10624,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10456
10624
  const initMethod = classType.details.fields.get('__init__');
10457
10625
  if (initMethod) {
10458
10626
  const initDecls = initMethod.getTypedDeclarations();
10459
- if (initDecls.length === 1 && initDecls[0].type === 3 /* Function */) {
10627
+ if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
10460
10628
  const initDeclNode = initDecls[0].node;
10461
10629
  const initParams = initDeclNode.parameters;
10462
10630
  if (initParams.length > 1 &&
@@ -10506,6 +10674,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10506
10674
  }
10507
10675
  }
10508
10676
  const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
10677
+ // Clear the "partially constructed" flag.
10678
+ classType.details.flags &= ~131072 /* PartiallyEvaluated */;
10509
10679
  // Now determine the decorated type of the class.
10510
10680
  let decoratedType = classType;
10511
10681
  let foundUnknown = false;
@@ -10542,8 +10712,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10542
10712
  (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
10543
10713
  (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, classType, initSubclassArgs);
10544
10714
  }
10545
- // Clear the "partially constructed" flag.
10546
- classType.details.flags &= ~131072 /* PartiallyEvaluated */;
10547
10715
  // Run any class hooks that depend on this class.
10548
10716
  runClassTypeHooks(classType);
10549
10717
  // Synthesize TypedDict methods.
@@ -10619,6 +10787,87 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10619
10787
  }
10620
10788
  return { classType, decoratedType };
10621
10789
  }
10790
+ function inferTypeParameterVarianceForClass(classType) {
10791
+ if (!classType.details.requiresVarianceInference) {
10792
+ return;
10793
+ }
10794
+ if (!objectType || !(0, types_1.isClassInstance)(objectType)) {
10795
+ return;
10796
+ }
10797
+ // Presumptively mark the variance inference as complete. This
10798
+ // prevents potential recursion.
10799
+ classType.details.requiresVarianceInference = false;
10800
+ // Presumptively mark the computed variance to "in progress". We'll
10801
+ // replace this below once the variance has been inferred.
10802
+ classType.details.typeParameters.forEach((param) => {
10803
+ if (param.details.declaredVariance === 0 /* Auto */) {
10804
+ param.computedVariance = 1 /* Unknown */;
10805
+ }
10806
+ });
10807
+ // Replace all of the type parameters with invariant TypeVars.
10808
+ const updatedTypeParams = classType.details.typeParameters.map((typeParam) => types_1.TypeVarType.cloneAsInvariant(typeParam));
10809
+ const updatedClassType = types_1.ClassType.cloneWithNewTypeParameters(classType, updatedTypeParams);
10810
+ const dummyTypeObject = types_1.ClassType.createInstantiable('__varianceDummy', '', '', '', 0, 0, undefined, undefined);
10811
+ updatedTypeParams.forEach((param, paramIndex) => {
10812
+ // Skip variadics and ParamSpecs.
10813
+ if (param.details.isVariadic || param.details.isParamSpec) {
10814
+ return;
10815
+ }
10816
+ // Skip type variables without auto-variance.
10817
+ if (param.details.declaredVariance !== 0 /* Auto */) {
10818
+ return;
10819
+ }
10820
+ // Replace all type arguments with a dummy type except for the
10821
+ // TypeVar of interest, which is replaced with an object instance.
10822
+ const srcTypeArgs = updatedTypeParams.map((p, i) => {
10823
+ if (p.details.isVariadic) {
10824
+ return p;
10825
+ }
10826
+ return i === paramIndex ? objectType : dummyTypeObject;
10827
+ });
10828
+ // Replace all type arguments with a dummy type except for the
10829
+ // TypeVar of interest, which is replaced with itself.
10830
+ const destTypeArgs = updatedTypeParams.map((p, i) => {
10831
+ return i === paramIndex || p.details.isVariadic ? p : dummyTypeObject;
10832
+ });
10833
+ const srcType = types_1.ClassType.cloneForSpecialization(updatedClassType, srcTypeArgs,
10834
+ /* isTypeArgumentExplicit */ true);
10835
+ const destType = types_1.ClassType.cloneForSpecialization(updatedClassType, destTypeArgs,
10836
+ /* isTypeArgumentExplicit */ true);
10837
+ const isDestSubtypeOfSrc = assignClassToSelf(srcType, destType);
10838
+ let inferredVariance;
10839
+ if (isDestSubtypeOfSrc) {
10840
+ inferredVariance = 3 /* Covariant */;
10841
+ }
10842
+ else {
10843
+ const isSrcSubtypeOfDest = assignClassToSelf(destType, srcType);
10844
+ if (isSrcSubtypeOfDest) {
10845
+ inferredVariance = 4 /* Contravariant */;
10846
+ }
10847
+ else {
10848
+ inferredVariance = 2 /* Invariant */;
10849
+ }
10850
+ }
10851
+ // We assume here that we don't need to clone the type var object
10852
+ // because it was already cloned when it was associated with this
10853
+ // class scope.
10854
+ classType.details.typeParameters[paramIndex].computedVariance = inferredVariance;
10855
+ });
10856
+ }
10857
+ function evaluateTypeParameterList(node) {
10858
+ const paramTypes = [];
10859
+ node.parameters.forEach((param) => {
10860
+ const paramSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name);
10861
+ (0, debug_1.assert)(paramSymbol);
10862
+ const typeOfParam = getDeclaredTypeOfSymbol(paramSymbol, param.name);
10863
+ if (!typeOfParam || !(0, types_1.isTypeVar)(typeOfParam)) {
10864
+ return;
10865
+ }
10866
+ writeTypeCache(param.name, typeOfParam, 0 /* None */, /* isIncomplete */ false);
10867
+ paramTypes.push(typeOfParam);
10868
+ });
10869
+ return paramTypes;
10870
+ }
10622
10871
  function computeEffectiveMetaclass(classType, errorNode) {
10623
10872
  let effectiveMetaclass = classType.details.declaredMetaclass;
10624
10873
  let reportedMetaclassConflict = false;
@@ -10944,6 +11193,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10944
11193
  }), node.functionAnnotationComment);
10945
11194
  }
10946
11195
  }
11196
+ if (node.typeParameters) {
11197
+ evaluateTypeParameterList(node.typeParameters);
11198
+ }
10947
11199
  const markParamAccessed = (param) => {
10948
11200
  if (param.name) {
10949
11201
  const symbolWithScope = lookUpSymbolRecursive(param.name, param.name.value, /* honorCodeFlow */ false);
@@ -11252,7 +11504,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11252
11504
  const baseClassMemberInfo = (0, typeUtils_1.lookUpClassMember)(containingClassType, methodName, 1 /* SkipOriginalClass */);
11253
11505
  if (baseClassMemberInfo) {
11254
11506
  const memberDecls = baseClassMemberInfo.symbol.getDeclarations();
11255
- if (memberDecls.length === 1 && memberDecls[0].type === 3 /* Function */) {
11507
+ if (memberDecls.length === 1 && memberDecls[0].type === 5 /* Function */) {
11256
11508
  const baseClassMethodNode = memberDecls[0].node;
11257
11509
  // Does the signature match exactly with the exception of annotations?
11258
11510
  if (baseClassMethodNode.parameters.length === functionNode.parameters.length &&
@@ -11529,14 +11781,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11529
11781
  // to recursion if there is a large number (1000's) of overloads.
11530
11782
  for (let i = 0; i < declIndex; i++) {
11531
11783
  const decl = decls[i];
11532
- if (decl.type === 3 /* Function */) {
11784
+ if (decl.type === 5 /* Function */) {
11533
11785
  getTypeOfFunction(decl.node);
11534
11786
  }
11535
11787
  }
11536
11788
  const overloadedTypes = [];
11537
11789
  // Look at the previous declaration's type.
11538
11790
  const prevDecl = decls[declIndex - 1];
11539
- if (prevDecl.type === 3 /* Function */) {
11791
+ if (prevDecl.type === 5 /* Function */) {
11540
11792
  const prevDeclDeclTypeInfo = getTypeOfFunction(prevDecl.node);
11541
11793
  if (prevDeclDeclTypeInfo) {
11542
11794
  if ((0, types_1.isFunction)(prevDeclDeclTypeInfo.decoratedType)) {
@@ -11878,7 +12130,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11878
12130
  }
11879
12131
  // For "async while", an implicit "await" is performed.
11880
12132
  if (isAsync) {
11881
- memberReturnType = getTypeOfAwaitable(memberReturnType, node);
12133
+ memberReturnType = getTypeOfAwaitable(memberReturnType, node.expression);
11882
12134
  }
11883
12135
  return memberReturnType;
11884
12136
  }
@@ -12086,19 +12338,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12086
12338
  // case, we want to choose the last declaration.
12087
12339
  const filteredDecls = symbolWithScope.symbol
12088
12340
  .getDeclarations()
12089
- .filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 6 /* Alias */);
12341
+ .filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 8 /* Alias */);
12090
12342
  let aliasDecl = filteredDecls.length > 0 ? filteredDecls[filteredDecls.length - 1] : undefined;
12091
12343
  // If we didn't find an exact match, look for any alias associated with
12092
12344
  // this symbol. In cases where we have multiple ImportAs nodes that share
12093
12345
  // the same first-part name (e.g. "import asyncio" and "import asyncio.tasks"),
12094
12346
  // we may not find the declaration associated with this node.
12095
12347
  if (!aliasDecl) {
12096
- aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 6 /* Alias */);
12348
+ aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 8 /* Alias */);
12097
12349
  }
12098
12350
  if (!aliasDecl) {
12099
12351
  return undefined;
12100
12352
  }
12101
- (0, debug_1.assert)(aliasDecl.type === 6 /* Alias */);
12353
+ (0, debug_1.assert)(aliasDecl.type === 8 /* Alias */);
12102
12354
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
12103
12355
  // Try to resolve the alias while honoring external visibility.
12104
12356
  const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl,
@@ -12135,7 +12387,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12135
12387
  // expression or statement that contains it. This contextual evaluation
12136
12388
  // allows for bidirectional type evaluation.
12137
12389
  function evaluateTypesForExpressionInContext(node) {
12138
- var _a, _b, _c;
12390
+ var _a, _b, _c, _d, _e;
12139
12391
  let lastContextualExpression = node;
12140
12392
  let curNode = node;
12141
12393
  function isContextual(node) {
@@ -12204,6 +12456,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12204
12456
  getTypeOfClass(node.parent);
12205
12457
  return;
12206
12458
  }
12459
+ else if (node.parent.nodeType === 77 /* TypeAlias */ && node.parent.name === node) {
12460
+ getTypeOfTypeAlias(node.parent);
12461
+ return;
12462
+ }
12207
12463
  else if (node.parent.nodeType === 29 /* Global */ ||
12208
12464
  node.parent.nodeType === 39 /* Nonlocal */) {
12209
12465
  // For global and nonlocal statements, allow forward references so
@@ -12242,15 +12498,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12242
12498
  verifyDeleteExpression(lastContextualExpression);
12243
12499
  return;
12244
12500
  }
12501
+ // If this is the name node within a type parameter list, see if it's a type alias
12502
+ // definition. If so, we need to evaluate the type alias contextually.
12503
+ if (parent.nodeType === 75 /* TypeParameter */ && lastContextualExpression === parent.name) {
12504
+ if (((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 76 /* TypeParameterList */ &&
12505
+ ((_b = parent.parent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 77 /* TypeAlias */) {
12506
+ getTypeOfTypeAlias(parent.parent.parent);
12507
+ return;
12508
+ }
12509
+ }
12510
+ if (parent.nodeType === 75 /* TypeParameter */) {
12511
+ getTypeOfExpression(parent.name);
12512
+ return;
12513
+ }
12514
+ if (parent.nodeType === 77 /* TypeAlias */) {
12515
+ getTypeOfTypeAlias(parent);
12516
+ return;
12517
+ }
12245
12518
  if (parent.nodeType === 5 /* AugmentedAssignment */) {
12246
12519
  evaluateTypesForAugmentedAssignment(parent);
12247
12520
  return;
12248
12521
  }
12249
12522
  if (parent.nodeType === 13 /* Decorator */) {
12250
- if (((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 10 /* Class */) {
12523
+ if (((_c = parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
12251
12524
  getTypeOfClass(parent.parent);
12252
12525
  }
12253
- else if (((_b = parent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 28 /* Function */) {
12526
+ else if (((_d = parent.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 28 /* Function */) {
12254
12527
  getTypeOfFunction(parent.parent);
12255
12528
  }
12256
12529
  return;
@@ -12301,7 +12574,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12301
12574
  return;
12302
12575
  }
12303
12576
  // A class argument must be evaluated in the context of the class declaration.
12304
- if (parent.nodeType === 1 /* Argument */ && ((_c = parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
12577
+ if (parent.nodeType === 1 /* Argument */ && ((_e = parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 10 /* Class */) {
12305
12578
  getTypeOfClass(parent.parent);
12306
12579
  return;
12307
12580
  }
@@ -12397,6 +12670,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12397
12670
  }
12398
12671
  break;
12399
12672
  }
12673
+ case 77 /* TypeAlias */: {
12674
+ getTypeOfTypeAlias(curNode);
12675
+ return;
12676
+ }
12400
12677
  case 4 /* AssignmentExpression */: {
12401
12678
  getTypeOfExpression(curNode);
12402
12679
  return;
@@ -12844,8 +13121,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12844
13121
  return specializedClass;
12845
13122
  }
12846
13123
  function getTypeOfArgument(arg) {
12847
- if (arg.type) {
12848
- return { type: arg.type };
13124
+ if (arg.typeResult) {
13125
+ return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
12849
13126
  }
12850
13127
  if (!arg.valueExpression) {
12851
13128
  // We shouldn't ever get here, but just in case.
@@ -12860,8 +13137,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12860
13137
  // and therefore follows the normal rules of types (e.g. they
12861
13138
  // can be forward-declared in stubs, etc.).
12862
13139
  function getTypeOfArgumentExpectingType(arg) {
12863
- if (arg.type) {
12864
- return { type: arg.type };
13140
+ if (arg.typeResult) {
13141
+ return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
12865
13142
  }
12866
13143
  // If there was no defined type provided, there should always
12867
13144
  // be a value expression from which we can retrieve the type.
@@ -12923,10 +13200,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12923
13200
  if (symbolWithScope && honorCodeFlow && scopeTypeHonorsCodeFlow) {
12924
13201
  // Filter the declarations based on flow reachability.
12925
13202
  const reachableDecls = symbolWithScope.symbol.getDeclarations().filter((decl) => {
12926
- if (decl.type !== 6 /* Alias */ && decl.type !== 0 /* Intrinsic */) {
13203
+ if (decl.type !== 8 /* Alias */ && decl.type !== 0 /* Intrinsic */) {
12927
13204
  // Is the declaration in the same execution scope as the "usageNode" node?
12928
13205
  const usageScope = ParseTreeUtils.getExecutionScopeNode(node);
12929
- const declNode = decl.type === 4 /* Class */ || decl.type === 3 /* Function */
13206
+ const declNode = decl.type === 6 /* Class */ ||
13207
+ decl.type === 5 /* Function */ ||
13208
+ decl.type === 4 /* TypeAlias */
12930
13209
  ? decl.node.name
12931
13210
  : decl.node;
12932
13211
  const declScope = ParseTreeUtils.getExecutionScopeNode(declNode);
@@ -13044,7 +13323,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13044
13323
  if ((0, types_1.isFunction)(type)) {
13045
13324
  if (type.details.declaration) {
13046
13325
  const functionDecl = type.details.declaration;
13047
- if (functionDecl.type === 3 /* Function */) {
13326
+ if (functionDecl.type === 5 /* Function */) {
13048
13327
  const functionNode = functionDecl.node;
13049
13328
  const functionScope = AnalyzerNodeInfo.getScope(functionNode);
13050
13329
  if (functionScope) {
@@ -13108,7 +13387,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13108
13387
  // The alias could have more decls that don't refer to this import. Filter
13109
13388
  // out the one(s) that specifically associated with this import statement.
13110
13389
  const declsForThisImport = symbolInScope.symbol.getDeclarations().filter((decl) => {
13111
- return decl.type === 6 /* Alias */ && decl.node === node.parent;
13390
+ return decl.type === 8 /* Alias */ && decl.node === node.parent;
13112
13391
  });
13113
13392
  (0, collectionUtils_1.appendArray)(declarations, (0, declarationUtils_1.getDeclarationsWithUsesLocalNameRemoved)(declsForThisImport));
13114
13393
  }
@@ -13117,7 +13396,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13117
13396
  else if (node.parent &&
13118
13397
  node.parent.nodeType === 35 /* MemberAccess */ &&
13119
13398
  node === node.parent.memberName) {
13120
- let baseType = getTypeOfExpression(node.parent.leftExpression, 2 /* DoNotSpecialize */).type;
13399
+ let baseType = getType(node.parent.leftExpression);
13121
13400
  if (baseType) {
13122
13401
  baseType = makeTopLevelTypeVarsConcrete(baseType);
13123
13402
  const memberName = node.parent.memberName.value;
@@ -13192,7 +13471,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13192
13471
  const argNode = node.parent;
13193
13472
  const paramName = node.value;
13194
13473
  if (argNode.parent && argNode.parent.nodeType === 9 /* Call */) {
13195
- const baseType = getTypeOfExpression(argNode.parent.leftExpression, 2 /* DoNotSpecialize */).type;
13474
+ const baseType = getType(argNode.parent.leftExpression);
13196
13475
  if (baseType) {
13197
13476
  if ((0, types_1.isFunction)(baseType) && baseType.details.declaration) {
13198
13477
  const paramDecl = getDeclarationFromFunctionNamedParameter(baseType, paramName);
@@ -13232,9 +13511,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13232
13511
  // Determine if this node is within a quoted type annotation.
13233
13512
  const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(AnalyzerNodeInfo.getFileInfo(node)));
13234
13513
  const allowForwardReferences = isWithinTypeAnnotation || fileInfo.isStubFile;
13235
- const symbolWithScope = lookUpSymbolRecursive(node, node.value, !allowForwardReferences, isWithinTypeAnnotation);
13236
- if (symbolWithScope) {
13237
- (0, collectionUtils_1.appendArray)(declarations, symbolWithScope.symbol.getDeclarations());
13514
+ let symbol;
13515
+ const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
13516
+ if (typeParamSymbol) {
13517
+ symbol = typeParamSymbol;
13518
+ }
13519
+ else {
13520
+ const symbolWithScope = lookUpSymbolRecursive(node, node.value, !allowForwardReferences, isWithinTypeAnnotation);
13521
+ symbol = symbolWithScope === null || symbolWithScope === void 0 ? void 0 : symbolWithScope.symbol;
13522
+ }
13523
+ if (symbol) {
13524
+ (0, collectionUtils_1.appendArray)(declarations, symbol.getDeclarations());
13238
13525
  }
13239
13526
  }
13240
13527
  return declarations;
@@ -13280,17 +13567,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13280
13567
  }
13281
13568
  return types_1.UnknownType.create();
13282
13569
  }
13283
- case 4 /* Class */: {
13570
+ case 6 /* Class */: {
13284
13571
  const classTypeInfo = getTypeOfClass(declaration.node);
13285
13572
  return classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.decoratedType;
13286
13573
  }
13287
- case 5 /* SpecialBuiltInClass */: {
13574
+ case 7 /* SpecialBuiltInClass */: {
13288
13575
  return getTypeOfAnnotation(declaration.node.typeAnnotation);
13289
13576
  }
13290
- case 3 /* Function */: {
13577
+ case 5 /* Function */: {
13291
13578
  const functionTypeInfo = getTypeOfFunction(declaration.node);
13292
13579
  return functionTypeInfo === null || functionTypeInfo === void 0 ? void 0 : functionTypeInfo.decoratedType;
13293
13580
  }
13581
+ case 4 /* TypeAlias */: {
13582
+ return getTypeOfTypeAlias(declaration.node);
13583
+ }
13294
13584
  case 2 /* Parameter */: {
13295
13585
  let typeAnnotationNode = declaration.node.typeAnnotation || declaration.node.typeAnnotationComment;
13296
13586
  // If there wasn't an annotation, see if the parent function
@@ -13312,6 +13602,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13312
13602
  }
13313
13603
  return undefined;
13314
13604
  }
13605
+ case 3 /* TypeParameter */: {
13606
+ let typeVar = types_1.TypeVarType.createInstantiable(declaration.node.name.value);
13607
+ if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
13608
+ typeVar.details.isVariadic = true;
13609
+ }
13610
+ else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
13611
+ typeVar.details.isParamSpec = true;
13612
+ }
13613
+ if (declaration.node.boundExpression) {
13614
+ if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
13615
+ const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
13616
+ const constraintType = getTypeOfExpressionExpectingType(constraint).type;
13617
+ if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
13618
+ addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), constraint);
13619
+ }
13620
+ return (0, typeUtils_1.convertToInstance)(constraintType);
13621
+ });
13622
+ if (constraints.length < 2) {
13623
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
13624
+ .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
13625
+ }
13626
+ else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
13627
+ typeVar.details.constraints = constraints;
13628
+ }
13629
+ }
13630
+ else {
13631
+ const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
13632
+ if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
13633
+ addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), declaration.node.boundExpression);
13634
+ }
13635
+ if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
13636
+ typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
13637
+ }
13638
+ }
13639
+ }
13640
+ typeVar.details.isTypeParamSyntax = true;
13641
+ // Associate the type variable with the owning scope.
13642
+ const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
13643
+ if (scopeNode) {
13644
+ let scopeType;
13645
+ if (scopeNode.nodeType === 10 /* Class */) {
13646
+ scopeType = 0 /* Class */;
13647
+ // Set the variance to "auto" for class-scoped TypeVars.
13648
+ typeVar.details.declaredVariance = 0 /* Auto */;
13649
+ }
13650
+ else if (scopeNode.nodeType === 28 /* Function */) {
13651
+ scopeType = 1 /* Function */;
13652
+ }
13653
+ else {
13654
+ (0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
13655
+ scopeType = 2 /* TypeAlias */;
13656
+ }
13657
+ typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
13658
+ }
13659
+ return typeVar;
13660
+ }
13315
13661
  case 1 /* Variable */: {
13316
13662
  const typeAnnotationNode = declaration.typeAnnotationNode;
13317
13663
  if (typeAnnotationNode) {
@@ -13349,7 +13695,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13349
13695
  }
13350
13696
  return undefined;
13351
13697
  }
13352
- case 6 /* Alias */: {
13698
+ case 8 /* Alias */: {
13353
13699
  return undefined;
13354
13700
  }
13355
13701
  }
@@ -13396,11 +13742,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13396
13742
  // If the resolved declaration is still an alias, the alias
13397
13743
  // is pointing at a module, and we need to synthesize a
13398
13744
  // module type.
13399
- if (resolvedDecl.type === 6 /* Alias */) {
13745
+ if (resolvedDecl.type === 8 /* Alias */) {
13400
13746
  // Build a module type that corresponds to the declaration and
13401
13747
  // its associated loader actions.
13402
13748
  let moduleName = resolvedDecl.moduleName;
13403
- if (decl.type === 6 /* Alias */) {
13749
+ if (decl.type === 8 /* Alias */) {
13404
13750
  if (decl.symbolName) {
13405
13751
  moduleName += '.' + decl.symbolName;
13406
13752
  }
@@ -13651,7 +13997,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13651
13997
  considerDecl = false;
13652
13998
  }
13653
13999
  if (usageNode !== undefined) {
13654
- if (decl.type !== 6 /* Alias */) {
14000
+ if (decl.type !== 8 /* Alias */) {
13655
14001
  // Is the declaration in the same execution scope as the "usageNode" node?
13656
14002
  const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
13657
14003
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
@@ -13764,9 +14110,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13764
14110
  // reachable from the usage node (if specified). This can happen in
13765
14111
  // cases where a property symbol is redefined to add a setter, deleter,
13766
14112
  // etc.
13767
- if (typedDecls.length > 1 && usageNode) {
14113
+ if (usageNode && typedDecls.length > 1) {
13768
14114
  const filteredTypedDecls = typedDecls.filter((decl) => {
13769
- if (decl.type !== 6 /* Alias */) {
14115
+ if (decl.type !== 8 /* Alias */) {
13770
14116
  // Is the declaration in the same execution scope as the "usageNode" node?
13771
14117
  const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
13772
14118
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
@@ -13778,9 +14124,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13778
14124
  }
13779
14125
  return true;
13780
14126
  });
13781
- if (filteredTypedDecls.length > 0) {
13782
- typedDecls = filteredTypedDecls;
14127
+ if (filteredTypedDecls.length === 0) {
14128
+ return types_1.UnboundType.create();
13783
14129
  }
14130
+ typedDecls = filteredTypedDecls;
13784
14131
  }
13785
14132
  // Start with the last decl. If that's already being resolved,
13786
14133
  // use the next-to-last decl, etc. This can happen when resolving
@@ -13806,7 +14153,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13806
14153
  // in the type cache. This exception is required to handle the
13807
14154
  // circular dependency between the "type" and "object" classes in
13808
14155
  // builtins.pyi (since "object" is a "type" and "type" is an "object").
13809
- if (popSymbolResolution(symbol) || decl.type === 4 /* Class */) {
14156
+ if (popSymbolResolution(symbol) || decl.type === 6 /* Class */) {
13810
14157
  return type;
13811
14158
  }
13812
14159
  }
@@ -13965,9 +14312,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13965
14312
  if (returnTypeInferenceContextStack.length >= maxReturnTypeInferenceStackSize) {
13966
14313
  return undefined;
13967
14314
  }
14315
+ const paramTypes = [];
14316
+ let isResultFromCache = false;
13968
14317
  // Suppress diagnostics because we don't want to generate errors.
13969
14318
  suppressDiagnostics(functionNode, () => {
13970
- var _a;
14319
+ var _a, _b;
13971
14320
  // Allocate a new temporary type cache for the context of just
13972
14321
  // this function so we can analyze it separately without polluting
13973
14322
  // the main type cache.
@@ -14010,13 +14359,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14010
14359
  if (!paramType) {
14011
14360
  paramType = types_1.UnknownType.create();
14012
14361
  }
14362
+ paramTypes.push(paramType);
14013
14363
  writeTypeCache(param.name, paramType, 0 /* None */, /* isIncomplete */ false);
14014
14364
  }
14015
14365
  });
14016
14366
  // Don't bother trying to determine the contextual return
14017
14367
  // type if none of the argument types are known.
14018
14368
  if (!allArgTypesAreUnknown) {
14019
- contextualReturnType = (_a = inferFunctionReturnType(functionNode, types_1.FunctionType.isAbstractMethod(type))) === null || _a === void 0 ? void 0 : _a.type;
14369
+ // See if the return type is already cached. If so, skip the
14370
+ // inference step, which is potentially very expensive.
14371
+ const cacheEntry = (_a = functionType.functionType.callSiteReturnTypeCache) === null || _a === void 0 ? void 0 : _a.find((entry) => {
14372
+ return (entry.paramTypes.length === paramTypes.length &&
14373
+ entry.paramTypes.every((t, i) => (0, types_1.isTypeSame)(t, paramTypes[i])));
14374
+ });
14375
+ if (cacheEntry) {
14376
+ contextualReturnType = cacheEntry.returnType;
14377
+ isResultFromCache = true;
14378
+ }
14379
+ else {
14380
+ contextualReturnType = (_b = inferFunctionReturnType(functionNode, types_1.FunctionType.isAbstractMethod(type))) === null || _b === void 0 ? void 0 : _b.type;
14381
+ }
14020
14382
  }
14021
14383
  }
14022
14384
  finally {
@@ -14030,6 +14392,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14030
14392
  if (types_1.FunctionType.isWrapReturnTypeInAwait(type) && !(0, types_1.isNever)(contextualReturnType)) {
14031
14393
  contextualReturnType = createAwaitableReturnType(functionNode, contextualReturnType, !!((_a = type.details.declaration) === null || _a === void 0 ? void 0 : _a.isGenerator));
14032
14394
  }
14395
+ if (!isResultFromCache) {
14396
+ // Cache the resulting type.
14397
+ if (!functionType.functionType.callSiteReturnTypeCache) {
14398
+ functionType.functionType.callSiteReturnTypeCache = [];
14399
+ }
14400
+ if (functionType.functionType.callSiteReturnTypeCache.length >= maxCallSiteReturnTypeCacheSize) {
14401
+ functionType.functionType.callSiteReturnTypeCache =
14402
+ functionType.functionType.callSiteReturnTypeCache.slice(1);
14403
+ }
14404
+ functionType.functionType.callSiteReturnTypeCache.push({
14405
+ paramTypes,
14406
+ returnType: contextualReturnType,
14407
+ });
14408
+ }
14033
14409
  return contextualReturnType;
14034
14410
  }
14035
14411
  return undefined;
@@ -14157,6 +14533,63 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14157
14533
  }));
14158
14534
  return false;
14159
14535
  }
14536
+ // This function is used to validate or infer the variance of type
14537
+ // parameters within a class.
14538
+ function assignClassToSelf(destType, srcType, recursionCount = 0) {
14539
+ (0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
14540
+ (0, debug_1.assert)(destType.details.typeParameters.length > 0);
14541
+ const diag = new diagnostic_1.DiagnosticAddendum();
14542
+ const typeVarContext = new typeVarContext_1.TypeVarContext();
14543
+ let isAssignable = true;
14544
+ destType.details.fields.forEach((symbol, name) => {
14545
+ if (isAssignable && symbol.isClassMember() && !symbol.isIgnoredForProtocolMatch()) {
14546
+ const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
14547
+ (0, debug_1.assert)(memberInfo !== undefined);
14548
+ let destMemberType = getDeclaredTypeOfSymbol(symbol);
14549
+ if (destMemberType) {
14550
+ const srcMemberType = getTypeOfMember(memberInfo);
14551
+ destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType);
14552
+ // Properties require special processing.
14553
+ if ((0, types_1.isClassInstance)(destMemberType) &&
14554
+ types_1.ClassType.isPropertyClass(destMemberType) &&
14555
+ (0, types_1.isClassInstance)(srcMemberType) &&
14556
+ types_1.ClassType.isPropertyClass(srcMemberType)) {
14557
+ if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType, diag, typeVarContext,
14558
+ /* selfTypeVarContext */ undefined, recursionCount)) {
14559
+ isAssignable = false;
14560
+ }
14561
+ }
14562
+ else {
14563
+ const primaryDecl = symbol.getDeclarations()[0];
14564
+ // Class and instance variables that are mutable need to
14565
+ // enforce invariance.
14566
+ const flags = (primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* Variable */ && !primaryDecl.isFinal
14567
+ ? 1 /* EnforceInvariance */
14568
+ : 0 /* Default */;
14569
+ if (!assignType(destMemberType, srcMemberType, diag, typeVarContext,
14570
+ /* srcTypeVarContext */ undefined, flags, recursionCount)) {
14571
+ isAssignable = false;
14572
+ }
14573
+ }
14574
+ }
14575
+ }
14576
+ });
14577
+ // Now handle generic base classes.
14578
+ destType.details.baseClasses.forEach((baseClass) => {
14579
+ if ((0, types_1.isInstantiableClass)(baseClass) &&
14580
+ !types_1.ClassType.isBuiltIn(baseClass, 'object') &&
14581
+ !types_1.ClassType.isBuiltIn(baseClass, 'Protocol') &&
14582
+ !types_1.ClassType.isBuiltIn(baseClass, 'Generic') &&
14583
+ baseClass.details.typeParameters.length > 0) {
14584
+ const specializedDestBaseClass = (0, typeUtils_1.specializeForBaseClass)(destType, baseClass);
14585
+ const specializedSrcBaseClass = (0, typeUtils_1.specializeForBaseClass)(srcType, baseClass);
14586
+ if (!assignClassToSelf(specializedDestBaseClass, specializedSrcBaseClass, recursionCount)) {
14587
+ isAssignable = false;
14588
+ }
14589
+ }
14590
+ });
14591
+ return isAssignable;
14592
+ }
14160
14593
  function assignTupleTypeArgs(destType, srcType, diag, typeVarContext, flags, recursionCount) {
14161
14594
  var _a, _b;
14162
14595
  const destTypeArgs = [...((_a = destType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [])];
@@ -14250,6 +14683,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14250
14683
  let curSrcType = srcType;
14251
14684
  let curTypeVarContext = destTypeVarContext !== null && destTypeVarContext !== void 0 ? destTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(destType));
14252
14685
  let effectiveFlags = flags;
14686
+ inferTypeParameterVarianceForClass(destType);
14253
14687
  // If we're using a private typeVarContext, don't skip solving type vars.
14254
14688
  if (!destTypeVarContext) {
14255
14689
  effectiveFlags &= ~8 /* SkipSolveTypeVars */;
@@ -14330,6 +14764,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14330
14764
  function verifyTypeArgumentsAssignable(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
14331
14765
  var _a, _b, _c;
14332
14766
  (0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
14767
+ inferTypeParameterVarianceForClass(destType);
14333
14768
  const destTypeParams = types_1.ClassType.getTypeParameters(destType);
14334
14769
  let destTypeArgs;
14335
14770
  let srcTypeArgs;
@@ -14356,7 +14791,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14356
14791
  const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
14357
14792
  const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
14358
14793
  const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
14359
- if (!destTypeParam || destTypeParam.details.variance === 1 /* Covariant */) {
14794
+ if (!destTypeParam || types_1.TypeVarType.getVariance(destTypeParam) === 3 /* Covariant */) {
14360
14795
  if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
14361
14796
  if (diag) {
14362
14797
  if (destTypeParam) {
@@ -14373,7 +14808,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14373
14808
  return false;
14374
14809
  }
14375
14810
  }
14376
- else if (destTypeParam.details.variance === 2 /* Contravariant */) {
14811
+ else if (types_1.TypeVarType.getVariance(destTypeParam) === 4 /* Contravariant */) {
14377
14812
  if (!assignType(srcTypeArg, destTypeArg, assignmentDiag, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
14378
14813
  if (diag) {
14379
14814
  const childDiag = diag.createAddendum();
@@ -14854,11 +15289,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14854
15289
  // Find first overloaded function that matches the parameters.
14855
15290
  // We don't want to pollute the current typeVarContext, so we'll
14856
15291
  // make a copy of the existing one if it's specified.
14857
- const overloads = concreteSrcType.overloads;
15292
+ const overloads = types_1.OverloadedFunctionType.getOverloads(concreteSrcType);
14858
15293
  const overloadIndex = overloads.findIndex((overload) => {
14859
- if (!types_1.FunctionType.isOverloaded(overload)) {
14860
- return false;
14861
- }
14862
15294
  return assignType(destType, overload, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone(), srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone(), flags, recursionCount);
14863
15295
  });
14864
15296
  if (overloadIndex < 0) {
@@ -14882,10 +15314,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14882
15314
  if ((0, types_1.isOverloadedFunction)(destType)) {
14883
15315
  const overloadDiag = diag === null || diag === void 0 ? void 0 : diag.createAddendum();
14884
15316
  // All overloads in the dest must be assignable.
14885
- const isAssignable = destType.overloads.every((destOverload) => {
14886
- if (!types_1.FunctionType.isOverloaded(destOverload)) {
14887
- return true;
14888
- }
15317
+ const isAssignable = types_1.OverloadedFunctionType.getOverloads(destType).every((destOverload) => {
14889
15318
  if (destTypeVarContext) {
14890
15319
  destTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(destOverload));
14891
15320
  }
@@ -15017,6 +15446,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15017
15446
  }
15018
15447
  // For union sources, all of the types need to be assignable to the dest.
15019
15448
  let isIncompatible = false;
15449
+ // Sort the subtypes so we have a deterministic order for unions.
15020
15450
  (0, typeUtils_1.doForEachSubtype)(srcType, (subtype, subtypeIndex) => {
15021
15451
  if (isIncompatible) {
15022
15452
  return;
@@ -15041,7 +15471,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15041
15471
  isIncompatible = true;
15042
15472
  }
15043
15473
  }
15044
- });
15474
+ },
15475
+ /* sortSubtypes */ true);
15045
15476
  if (isIncompatible) {
15046
15477
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15047
15478
  sourceType: printType(srcType),
@@ -15056,6 +15487,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15056
15487
  // matches for types like `tuple[Any]` and `tuple[int]` from being considered
15057
15488
  // proper subtypes of each other.
15058
15489
  function isProperSubtype(destType, srcType, recursionCount) {
15490
+ // Shortcut the check if either type is Any or Unknown.
15491
+ if ((0, types_1.isAnyOrUnknown)(destType) || (0, types_1.isAnyOrUnknown)(srcType)) {
15492
+ return true;
15493
+ }
15494
+ // Shortcut the check if either type is a class whose hierarchy contains an unknown type.
15495
+ if ((0, types_1.isClass)(destType) && destType.details.mro.some((mro) => (0, types_1.isAnyOrUnknown)(mro))) {
15496
+ return true;
15497
+ }
15498
+ if ((0, types_1.isClass)(srcType) && srcType.details.mro.some((mro) => (0, types_1.isAnyOrUnknown)(mro))) {
15499
+ return true;
15500
+ }
15059
15501
  return (assignType(destType, srcType,
15060
15502
  /* diag */ undefined,
15061
15503
  /* destTypeVarContext */ undefined,
@@ -16005,22 +16447,41 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16005
16447
  return narrowedType;
16006
16448
  }
16007
16449
  function validateOverrideMethod(baseMethod, overrideMethod, diag, enforceParamNames = true) {
16008
- var _a, _b;
16009
- // If we're overriding an overloaded method, uses the implementation.
16010
- if ((0, types_1.isOverloadedFunction)(baseMethod)) {
16011
- const implementation = baseMethod.overloads.find((overload) => !types_1.FunctionType.isOverloaded(overload));
16012
- // If the overloaded method doesn't have an implementation, skip the check.
16013
- if (!implementation) {
16014
- return true;
16015
- }
16016
- baseMethod = implementation;
16017
- }
16018
16450
  // If we're overriding a non-method with a method, report it as an error.
16019
16451
  // This occurs when a non-property overrides a property.
16020
- if (!(0, types_1.isFunction)(baseMethod)) {
16452
+ if (!(0, types_1.isFunction)(baseMethod) && !(0, types_1.isOverloadedFunction)(baseMethod)) {
16021
16453
  diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideType().format({ type: printType(baseMethod) }));
16022
16454
  return false;
16023
16455
  }
16456
+ if ((0, types_1.isFunction)(baseMethod)) {
16457
+ // Handle the easy case - a simple function overriding another simple function.
16458
+ if ((0, types_1.isFunction)(overrideMethod)) {
16459
+ return validateOverrideMethodInternal(baseMethod, overrideMethod, diag, enforceParamNames);
16460
+ }
16461
+ // For an overload overriding a base method, at least one overload
16462
+ // must be compatible with the base method.
16463
+ if (types_1.OverloadedFunctionType.getOverloads(overrideMethod).some((overrideOverload) => {
16464
+ return validateOverrideMethodInternal(baseMethod, overrideOverload,
16465
+ /* diag */ undefined, enforceParamNames);
16466
+ })) {
16467
+ return true;
16468
+ }
16469
+ // Or the implementation must be compatible.
16470
+ const overrideImplementation = types_1.OverloadedFunctionType.getImplementation(overrideMethod);
16471
+ if (overrideImplementation) {
16472
+ if (validateOverrideMethodInternal(baseMethod, overrideImplementation,
16473
+ /* diag */ undefined, enforceParamNames)) {
16474
+ return true;
16475
+ }
16476
+ }
16477
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNoOverloadMatches());
16478
+ return false;
16479
+ }
16480
+ // TODO - need to implement the case where the base method is overloaded
16481
+ return true;
16482
+ }
16483
+ function validateOverrideMethodInternal(baseMethod, overrideMethod, diag, enforceParamNames) {
16484
+ var _a, _b;
16024
16485
  const baseParamDetails = (0, typeUtils_1.getParameterListDetails)(baseMethod);
16025
16486
  const overrideParamDetails = (0, typeUtils_1.getParameterListDetails)(overrideMethod);
16026
16487
  let canOverride = true;
@@ -16028,19 +16489,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16028
16489
  // an incompatible type.
16029
16490
  if (types_1.FunctionType.isStaticMethod(baseMethod)) {
16030
16491
  if (!types_1.FunctionType.isStaticMethod(overrideMethod)) {
16031
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotStaticMethod());
16492
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotStaticMethod());
16032
16493
  canOverride = false;
16033
16494
  }
16034
16495
  }
16035
16496
  else if (types_1.FunctionType.isClassMethod(baseMethod)) {
16036
16497
  if (!types_1.FunctionType.isClassMethod(overrideMethod)) {
16037
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotClassMethod());
16498
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotClassMethod());
16038
16499
  canOverride = false;
16039
16500
  }
16040
16501
  }
16041
16502
  if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
16042
16503
  if (!types_1.FunctionType.isInstanceMethod(overrideMethod)) {
16043
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
16504
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
16044
16505
  canOverride = false;
16045
16506
  }
16046
16507
  }
@@ -16065,7 +16526,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16065
16526
  }
16066
16527
  }
16067
16528
  if (foundParamCountMismatch) {
16068
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overridePositionalParamCount().format({
16529
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overridePositionalParamCount().format({
16069
16530
  baseCount: baseParamDetails.params.length,
16070
16531
  overrideCount: overrideParamDetails.params.length,
16071
16532
  }));
@@ -16092,13 +16553,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16092
16553
  if (overrideParam.category === 0 /* Simple */) {
16093
16554
  if (enforceParamNames) {
16094
16555
  if (overrideParamDetails.params[i].source === typeUtils_1.ParameterSource.PositionOnly) {
16095
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
16556
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
16096
16557
  index: i + 1,
16097
16558
  baseName: baseParam.name || '*',
16098
16559
  }));
16099
16560
  }
16100
16561
  else {
16101
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamName().format({
16562
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamName().format({
16102
16563
  index: i + 1,
16103
16564
  baseName: baseParam.name || '*',
16104
16565
  overrideName: overrideParam.name || '*',
@@ -16110,7 +16571,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16110
16571
  }
16111
16572
  else if (i < overrideParamDetails.positionOnlyParamCount &&
16112
16573
  i >= baseParamDetails.positionOnlyParamCount) {
16113
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
16574
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNamePositionOnly().format({
16114
16575
  index: i + 1,
16115
16576
  baseName: baseParam.name || '*',
16116
16577
  }));
@@ -16123,8 +16584,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16123
16584
  const overrideIsSynthesizedTypeVar = (0, types_1.isTypeVar)(overrideParamType) && overrideParamType.details.isSynthesized;
16124
16585
  if (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar) {
16125
16586
  if (baseParam.category !== overrideParam.category ||
16126
- !assignType(overrideParamType, baseParamType, diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
16127
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
16587
+ !assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
16588
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
16128
16589
  index: i + 1,
16129
16590
  baseType: printType(baseParamType),
16130
16591
  overrideType: printType(overrideParamType),
@@ -16133,7 +16594,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16133
16594
  }
16134
16595
  }
16135
16596
  if (baseParamDetails.params[i].param.hasDefault && !overrideParamDetails.params[i].param.hasDefault) {
16136
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNoDefault().format({
16597
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNoDefault().format({
16137
16598
  index: i + 1,
16138
16599
  }));
16139
16600
  canOverride = false;
@@ -16143,7 +16604,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16143
16604
  // Check for a *args match.
16144
16605
  if (baseParamDetails.argsIndex !== undefined) {
16145
16606
  if (overrideParamDetails.argsIndex === undefined) {
16146
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
16607
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
16147
16608
  name: (_a = baseParamDetails.params[baseParamDetails.argsIndex].param.name) !== null && _a !== void 0 ? _a : '?',
16148
16609
  }));
16149
16610
  canOverride = false;
@@ -16151,9 +16612,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16151
16612
  else {
16152
16613
  const overrideParamType = overrideParamDetails.params[overrideParamDetails.argsIndex].type;
16153
16614
  const baseParamType = baseParamDetails.params[baseParamDetails.argsIndex].type;
16154
- if (!assignType(overrideParamType, baseParamType, diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
16615
+ if (!assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
16155
16616
  /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
16156
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
16617
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
16157
16618
  name: (_b = overrideParamDetails.params[overrideParamDetails.argsIndex].param.name) !== null && _b !== void 0 ? _b : '?',
16158
16619
  baseType: printType(baseParamType),
16159
16620
  overrideType: printType(overrideParamType),
@@ -16171,7 +16632,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16171
16632
  var _a, _b, _c;
16172
16633
  const overrideParamInfo = overrideWkOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
16173
16634
  if (!overrideParamInfo && overrideParamDetails.kwargsIndex === undefined) {
16174
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
16635
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
16175
16636
  name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
16176
16637
  }));
16177
16638
  canOverride = false;
@@ -16181,9 +16642,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16181
16642
  if (!targetParamType) {
16182
16643
  targetParamType = overrideParamDetails.params[overrideParamDetails.kwargsIndex].type;
16183
16644
  }
16184
- if (!assignType(targetParamType, paramInfo.type, diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
16645
+ if (!assignType(targetParamType, paramInfo.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
16185
16646
  /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
16186
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
16647
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
16187
16648
  name: (_b = paramInfo.param.name) !== null && _b !== void 0 ? _b : '?',
16188
16649
  baseType: printType(paramInfo.type),
16189
16650
  overrideType: printType(targetParamType),
@@ -16192,7 +16653,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16192
16653
  }
16193
16654
  if (overrideParamInfo) {
16194
16655
  if (paramInfo.param.hasDefault && !overrideParamInfo.param.hasDefault) {
16195
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordNoDefault().format({
16656
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordNoDefault().format({
16196
16657
  name: (_c = overrideParamInfo.param.name) !== null && _c !== void 0 ? _c : '?',
16197
16658
  }));
16198
16659
  canOverride = false;
@@ -16208,7 +16669,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16208
16669
  if (!baseParamInfo) {
16209
16670
  if (baseParamDetails.kwargsIndex === undefined) {
16210
16671
  if (!paramInfo.param.hasDefault) {
16211
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameExtra().format({
16672
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameExtra().format({
16212
16673
  name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
16213
16674
  }));
16214
16675
  canOverride = false;
@@ -16219,9 +16680,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16219
16680
  // Now check the return type.
16220
16681
  const baseReturnType = getFunctionEffectiveReturnType(baseMethod);
16221
16682
  const overrideReturnType = getFunctionEffectiveReturnType(overrideMethod);
16222
- if (!assignType(baseReturnType, overrideReturnType, diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)),
16683
+ if (!assignType(baseReturnType, overrideReturnType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)),
16223
16684
  /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
16224
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideReturnType().format({
16685
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideReturnType().format({
16225
16686
  baseType: printType(baseReturnType),
16226
16687
  overrideType: printType(overrideReturnType),
16227
16688
  }));
@@ -16347,7 +16808,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16347
16808
  if (symbol.isClassMember() || symbol.isNamedTupleMemberMember()) {
16348
16809
  let isAbstract;
16349
16810
  const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
16350
- if (decl && decl.type === 3 /* Function */) {
16811
+ if (decl && decl.type === 5 /* Function */) {
16351
16812
  const functionFlags = getFunctionFlagsFromDecorators(decl.node, true);
16352
16813
  isAbstract = !!(functionFlags & 8 /* AbstractMethod */);
16353
16814
  }
@@ -16623,6 +17084,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16623
17084
  assignType,
16624
17085
  validateOverrideMethod,
16625
17086
  assignTypeToExpression,
17087
+ assignClassToSelf,
16626
17088
  getTypedDictClassType,
16627
17089
  getTupleClassType,
16628
17090
  getObjectType,
@@ -16630,10 +17092,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16630
17092
  getTypingType,
16631
17093
  verifyTypeArgumentsAssignable,
16632
17094
  inferReturnTypeIfNecessary,
17095
+ inferTypeParameterVarianceForClass,
16633
17096
  addError,
16634
17097
  addWarning,
16635
17098
  addInformation,
16636
17099
  addUnusedCode,
17100
+ addUnreachableCode,
16637
17101
  addDeprecated,
16638
17102
  addDiagnostic,
16639
17103
  addDiagnosticForTextRange,