@zzzen/pyright-internal 1.2.0-dev.20230813 → 1.2.0-dev.20230827

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 (122) hide show
  1. package/dist/analyzer/binder.js +8 -2
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +1 -0
  4. package/dist/analyzer/checker.js +123 -70
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +23 -1
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolver.js +2 -1
  9. package/dist/analyzer/constraintSolver.js.map +1 -1
  10. package/dist/analyzer/constructorTransform.js +1 -1
  11. package/dist/analyzer/constructorTransform.js.map +1 -1
  12. package/dist/analyzer/dataClasses.js +242 -236
  13. package/dist/analyzer/dataClasses.js.map +1 -1
  14. package/dist/analyzer/decorators.js +11 -6
  15. package/dist/analyzer/decorators.js.map +1 -1
  16. package/dist/analyzer/deprecatedSymbols.d.ts +9 -0
  17. package/dist/analyzer/deprecatedSymbols.js +292 -0
  18. package/dist/analyzer/deprecatedSymbols.js.map +1 -0
  19. package/dist/analyzer/docStringConversion.js +7 -1
  20. package/dist/analyzer/docStringConversion.js.map +1 -1
  21. package/dist/analyzer/enums.js +12 -0
  22. package/dist/analyzer/enums.js.map +1 -1
  23. package/dist/analyzer/importResolver.js +8 -1
  24. package/dist/analyzer/importResolver.js.map +1 -1
  25. package/dist/analyzer/namedTuples.js +6 -0
  26. package/dist/analyzer/namedTuples.js.map +1 -1
  27. package/dist/analyzer/operations.d.ts +1 -1
  28. package/dist/analyzer/operations.js +2 -2
  29. package/dist/analyzer/operations.js.map +1 -1
  30. package/dist/analyzer/parameterUtils.d.ts +2 -1
  31. package/dist/analyzer/parameterUtils.js +15 -0
  32. package/dist/analyzer/parameterUtils.js.map +1 -1
  33. package/dist/analyzer/program.d.ts +3 -3
  34. package/dist/analyzer/program.js +5 -9
  35. package/dist/analyzer/program.js.map +1 -1
  36. package/dist/analyzer/protocols.js +14 -0
  37. package/dist/analyzer/protocols.js.map +1 -1
  38. package/dist/analyzer/service.js +2 -2
  39. package/dist/analyzer/service.js.map +1 -1
  40. package/dist/analyzer/sourceFile.js +1 -0
  41. package/dist/analyzer/sourceFile.js.map +1 -1
  42. package/dist/analyzer/typeEvaluator.js +713 -529
  43. package/dist/analyzer/typeEvaluator.js.map +1 -1
  44. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
  45. package/dist/analyzer/typeEvaluatorTypes.js +2 -2
  46. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  47. package/dist/analyzer/typeGuards.js +18 -4
  48. package/dist/analyzer/typeGuards.js.map +1 -1
  49. package/dist/analyzer/typePrinter.js +3 -0
  50. package/dist/analyzer/typePrinter.js.map +1 -1
  51. package/dist/analyzer/typeUtils.d.ts +3 -2
  52. package/dist/analyzer/typeUtils.js +30 -7
  53. package/dist/analyzer/typeUtils.js.map +1 -1
  54. package/dist/analyzer/typeVarContext.js +3 -1
  55. package/dist/analyzer/typeVarContext.js.map +1 -1
  56. package/dist/analyzer/types.d.ts +6 -1
  57. package/dist/analyzer/types.js +20 -0
  58. package/dist/analyzer/types.js.map +1 -1
  59. package/dist/common/cancellationUtils.d.ts +2 -1
  60. package/dist/common/cancellationUtils.js +3 -0
  61. package/dist/common/cancellationUtils.js.map +1 -1
  62. package/dist/common/configOptions.d.ts +1 -0
  63. package/dist/common/configOptions.js +5 -1
  64. package/dist/common/configOptions.js.map +1 -1
  65. package/dist/common/diagnosticRules.d.ts +1 -0
  66. package/dist/common/diagnosticRules.js +1 -0
  67. package/dist/common/diagnosticRules.js.map +1 -1
  68. package/dist/common/serviceProvider.d.ts +4 -3
  69. package/dist/languageServerBase.d.ts +2 -2
  70. package/dist/languageServerBase.js +4 -2
  71. package/dist/languageServerBase.js.map +1 -1
  72. package/dist/languageService/completionProvider.js +9 -3
  73. package/dist/languageService/completionProvider.js.map +1 -1
  74. package/dist/localization/localize.d.ts +25 -4
  75. package/dist/localization/localize.js +8 -2
  76. package/dist/localization/localize.js.map +1 -1
  77. package/dist/localization/package.nls.cs.json +15 -12
  78. package/dist/localization/package.nls.de.json +15 -12
  79. package/dist/localization/package.nls.en-us.json +18 -12
  80. package/dist/localization/package.nls.es.json +15 -12
  81. package/dist/localization/package.nls.fr.json +15 -12
  82. package/dist/localization/package.nls.it.json +15 -12
  83. package/dist/localization/package.nls.ja.json +15 -12
  84. package/dist/localization/package.nls.ko.json +15 -12
  85. package/dist/localization/package.nls.pl.json +15 -12
  86. package/dist/localization/package.nls.pt-br.json +15 -12
  87. package/dist/localization/package.nls.qps-ploc.json +15 -12
  88. package/dist/localization/package.nls.ru.json +15 -12
  89. package/dist/localization/package.nls.tr.json +15 -12
  90. package/dist/localization/package.nls.zh-cn.json +15 -12
  91. package/dist/localization/package.nls.zh-tw.json +14 -11
  92. package/dist/parser/parser.d.ts +1 -0
  93. package/dist/parser/parser.js +80 -18
  94. package/dist/parser/parser.js.map +1 -1
  95. package/dist/parser/tokenizer.d.ts +1 -1
  96. package/dist/parser/tokenizer.js +9 -5
  97. package/dist/parser/tokenizer.js.map +1 -1
  98. package/dist/server.js +1 -1
  99. package/dist/server.js.map +1 -1
  100. package/dist/tests/checker.test.js +34 -13
  101. package/dist/tests/checker.test.js.map +1 -1
  102. package/dist/tests/completions.test.js +39 -2
  103. package/dist/tests/completions.test.js.map +1 -1
  104. package/dist/tests/docStringConversion.test.js +23 -0
  105. package/dist/tests/docStringConversion.test.js.map +1 -1
  106. package/dist/tests/harness/fourslash/testState.d.ts +1 -1
  107. package/dist/tests/harness/fourslash/testState.js +2 -2
  108. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  109. package/dist/tests/typeEvaluator1.test.js +8 -4
  110. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  111. package/dist/tests/typeEvaluator2.test.js +13 -1
  112. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  113. package/dist/tests/typeEvaluator3.test.js +21 -23
  114. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  115. package/dist/tests/typeEvaluator4.test.js +21 -1
  116. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  117. package/dist/tests/typeEvaluator5.test.js +33 -1
  118. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  119. package/dist/workspaceFactory.d.ts +1 -1
  120. package/dist/workspaceFactory.js +3 -3
  121. package/dist/workspaceFactory.js.map +1 -1
  122. package/package.json +1 -1
@@ -47,6 +47,8 @@ const parseNodes_1 = require("../parser/parseNodes");
47
47
  const stringTokenUtils_1 = require("../parser/stringTokenUtils");
48
48
  const AnalyzerNodeInfo = __importStar(require("./analyzerNodeInfo"));
49
49
  const declaration_1 = require("./declaration");
50
+ const declarationUtils_1 = require("./declarationUtils");
51
+ const deprecatedSymbols_1 = require("./deprecatedSymbols");
50
52
  const importResolver_1 = require("./importResolver");
51
53
  const importStatementUtils_1 = require("./importStatementUtils");
52
54
  const parameterUtils_1 = require("./parameterUtils");
@@ -65,43 +67,6 @@ const typeGuards_1 = require("./typeGuards");
65
67
  const typeUtils_1 = require("./typeUtils");
66
68
  const typeVarContext_1 = require("./typeVarContext");
67
69
  const types_1 = require("./types");
68
- const deprecatedAliases = new Map([
69
- ['Tuple', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.tuple', replacementText: 'tuple' }],
70
- ['List', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.list', replacementText: 'list' }],
71
- ['Dict', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.dict', replacementText: 'dict' }],
72
- ['Set', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.set', replacementText: 'set' }],
73
- ['FrozenSet', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.frozenset', replacementText: 'frozenset' }],
74
- ['Type', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'builtins.type', replacementText: 'type' }],
75
- ['Deque', { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'collections.deque', replacementText: 'collections.deque' }],
76
- [
77
- 'DefaultDict',
78
- {
79
- version: pythonVersion_1.PythonVersion.V3_9,
80
- fullName: 'collections.defaultdict',
81
- replacementText: 'collections.defaultdict',
82
- },
83
- ],
84
- [
85
- 'OrderedDict',
86
- {
87
- version: pythonVersion_1.PythonVersion.V3_9,
88
- fullName: 'collections.OrderedDict',
89
- replacementText: 'collections.OrderedDict',
90
- },
91
- ],
92
- [
93
- 'Counter',
94
- { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'collections.Counter', replacementText: 'collections.Counter' },
95
- ],
96
- [
97
- 'ChainMap',
98
- { version: pythonVersion_1.PythonVersion.V3_9, fullName: 'collections.ChainMap', replacementText: 'collections.ChainMap' },
99
- ],
100
- ]);
101
- const deprecatedSpecialForms = new Map([
102
- ['Optional', { version: pythonVersion_1.PythonVersion.V3_10, fullName: 'typing.Optional', replacementText: '| None' }],
103
- ['Union', { version: pythonVersion_1.PythonVersion.V3_10, fullName: 'typing.Union', replacementText: '|' }],
104
- ]);
105
70
  // When enabled, this debug flag causes the code complexity of
106
71
  // functions to be emitted.
107
72
  const isPrintCodeComplexityEnabled = false;
@@ -211,6 +176,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
211
176
  this._validateBaseClassOverrides(classTypeResult.classType);
212
177
  this._validateSlotsClassVarConflict(classTypeResult.classType);
213
178
  }
179
+ this._validateMultipleInheritanceBaseClasses(classTypeResult.classType, node.name);
214
180
  this._validateMultipleInheritanceCompatibility(classTypeResult.classType, node.name);
215
181
  this._validateConstructorConsistency(classTypeResult.classType);
216
182
  this._validateFinalMemberOverrides(classTypeResult.classType);
@@ -339,12 +305,14 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
339
305
  if (param.typeAnnotationComment) {
340
306
  this.walk(param.typeAnnotationComment);
341
307
  }
308
+ // Look for method parameters that are typed with TypeVars that have the wrong variance.
342
309
  if (functionTypeResult) {
343
310
  const annotationNode = param.typeAnnotation || param.typeAnnotationComment;
344
311
  if (annotationNode && index < functionTypeResult.functionType.details.parameters.length) {
345
312
  const paramType = functionTypeResult.functionType.details.parameters[index].type;
346
313
  const exemptMethods = ['__init__', '__new__'];
347
- if ((0, types_1.isTypeVar)(paramType) &&
314
+ if (containingClassNode &&
315
+ (0, types_1.isTypeVar)(paramType) &&
348
316
  paramType.details.declaredVariance === 3 /* Covariant */ &&
349
317
  !paramType.details.isSynthesized &&
350
318
  !exemptMethods.some((name) => name === functionTypeResult.functionType.details.name)) {
@@ -629,6 +597,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
629
597
  var _a, _b, _c, _d;
630
598
  const yieldFromType = this._evaluator.getType(node.expression) || types_1.UnknownType.create();
631
599
  let yieldType;
600
+ let sendType;
632
601
  if ((0, types_1.isClassInstance)(yieldFromType) && types_1.ClassType.isBuiltIn(yieldFromType, 'Coroutine')) {
633
602
  // Handle the case of old-style (pre-await) coroutines.
634
603
  yieldType = types_1.UnknownType.create();
@@ -642,13 +611,14 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
642
611
  const generatorTypeArgs = (0, typeUtils_1.getGeneratorTypeArgs)(yieldType);
643
612
  if (generatorTypeArgs) {
644
613
  yieldType = generatorTypeArgs.length >= 1 ? generatorTypeArgs[0] : types_1.UnknownType.create();
614
+ sendType = generatorTypeArgs.length >= 2 ? generatorTypeArgs[1] : undefined;
645
615
  }
646
616
  else {
647
617
  yieldType =
648
618
  (_d = (_c = this._evaluator.getTypeOfIterator({ type: yieldFromType }, /* isAsync */ false, node)) === null || _c === void 0 ? void 0 : _c.type) !== null && _d !== void 0 ? _d : types_1.UnknownType.create();
649
619
  }
650
620
  }
651
- this._validateYieldType(node, yieldType);
621
+ this._validateYieldType(node, yieldType, sendType);
652
622
  return true;
653
623
  }
654
624
  visitRaise(node) {
@@ -930,7 +900,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
930
900
  }
931
901
  visitMemberAccess(node) {
932
902
  const type = this._evaluator.getType(node);
933
- this._reportDeprecatedUse(node.memberName, type);
903
+ const leftExprType = this._evaluator.getType(node.leftExpression);
904
+ this._reportDeprecatedUse(node.memberName, type, leftExprType && (0, types_1.isModule)(leftExprType) && leftExprType.moduleName === 'typing');
934
905
  this._conditionallyReportPrivateUsage(node.memberName);
935
906
  // Walk the leftExpression but not the memberName.
936
907
  this.walk(node.leftExpression);
@@ -957,6 +928,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
957
928
  });
958
929
  }
959
930
  else {
931
+ this._evaluator.evaluateTypesForStatement(node);
960
932
  const importInfo = AnalyzerNodeInfo.getImportInfo(node.module);
961
933
  if (importInfo &&
962
934
  importInfo.isImportFound &&
@@ -968,7 +940,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
968
940
  return true;
969
941
  }
970
942
  visitImportFromAs(node) {
971
- var _a;
943
+ var _a, _b;
972
944
  if (this._fileInfo.isStubFile) {
973
945
  return false;
974
946
  }
@@ -992,8 +964,16 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
992
964
  this._addMissingModuleSourceDiagnosticIfNeeded(importResult, node.name);
993
965
  break;
994
966
  }
995
- const type = this._evaluator.getType((_a = node.alias) !== null && _a !== void 0 ? _a : node.name);
996
- this._reportDeprecatedUse(node.name, type);
967
+ let isImportFromTyping = false;
968
+ if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 22 /* ImportFrom */) {
969
+ if (node.parent.module.leadingDots === 0 && node.parent.module.nameParts.length === 1) {
970
+ if (node.parent.module.nameParts[0].value === 'typing') {
971
+ isImportFromTyping = true;
972
+ }
973
+ }
974
+ }
975
+ const type = this._evaluator.getType((_b = node.alias) !== null && _b !== void 0 ? _b : node.name);
976
+ this._reportDeprecatedUse(node.name, type, isImportFromTyping);
997
977
  return false;
998
978
  }
999
979
  visitModuleName(node) {
@@ -1928,17 +1908,25 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
1928
1908
  implementationFunction = type;
1929
1909
  }
1930
1910
  if (!implementationFunction) {
1931
- let isProtocolMethod = false;
1911
+ let exemptMissingImplementation = false;
1932
1912
  const containingClassNode = ParseTreeUtils.getEnclosingClassOrFunction(primaryDecl.node);
1933
1913
  if (containingClassNode && containingClassNode.nodeType === 10 /* Class */) {
1934
1914
  const classType = this._evaluator.getTypeOfClass(containingClassNode);
1935
- if (classType && types_1.ClassType.isProtocolClass(classType.classType)) {
1936
- isProtocolMethod = true;
1915
+ if (classType) {
1916
+ if (types_1.ClassType.isProtocolClass(classType.classType)) {
1917
+ exemptMissingImplementation = true;
1918
+ }
1919
+ else if (types_1.ClassType.supportsAbstractMethods(classType.classType)) {
1920
+ if ((0, types_1.isOverloadedFunction)(type) &&
1921
+ types_1.OverloadedFunctionType.getOverloads(type).every((overload) => types_1.FunctionType.isAbstractMethod(overload))) {
1922
+ exemptMissingImplementation = true;
1923
+ }
1924
+ }
1937
1925
  }
1938
1926
  }
1939
1927
  // If this is a method within a protocol class, don't require that
1940
1928
  // there is an implementation.
1941
- if (!isProtocolMethod) {
1929
+ if (!exemptMissingImplementation) {
1942
1930
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadWithoutImplementation().format({
1943
1931
  name: primaryDecl.node.name.value,
1944
1932
  }), primaryDecl.node.name);
@@ -2632,8 +2620,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2632
2620
  }
2633
2621
  return false;
2634
2622
  }
2635
- _reportDeprecatedUse(node, type) {
2636
- var _a;
2623
+ _reportDeprecatedUse(node, type, isImportFromTyping = false) {
2624
+ var _a, _b;
2637
2625
  if (!type) {
2638
2626
  return;
2639
2627
  }
@@ -2710,24 +2698,25 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
2710
2698
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportDeprecated, diagnosticRules_1.DiagnosticRule.reportDeprecated, errorMessage + diag.getString(), node);
2711
2699
  }
2712
2700
  }
2713
- // We'll leave this disabled for now because this would be too noisy for most
2714
- // code bases. We may want to add it at some future date.
2715
- if (0) {
2716
- const deprecatedForm = (_a = deprecatedAliases.get(node.value)) !== null && _a !== void 0 ? _a : deprecatedSpecialForms.get(node.value);
2701
+ if (this._fileInfo.diagnosticRuleSet.deprecateTypingAliases) {
2702
+ const deprecatedForm = (_a = deprecatedSymbols_1.deprecatedAliases.get(node.value)) !== null && _a !== void 0 ? _a : deprecatedSymbols_1.deprecatedSpecialForms.get(node.value);
2717
2703
  if (deprecatedForm) {
2718
- if ((0, types_1.isInstantiableClass)(type) && type.details.fullName === deprecatedForm.fullName) {
2704
+ if (((0, types_1.isInstantiableClass)(type) && type.details.fullName === deprecatedForm.fullName) ||
2705
+ ((_b = type.typeAliasInfo) === null || _b === void 0 ? void 0 : _b.fullName) === deprecatedForm.fullName) {
2719
2706
  if (this._fileInfo.executionEnvironment.pythonVersion >= deprecatedForm.version) {
2720
- if (this._fileInfo.diagnosticRuleSet.reportDeprecated === 'none') {
2721
- this._evaluator.addDeprecated(localize_1.Localizer.Diagnostic.deprecatedType().format({
2722
- version: (0, pythonVersion_1.versionToString)(deprecatedForm.version),
2723
- replacement: deprecatedForm.replacementText,
2724
- }), node);
2725
- }
2726
- else {
2727
- this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportDeprecated, diagnosticRules_1.DiagnosticRule.reportDeprecated, localize_1.Localizer.Diagnostic.deprecatedType().format({
2728
- version: (0, pythonVersion_1.versionToString)(deprecatedForm.version),
2729
- replacement: deprecatedForm.replacementText,
2730
- }), node);
2707
+ if (!deprecatedForm.typingImportOnly || isImportFromTyping) {
2708
+ if (this._fileInfo.diagnosticRuleSet.reportDeprecated === 'none') {
2709
+ this._evaluator.addDeprecated(localize_1.Localizer.Diagnostic.deprecatedType().format({
2710
+ version: (0, pythonVersion_1.versionToString)(deprecatedForm.version),
2711
+ replacement: deprecatedForm.replacementText,
2712
+ }), node);
2713
+ }
2714
+ else {
2715
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportDeprecated, diagnosticRules_1.DiagnosticRule.reportDeprecated, localize_1.Localizer.Diagnostic.deprecatedType().format({
2716
+ version: (0, pythonVersion_1.versionToString)(deprecatedForm.version),
2717
+ replacement: deprecatedForm.replacementText,
2718
+ }), node);
2719
+ }
2731
2720
  }
2732
2721
  }
2733
2722
  }
@@ -3611,6 +3600,68 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
3611
3600
  }
3612
3601
  }
3613
3602
  }
3603
+ // Verifies that classes that have more than one base class do not have
3604
+ // have conflicting type arguments.
3605
+ _validateMultipleInheritanceBaseClasses(classType, errorNode) {
3606
+ // Skip this check if the class has only one base class or one or more
3607
+ // of the base classes are Any.
3608
+ const filteredBaseClasses = [];
3609
+ for (const baseClass of classType.details.baseClasses) {
3610
+ if (!(0, types_1.isClass)(baseClass)) {
3611
+ return;
3612
+ }
3613
+ if (!types_1.ClassType.isBuiltIn(baseClass, ['Generic', 'Protocol', 'object'])) {
3614
+ filteredBaseClasses.push(baseClass);
3615
+ }
3616
+ }
3617
+ if (filteredBaseClasses.length < 2) {
3618
+ return;
3619
+ }
3620
+ const diagAddendum = new diagnostic_1.DiagnosticAddendum();
3621
+ for (const baseClass of filteredBaseClasses) {
3622
+ const typeVarContext = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(baseClass);
3623
+ for (const baseClassMroClass of baseClass.details.mro) {
3624
+ // There's no need to check for conflicts if this class isn't generic.
3625
+ if ((0, types_1.isClass)(baseClassMroClass) && baseClassMroClass.details.typeParameters.length > 0) {
3626
+ const specializedBaseClassMroClass = (0, typeUtils_1.applySolvedTypeVars)(baseClassMroClass, typeVarContext);
3627
+ // Find the corresponding class in the derived class's MRO list.
3628
+ const matchingMroClass = classType.details.mro.find((mroClass) => (0, types_1.isClass)(mroClass) && types_1.ClassType.isSameGenericClass(mroClass, specializedBaseClassMroClass));
3629
+ if (matchingMroClass && (0, types_1.isInstantiableClass)(matchingMroClass)) {
3630
+ const matchingMroObject = types_1.ClassType.cloneAsInstance(matchingMroClass);
3631
+ const baseClassMroObject = types_1.ClassType.cloneAsInstance(specializedBaseClassMroClass);
3632
+ // If the types match exactly, we can shortcut the remainder of the MRO chain.
3633
+ // if (isTypeSame(matchingMroObject, baseClassMroObject)) {
3634
+ // break;
3635
+ // }
3636
+ if (!this._evaluator.assignType(matchingMroObject, baseClassMroObject)) {
3637
+ const diag = new diagnostic_1.DiagnosticAddendum();
3638
+ const baseClassObject = (0, typeUtils_1.convertToInstance)(baseClass);
3639
+ if ((0, types_1.isTypeSame)(baseClassObject, baseClassMroObject)) {
3640
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.baseClassIncompatible().format({
3641
+ baseClass: this._evaluator.printType(baseClassObject),
3642
+ type: this._evaluator.printType(matchingMroObject),
3643
+ }));
3644
+ }
3645
+ else {
3646
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.baseClassIncompatibleSubclass().format({
3647
+ baseClass: this._evaluator.printType(baseClassObject),
3648
+ subclass: this._evaluator.printType(baseClassMroObject),
3649
+ type: this._evaluator.printType(matchingMroObject),
3650
+ }));
3651
+ }
3652
+ diagAddendum.addAddendum(diag);
3653
+ // Break out of the inner loop so we don't report any redundant errors for this base class.
3654
+ break;
3655
+ }
3656
+ }
3657
+ }
3658
+ }
3659
+ }
3660
+ if (!diagAddendum.isEmpty()) {
3661
+ this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassIncompatible().format({ type: classType.details.name }) +
3662
+ diagAddendum.getString(), errorNode);
3663
+ }
3664
+ }
3614
3665
  // Validates that any methods and variables in multiple base classes are
3615
3666
  // compatible with each other.
3616
3667
  _validateMultipleInheritanceCompatibility(classType, errorNode) {
@@ -3888,10 +3939,11 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
3888
3939
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overriddenMethodNotFound().format({ name: funcNode.name.value }), funcNode.name);
3889
3940
  }
3890
3941
  _validateBaseClassOverride(baseClassAndSymbol, overrideSymbol, overrideType, childClassType, memberName) {
3942
+ var _a, _b;
3891
3943
  if (!(0, types_1.isInstantiableClass)(baseClassAndSymbol.classType)) {
3892
3944
  return;
3893
3945
  }
3894
- if (baseClassAndSymbol.symbol.isIgnoredForOverrideChecks()) {
3946
+ if (baseClassAndSymbol.symbol.isIgnoredForOverrideChecks() || overrideSymbol.isIgnoredForOverrideChecks()) {
3895
3947
  return;
3896
3948
  }
3897
3949
  // If the base class doesn't provide a type declaration, we won't bother
@@ -4051,7 +4103,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4051
4103
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, localize_1.Localizer.Diagnostic.symbolOverridden().format({
4052
4104
  name: memberName,
4053
4105
  className: baseClassAndSymbol.classType.details.name,
4054
- }) + diagAddendum.getString(), lastDecl.node);
4106
+ }) + diagAddendum.getString(), (_a = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _a !== void 0 ? _a : lastDecl.node);
4055
4107
  const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4056
4108
  if (diag && origDecl) {
4057
4109
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
@@ -4093,7 +4145,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4093
4145
  const diag = this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportIncompatibleVariableOverride, diagnosticRules_1.DiagnosticRule.reportIncompatibleVariableOverride, unformattedMessage.format({
4094
4146
  name: memberName,
4095
4147
  className: baseClassAndSymbol.classType.details.name,
4096
- }), lastDecl.node);
4148
+ }), (_b = (0, declarationUtils_1.getNameNodeForDeclaration)(lastDecl)) !== null && _b !== void 0 ? _b : lastDecl.node);
4097
4149
  const origDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(baseClassAndSymbol.symbol);
4098
4150
  if (diag && origDecl) {
4099
4151
  diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.overriddenSymbol(), origDecl.path, origDecl.range);
@@ -4336,7 +4388,7 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4336
4388
  }
4337
4389
  // Determines whether a yield or yield from node is compatible with the
4338
4390
  // return type annotation of the containing function.
4339
- _validateYieldType(node, yieldType) {
4391
+ _validateYieldType(node, yieldType, sendType) {
4340
4392
  var _a;
4341
4393
  const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(node);
4342
4394
  if (!enclosingFunctionNode || !enclosingFunctionNode.returnTypeAnnotation) {
@@ -4371,7 +4423,8 @@ class Checker extends parseTreeWalker_1.ParseTreeWalker {
4371
4423
  this._evaluator.addDiagnostic(this._fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.noReturnContainsYield(), node);
4372
4424
  return;
4373
4425
  }
4374
- const specializedGenerator = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForSpecialization(generatorType, [yieldType], /* isTypeArgumentExplicit */ true));
4426
+ const generatorTypeArgs = [yieldType, sendType !== null && sendType !== void 0 ? sendType : types_1.UnknownType.create(), types_1.UnknownType.create()];
4427
+ const specializedGenerator = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForSpecialization(generatorType, generatorTypeArgs, /* isTypeArgumentExplicit */ true));
4375
4428
  const diagAddendum = new diagnostic_1.DiagnosticAddendum();
4376
4429
  if (!this._evaluator.assignType(declaredReturnType, specializedGenerator, diagAddendum)) {
4377
4430
  const errorMessage = enclosingFunctionNode.isAsync