@zzzen/pyright-internal 1.2.0-dev.20230820 → 1.2.0-dev.20230903

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 (176) hide show
  1. package/dist/analyzer/binder.js +4 -1
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.js +47 -64
  4. package/dist/analyzer/checker.js.map +1 -1
  5. package/dist/analyzer/codeFlowEngine.js +24 -3
  6. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  7. package/dist/analyzer/constraintSolver.js +2 -1
  8. package/dist/analyzer/constraintSolver.js.map +1 -1
  9. package/dist/analyzer/constructorTransform.js +1 -1
  10. package/dist/analyzer/constructorTransform.js.map +1 -1
  11. package/dist/analyzer/decorators.js +11 -6
  12. package/dist/analyzer/decorators.js.map +1 -1
  13. package/dist/analyzer/deprecatedSymbols.d.ts +9 -0
  14. package/dist/analyzer/deprecatedSymbols.js +303 -0
  15. package/dist/analyzer/deprecatedSymbols.js.map +1 -0
  16. package/dist/analyzer/docStringConversion.js +7 -1
  17. package/dist/analyzer/docStringConversion.js.map +1 -1
  18. package/dist/analyzer/importResolver.d.ts +6 -4
  19. package/dist/analyzer/importResolver.js +21 -11
  20. package/dist/analyzer/importResolver.js.map +1 -1
  21. package/dist/analyzer/namedTuples.js +1 -1
  22. package/dist/analyzer/namedTuples.js.map +1 -1
  23. package/dist/analyzer/packageTypeVerifier.d.ts +3 -3
  24. package/dist/analyzer/packageTypeVerifier.js +8 -11
  25. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  26. package/dist/analyzer/program.d.ts +10 -23
  27. package/dist/analyzer/program.js +94 -92
  28. package/dist/analyzer/program.js.map +1 -1
  29. package/dist/analyzer/protocols.js +3 -1
  30. package/dist/analyzer/protocols.js.map +1 -1
  31. package/dist/analyzer/service.d.ts +6 -3
  32. package/dist/analyzer/service.js +26 -8
  33. package/dist/analyzer/service.js.map +1 -1
  34. package/dist/analyzer/sourceFile.d.ts +6 -4
  35. package/dist/analyzer/sourceFile.js +10 -16
  36. package/dist/analyzer/sourceFile.js.map +1 -1
  37. package/dist/analyzer/sourceFileInfo.d.ts +62 -0
  38. package/dist/analyzer/sourceFileInfo.js +145 -0
  39. package/dist/analyzer/sourceFileInfo.js.map +1 -0
  40. package/dist/analyzer/sourceMapper.d.ts +1 -1
  41. package/dist/analyzer/typeEvaluator.js +729 -592
  42. package/dist/analyzer/typeEvaluator.js.map +1 -1
  43. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -0
  44. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  45. package/dist/analyzer/typeGuards.js +93 -18
  46. package/dist/analyzer/typeGuards.js.map +1 -1
  47. package/dist/analyzer/typeUtils.d.ts +2 -2
  48. package/dist/analyzer/typeUtils.js +32 -13
  49. package/dist/analyzer/typeUtils.js.map +1 -1
  50. package/dist/analyzer/typeVarContext.js +3 -1
  51. package/dist/analyzer/typeVarContext.js.map +1 -1
  52. package/dist/analyzer/typeWalker.js +1 -1
  53. package/dist/analyzer/typeWalker.js.map +1 -1
  54. package/dist/analyzer/types.d.ts +6 -1
  55. package/dist/analyzer/types.js +19 -0
  56. package/dist/analyzer/types.js.map +1 -1
  57. package/dist/backgroundAnalysis.d.ts +1 -2
  58. package/dist/backgroundAnalysis.js +2 -2
  59. package/dist/backgroundAnalysis.js.map +1 -1
  60. package/dist/backgroundAnalysisBase.d.ts +1 -2
  61. package/dist/backgroundAnalysisBase.js +4 -4
  62. package/dist/backgroundAnalysisBase.js.map +1 -1
  63. package/dist/backgroundThreadBase.d.ts +1 -1
  64. package/dist/backgroundThreadBase.js +1 -0
  65. package/dist/backgroundThreadBase.js.map +1 -1
  66. package/dist/common/cancellationUtils.d.ts +2 -1
  67. package/dist/common/cancellationUtils.js +3 -0
  68. package/dist/common/cancellationUtils.js.map +1 -1
  69. package/dist/common/commandLineOptions.d.ts +1 -0
  70. package/dist/common/commandLineOptions.js.map +1 -1
  71. package/dist/common/configOptions.d.ts +5 -1
  72. package/dist/common/configOptions.js +21 -4
  73. package/dist/common/configOptions.js.map +1 -1
  74. package/dist/common/console.d.ts +3 -0
  75. package/dist/common/console.js +8 -1
  76. package/dist/common/console.js.map +1 -1
  77. package/dist/common/diagnosticRules.d.ts +1 -0
  78. package/dist/common/diagnosticRules.js +1 -0
  79. package/dist/common/diagnosticRules.js.map +1 -1
  80. package/dist/common/extensibility.d.ts +4 -1
  81. package/dist/common/extensibility.js.map +1 -1
  82. package/dist/common/fileSystem.d.ts +3 -0
  83. package/dist/common/fileSystem.js +8 -1
  84. package/dist/common/fileSystem.js.map +1 -1
  85. package/dist/common/serviceProvider.d.ts +1 -4
  86. package/dist/common/serviceProvider.js +4 -4
  87. package/dist/common/serviceProvider.js.map +1 -1
  88. package/dist/common/serviceProviderExtensions.d.ts +10 -4
  89. package/dist/common/serviceProviderExtensions.js +43 -1
  90. package/dist/common/serviceProviderExtensions.js.map +1 -1
  91. package/dist/languageServerBase.d.ts +8 -8
  92. package/dist/languageServerBase.js +3 -2
  93. package/dist/languageServerBase.js.map +1 -1
  94. package/dist/languageService/analyzerServiceExecutor.js +3 -2
  95. package/dist/languageService/analyzerServiceExecutor.js.map +1 -1
  96. package/dist/languageService/completionProvider.d.ts +4 -3
  97. package/dist/languageService/completionProvider.js +187 -173
  98. package/dist/languageService/completionProvider.js.map +1 -1
  99. package/dist/languageService/completionProviderUtils.d.ts +1 -1
  100. package/dist/languageService/completionProviderUtils.js +1 -1
  101. package/dist/languageService/completionProviderUtils.js.map +1 -1
  102. package/dist/localization/localize.d.ts +8 -0
  103. package/dist/localization/localize.js +2 -0
  104. package/dist/localization/localize.js.map +1 -1
  105. package/dist/localization/package.nls.cs.json +15 -10
  106. package/dist/localization/package.nls.de.json +11 -6
  107. package/dist/localization/package.nls.en-us.json +6 -4
  108. package/dist/localization/package.nls.es.json +16 -11
  109. package/dist/localization/package.nls.fr.json +17 -12
  110. package/dist/localization/package.nls.it.json +17 -12
  111. package/dist/localization/package.nls.ja.json +11 -6
  112. package/dist/localization/package.nls.ko.json +15 -10
  113. package/dist/localization/package.nls.pl.json +14 -9
  114. package/dist/localization/package.nls.pt-br.json +18 -13
  115. package/dist/localization/package.nls.qps-ploc.json +18 -13
  116. package/dist/localization/package.nls.ru.json +15 -10
  117. package/dist/localization/package.nls.tr.json +11 -6
  118. package/dist/localization/package.nls.zh-cn.json +14 -9
  119. package/dist/localization/package.nls.zh-tw.json +11 -6
  120. package/dist/parser/parser.js +2 -0
  121. package/dist/parser/parser.js.map +1 -1
  122. package/dist/parser/tokenizer.d.ts +1 -1
  123. package/dist/parser/tokenizer.js +9 -5
  124. package/dist/parser/tokenizer.js.map +1 -1
  125. package/dist/pyright.js +6 -4
  126. package/dist/pyright.js.map +1 -1
  127. package/dist/server.d.ts +2 -2
  128. package/dist/server.js +6 -9
  129. package/dist/server.js.map +1 -1
  130. package/dist/tests/chainedSourceFiles.test.js +4 -1
  131. package/dist/tests/chainedSourceFiles.test.js.map +1 -1
  132. package/dist/tests/checker.test.js +34 -13
  133. package/dist/tests/checker.test.js.map +1 -1
  134. package/dist/tests/completions.test.js +69 -2
  135. package/dist/tests/completions.test.js.map +1 -1
  136. package/dist/tests/config.test.js +23 -17
  137. package/dist/tests/config.test.js.map +1 -1
  138. package/dist/tests/docStringConversion.test.js +23 -0
  139. package/dist/tests/docStringConversion.test.js.map +1 -1
  140. package/dist/tests/fourslash/diagnostics.missingModuleSource.fourslash.js +8 -8
  141. package/dist/tests/fourslash/diagnostics.missingModuleSource.fourslash.js.map +1 -1
  142. package/dist/tests/fourslash/importnotresolved.fourslash.js +2 -2
  143. package/dist/tests/fourslash/importnotresolved.fourslash.js.map +1 -1
  144. package/dist/tests/fourslash/missingModuleSource.fourslash.js +4 -1
  145. package/dist/tests/fourslash/missingModuleSource.fourslash.js.map +1 -1
  146. package/dist/tests/harness/fourslash/testLanguageService.js +4 -1
  147. package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
  148. package/dist/tests/harness/fourslash/testState.d.ts +2 -0
  149. package/dist/tests/harness/fourslash/testState.js +5 -1
  150. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  151. package/dist/tests/importResolver.test.js +14 -9
  152. package/dist/tests/importResolver.test.js.map +1 -1
  153. package/dist/tests/localizer.test.js +1 -1
  154. package/dist/tests/localizer.test.js.map +1 -1
  155. package/dist/tests/service.test.js +55 -0
  156. package/dist/tests/service.test.js.map +1 -1
  157. package/dist/tests/sourceFile.test.js +4 -2
  158. package/dist/tests/sourceFile.test.js.map +1 -1
  159. package/dist/tests/testUtils.js +3 -5
  160. package/dist/tests/testUtils.js.map +1 -1
  161. package/dist/tests/typeEvaluator1.test.js +6 -2
  162. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  163. package/dist/tests/typeEvaluator2.test.js +9 -1
  164. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  165. package/dist/tests/typeEvaluator3.test.js +17 -23
  166. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  167. package/dist/tests/typeEvaluator4.test.js +12 -0
  168. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  169. package/dist/tests/typeEvaluator5.test.js +24 -0
  170. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  171. package/dist/tests/workspaceEditUtils.test.js +24 -20
  172. package/dist/tests/workspaceEditUtils.test.js.map +1 -1
  173. package/dist/workspaceFactory.d.ts +2 -1
  174. package/dist/workspaceFactory.js +15 -6
  175. package/dist/workspaceFactory.js.map +1 -1
  176. package/package.json +1 -1
@@ -683,6 +683,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
683
683
  }
684
684
  return typeResult;
685
685
  }
686
+ // Reports the case where a function or class has been decorated with
687
+ // @type_check_only and is used in a value expression.
688
+ function reportUseOfTypeCheckOnly(type, node) {
689
+ let isTypeCheckingOnly = false;
690
+ let name = '';
691
+ if ((0, types_1.isInstantiableClass)(type) && !type.includeSubclasses) {
692
+ isTypeCheckingOnly = types_1.ClassType.isTypeCheckOnly(type);
693
+ name = type.details.name;
694
+ }
695
+ else if ((0, types_1.isFunction)(type)) {
696
+ isTypeCheckingOnly = types_1.FunctionType.isTypeCheckOnly(type);
697
+ name = type.details.name;
698
+ }
699
+ if (isTypeCheckingOnly) {
700
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
701
+ if (!fileInfo.isStubFile) {
702
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeCheckOnly().format({ name }), node);
703
+ }
704
+ }
705
+ }
686
706
  function reportInvalidUseOfPep695TypeAlias(type, node) {
687
707
  var _a;
688
708
  // PEP 695 type aliases cannot be used as instantiable classes.
@@ -866,13 +886,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
866
886
  function getTypeOfString(node) {
867
887
  const isBytes = (node.token.flags & 32 /* Bytes */) !== 0;
868
888
  let typeResult;
889
+ let isIncomplete = false;
869
890
  // Don't create a literal type if it's an f-string.
870
891
  if (node.nodeType === 27 /* FormatString */) {
871
892
  let isLiteralString = true;
872
893
  // If all of the format expressions are of type LiteralString, then
873
894
  // the resulting formatted string is also LiteralString.
874
895
  node.fieldExpressions.forEach((expr) => {
875
- const exprType = getTypeOfExpression(expr).type;
896
+ const exprTypeResult = getTypeOfExpression(expr);
897
+ const exprType = exprTypeResult.type;
898
+ if (exprTypeResult.isIncomplete) {
899
+ isIncomplete = true;
900
+ }
876
901
  (0, typeUtils_1.doForEachSubtype)(exprType, (exprSubtype) => {
877
902
  if (!(0, types_1.isClassInstance)(exprSubtype)) {
878
903
  isLiteralString = false;
@@ -890,18 +915,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
890
915
  if (!isBytes && isLiteralString) {
891
916
  const literalStringType = getTypingType(node, 'LiteralString');
892
917
  if (literalStringType && (0, types_1.isInstantiableClass)(literalStringType)) {
893
- typeResult = { type: types_1.ClassType.cloneAsInstance(literalStringType) };
918
+ typeResult = { type: types_1.ClassType.cloneAsInstance(literalStringType), isIncomplete };
894
919
  }
895
920
  }
896
921
  if (!typeResult) {
897
922
  typeResult = {
898
923
  type: getBuiltInObject(node, isBytes ? 'bytes' : 'str'),
924
+ isIncomplete,
899
925
  };
900
926
  }
901
927
  }
902
928
  else {
903
929
  typeResult = {
904
930
  type: cloneBuiltinObjectWithLiteral(node, isBytes ? 'bytes' : 'str', node.value),
931
+ isIncomplete,
905
932
  };
906
933
  }
907
934
  return typeResult;
@@ -1234,11 +1261,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1234
1261
  let memberInfo;
1235
1262
  const classDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1236
1263
  const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1264
+ let considerMetaclassOnly = (memberAccessFlags & 32 /* ConsiderMetaclassOnly */) !== 0;
1237
1265
  if (types_1.ClassType.isPartiallyEvaluated(classType)) {
1238
1266
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), errorNode);
1239
1267
  return { type: types_1.UnknownType.create() };
1240
1268
  }
1241
- if ((memberAccessFlags & 32 /* ConsiderMetaclassOnly */) === 0) {
1269
+ const metaclass = classType.details.effectiveMetaclass;
1270
+ // Look up the attribute in the metaclass first. If the member is a descriptor
1271
+ // (an object with a __get__ method) and the access is a 'get', the Python runtime
1272
+ // uses this metaclass descriptor to satisfy the lookup. Skip this costly lookup
1273
+ // in the common case where the metaclass is 'type' since we know that `type` doesn't
1274
+ // have any attributes that are descriptors.
1275
+ if (usage.method === 'get' &&
1276
+ metaclass &&
1277
+ (0, types_1.isInstantiableClass)(metaclass) &&
1278
+ !types_1.ClassType.isBuiltIn(metaclass, 'type') &&
1279
+ !types_1.ClassType.isSameGenericClass(metaclass, classType)) {
1280
+ const metaclassMemberInfo = getTypeOfClassMemberName(errorNode, metaclass,
1281
+ /* isAccessedThroughObject */ false, memberName, usage, metaclassDiag, memberAccessFlags, classType);
1282
+ if (metaclassMemberInfo && (0, typeUtils_1.isDescriptorInstance)(metaclassMemberInfo.type)) {
1283
+ considerMetaclassOnly = true;
1284
+ }
1285
+ }
1286
+ // Look up the attribute in the class object.
1287
+ if (!memberInfo && !considerMetaclassOnly) {
1242
1288
  memberInfo = getTypeOfClassMemberName(errorNode, classType,
1243
1289
  /* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
1244
1290
  }
@@ -2920,6 +2966,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2920
2966
  }
2921
2967
  }
2922
2968
  }
2969
+ if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
2970
+ reportUseOfTypeCheckOnly(type, node);
2971
+ }
2923
2972
  if ((flags & 16777216 /* DisallowPep695TypeAlias */) !== 0) {
2924
2973
  if (reportInvalidUseOfPep695TypeAlias(type, node)) {
2925
2974
  type = types_1.UnknownType.create();
@@ -3389,7 +3438,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3389
3438
  }
3390
3439
  return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3391
3440
  }
3392
- if (flags & 256 /* ExpectingTypeAnnotation */) {
3441
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
3393
3442
  if (!isIncomplete) {
3394
3443
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
3395
3444
  type: printType(baseType),
@@ -3613,6 +3662,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3613
3662
  // additional reportUnknownMemberType diagnostics.
3614
3663
  type = isFunctionRule ? types_1.AnyType.create() : types_1.UnknownType.create();
3615
3664
  }
3665
+ if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
3666
+ reportUseOfTypeCheckOnly(type, node.memberName);
3667
+ }
3616
3668
  // Should we specialize the class?
3617
3669
  if ((flags & 2 /* DoNotSpecialize */) === 0) {
3618
3670
  if ((0, types_1.isInstantiableClass)(type) && !type.typeArguments) {
@@ -3705,13 +3757,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3705
3757
  }
3706
3758
  }
3707
3759
  if (!type) {
3760
+ let selfClass = classType;
3708
3761
  // Determine whether to replace Self variables with a specific
3709
3762
  // class. Avoid doing this if there's a "bindToType" specified
3710
3763
  // because that case is used for super() calls where we want
3711
3764
  // to leave the Self type generic (not specialized). We'll also
3712
3765
  // skip this for __new__ methods because they are not bound
3713
3766
  // to the class but rather assume the type of the cls argument.
3714
- const selfClass = !!bindToType || memberName === '__new__' ? undefined : classType;
3767
+ if (bindToType) {
3768
+ if ((0, types_1.isTypeVar)(bindToType) && bindToType.details.isSynthesizedSelf) {
3769
+ selfClass = bindToType;
3770
+ }
3771
+ else {
3772
+ selfClass = undefined;
3773
+ }
3774
+ }
3775
+ else if (memberName === '__new__') {
3776
+ selfClass = undefined;
3777
+ }
3715
3778
  const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3716
3779
  if (typeResult) {
3717
3780
  type = typeResult.type;
@@ -3886,14 +3949,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3886
3949
  ];
3887
3950
  if (usage.method === 'get') {
3888
3951
  // Provide "owner" argument.
3889
- // Use Any rather than None for the owner argument if accessing through an object.
3890
- // None is more correct, but it doesn't really matter, and many descriptor classes
3891
- // incorrectly annotate the owner parameter. Rather than create a bunch of noise,
3892
- // we'll use Any here.
3893
3952
  argList.push({
3894
3953
  argumentCategory: 0 /* Simple */,
3895
3954
  typeResult: {
3896
- type: isAccessedThroughObject ? types_1.AnyType.create() : baseTypeClass,
3955
+ type: baseTypeClass,
3897
3956
  },
3898
3957
  });
3899
3958
  }
@@ -4251,14 +4310,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4251
4310
  function getTypeOfIndex(node, flags = 0 /* None */) {
4252
4311
  const baseTypeResult = getTypeOfExpression(node.baseExpression, flags | 2 /* IndexBaseDefaults */);
4253
4312
  // If this is meant to be a type and the base expression is a string expression,
4254
- // emit an error because this will generate a runtime exception in Python versions
4255
- // less than 3.10.
4313
+ // emit an error because this is an illegal annotation form and will generate a
4314
+ // runtime exception.
4256
4315
  if (flags & 128 /* ExpectingInstantiableType */) {
4257
4316
  if (node.baseExpression.nodeType === 48 /* StringList */) {
4258
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4259
- if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
4260
- addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
4261
- }
4317
+ addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
4262
4318
  }
4263
4319
  }
4264
4320
  // Check for builtin classes that will generate runtime exceptions if subscripted.
@@ -4608,7 +4664,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4608
4664
  const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
4609
4665
  /* usage */ undefined,
4610
4666
  /* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 32 /* ConsiderMetaclassOnly */);
4611
- if (flags & 256 /* ExpectingTypeAnnotation */) {
4667
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
4612
4668
  // If the class doesn't derive from Generic, a type argument should not be allowed.
4613
4669
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
4614
4670
  name: printType(types_1.ClassType.cloneAsInstance(concreteSubtype)),
@@ -4660,9 +4716,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4660
4716
  // Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
4661
4717
  // This feature is currently experimental.
4662
4718
  const supportsTypedDictTypeArg = AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
4663
- (0, types_1.isInstantiableClass)(concreteSubtype) &&
4664
- types_1.ClassType.isBuiltIn(concreteSubtype, 'dict') &&
4665
- !concreteSubtype.aliasName;
4719
+ types_1.ClassType.isBuiltIn(concreteSubtype, ['dict', 'TypedDict']) &&
4720
+ !types_1.ClassType.isBuiltIn(concreteSubtype, 'Dict');
4666
4721
  let typeArgs = getTypeArgs(node, flags, {
4667
4722
  isAnnotatedClass,
4668
4723
  hasCustomClassGetItem: hasCustomClassGetItem || !isGenericClass,
@@ -5633,7 +5688,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5633
5688
  if (node.arguments.length > 2) {
5634
5689
  addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
5635
5690
  }
5636
- const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
5691
+ const enclosingFunction = ParseTreeUtils.getEnclosingFunction(node);
5692
+ const enclosingClass = enclosingFunction
5693
+ ? ParseTreeUtils.getEnclosingClass(enclosingFunction, /* stopAtFunction */ true)
5694
+ : undefined;
5637
5695
  const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
5638
5696
  // Determine which class the "super" call is applied to. If
5639
5697
  // there is no first argument, then the class is implicit.
@@ -5804,13 +5862,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5804
5862
  return argParamCopy;
5805
5863
  });
5806
5864
  }
5807
- // Clone the typeVarContext so we don't modify the original. If this is
5808
- // not the first time through the loop, clone the type var context
5809
- // from the previous successful match.
5810
- const typeVarContextToClone = matchedOverloads.length > 0
5811
- ? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
5812
- : typeVarContext;
5813
- const effectiveTypeVarContext = (_a = typeVarContextToClone === null || typeVarContextToClone === void 0 ? void 0 : typeVarContextToClone.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
5865
+ // Clone the typeVarContext so we don't modify the original.
5866
+ const effectiveTypeVarContext = (_a = typeVarContext === null || typeVarContext === void 0 ? void 0 : typeVarContext.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
5814
5867
  effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
5815
5868
  effectiveTypeVarContext.unlock();
5816
5869
  // Use speculative mode so we don't output any diagnostics or
@@ -6557,7 +6610,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6557
6610
  var _a, _b;
6558
6611
  const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6559
6612
  /* usage */ undefined,
6560
- /* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
6613
+ /* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 1 /* AccessClassMembersOnly */)) === null || _a === void 0 ? void 0 : _a.type;
6561
6614
  if (!memberType) {
6562
6615
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6563
6616
  type: printType(expandedCallType),
@@ -7960,6 +8013,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7960
8013
  const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
7961
8014
  const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
7962
8015
  const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
8016
+ const nestedArgList = [];
7963
8017
  argList.forEach((arg) => {
7964
8018
  var _a;
7965
8019
  if (arg.argumentCategory === 0 /* Simple */) {
@@ -7989,6 +8043,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7989
8043
  else if (argsParam) {
7990
8044
  paramType = argsParam.type;
7991
8045
  }
8046
+ else if (paramSpecType.details.paramSpec) {
8047
+ nestedArgList.push(arg);
8048
+ }
7992
8049
  else {
7993
8050
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, paramSpecParams.length === 1
7994
8051
  ? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
@@ -8034,6 +8091,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8034
8091
  }
8035
8092
  }
8036
8093
  });
8094
+ // Handle recursive ParamSpecs.
8095
+ if (paramSpecType.details.paramSpec) {
8096
+ const boundTypeForParamSpec = srcTypeVarContext
8097
+ .getPrimarySignature()
8098
+ .getParamSpecType(paramSpecType.details.paramSpec);
8099
+ if (boundTypeForParamSpec) {
8100
+ const paramSpecArgResult = validateFunctionArgumentsForParamSpec(errorNode, nestedArgList, paramSpecType.details.paramSpec, srcTypeVarContext, conditionFilter);
8101
+ if (paramSpecArgResult.argumentErrors) {
8102
+ reportedArgError = true;
8103
+ }
8104
+ }
8105
+ }
8037
8106
  });
8038
8107
  }
8039
8108
  // Report any missing parameters.
@@ -8071,10 +8140,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8071
8140
  let isCompatible = true;
8072
8141
  const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
8073
8142
  let skippedBareTypeVarExpectedType = false;
8143
+ let skipSolveTypeVars = false;
8074
8144
  if (argParam.argument.valueExpression) {
8075
8145
  let expectedType;
8076
- const isBareTypeVarExpectedType = (0, types_1.isTypeVar)(argParam.paramType) && argParam.paramType.scopeId === (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId);
8077
- if (!options.skipBareTypeVarExpectedType || !isBareTypeVarExpectedType) {
8146
+ // Is the expected type a "bare" in-scope TypeVar or a union of bare in-scope TypeVars?
8147
+ let isExpectedTypeBareTypeVar = true;
8148
+ (0, typeUtils_1.doForEachSubtype)(argParam.paramType, (subtype) => {
8149
+ if (!(0, types_1.isTypeVar)(subtype) || subtype.scopeId !== (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId)) {
8150
+ isExpectedTypeBareTypeVar = false;
8151
+ }
8152
+ });
8153
+ if (!options.skipBareTypeVarExpectedType || !isExpectedTypeBareTypeVar) {
8078
8154
  expectedType = argParam.paramType;
8079
8155
  // If the parameter type is a function with a ParamSpec, don't apply
8080
8156
  // the solved TypeVars if the typeVarContext has more than one signature.
@@ -8090,6 +8166,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8090
8166
  }
8091
8167
  else {
8092
8168
  skippedBareTypeVarExpectedType = true;
8169
+ // If the expected type is a union of bare TypeVars, it's not clear which of the two
8170
+ // (or both) should be constrained. We'll skip any attempt to solve the TypeVars during
8171
+ // this pass and hope that subsequent arg assignments will help us establish the correct
8172
+ // constraints.
8173
+ if ((0, types_1.isUnion)(argParam.paramType)) {
8174
+ skipSolveTypeVars = true;
8175
+ }
8093
8176
  }
8094
8177
  // If the expected type is unknown, don't use an expected type. Instead,
8095
8178
  // use default rules for evaluating the expression type.
@@ -8166,15 +8249,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8166
8249
  }
8167
8250
  const condition = argType.condition;
8168
8251
  let diag = new diagnostic_1.DiagnosticAddendum();
8169
- // Handle the case where we're assigning a *args or **kwargs argument
8170
- // to a *P.args or **P.kwargs parameter.
8171
- if ((0, types_1.isParamSpec)(argParam.paramType) && argParam.paramType.paramSpecAccess !== undefined) {
8172
- return { isCompatible, argType, isTypeIncomplete, condition };
8173
- }
8174
- // Handle the case where we're assigning a *P.args or **P.kwargs argument
8175
- // to a *P.args or **P.kwargs parameter.
8176
- if ((0, types_1.isParamSpec)(argType) && argType.paramSpecAccess !== undefined) {
8177
- return { isCompatible, argType, isTypeIncomplete, condition };
8252
+ if ((0, types_1.isParamSpec)(argParam.paramType)) {
8253
+ // Handle the case where we're assigning a *args or **kwargs argument
8254
+ // to a *P.args or **P.kwargs parameter.
8255
+ if (argParam.paramType.paramSpecAccess !== undefined) {
8256
+ return { isCompatible, argType, isTypeIncomplete, condition };
8257
+ }
8258
+ // Handle the case where we're assigning a *P.args or **P.kwargs argument
8259
+ // to a *P.args or **P.kwargs parameter.
8260
+ if ((0, types_1.isParamSpec)(argType) && argType.paramSpecAccess !== undefined) {
8261
+ return { isCompatible, argType, isTypeIncomplete, condition };
8262
+ }
8178
8263
  }
8179
8264
  // If we are asked to skip overload arguments, determine whether the argument
8180
8265
  // is an explicit overload type, an overloaded class constructor, or a
@@ -8206,7 +8291,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8206
8291
  }
8207
8292
  }
8208
8293
  if ((0, types_1.isClassInstance)(argType)) {
8209
- const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__');
8294
+ const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 8 /* SkipInstanceVariables */);
8210
8295
  if (callMember) {
8211
8296
  const memberType = getTypeOfMember(callMember);
8212
8297
  if ((0, types_1.isOverloadedFunction)(memberType)) {
@@ -8223,7 +8308,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8223
8308
  }
8224
8309
  }
8225
8310
  }
8226
- if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext)) {
8311
+ if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext,
8312
+ /* srcTypeVarContext */ undefined, skipSolveTypeVars ? 8 /* SkipSolveTypeVars */ : undefined)) {
8227
8313
  // Mismatching parameter types are common in untyped code; don't bother spending time
8228
8314
  // printing types if the diagnostic is disabled.
8229
8315
  const fileInfo = AnalyzerNodeInfo.getFileInfo(argParam.errorNode);
@@ -10064,7 +10150,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10064
10150
  }
10065
10151
  }
10066
10152
  if (!type) {
10067
- const exprType = getTypeOfExpression(itemExpr);
10153
+ const exprType = getTypeOfExpression(itemExpr, flags & 4 /* AllowForwardReferences */);
10068
10154
  // Is this an enum type?
10069
10155
  if ((0, types_1.isClassInstance)(exprType.type) &&
10070
10156
  types_1.ClassType.isEnumClass(exprType.type) &&
@@ -10616,7 +10702,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10616
10702
  // methods that are abstract are overridden and shouldn't
10617
10703
  // cause the TypedDict to be marked as abstract.
10618
10704
  if ((0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, '_TypedDict')) {
10619
- baseClass.details.flags &= ~1024 /* SupportsAbstractMethods */;
10705
+ baseClass = types_1.ClassType.cloneWithNewFlags(baseClass, baseClass.details.flags &
10706
+ ~(1024 /* SupportsAbstractMethods */ | 134217728 /* TypeCheckOnly */));
10620
10707
  }
10621
10708
  }
10622
10709
  }
@@ -11022,452 +11109,465 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11022
11109
  setSymbolResolutionPartialType(classSymbol, classDecl, classType);
11023
11110
  }
11024
11111
  classType.details.flags |= 131072 /* PartiallyEvaluated */;
11025
- writeTypeCache(node, { type: classType }, /* flags */ undefined);
11026
- writeTypeCache(node.name, { type: classType }, /* flags */ undefined);
11027
- // Keep a list of unique type parameters that are used in the
11028
- // base class arguments.
11029
- let typeParameters = [];
11030
- if (node.typeParameters) {
11031
- typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
11032
- }
11033
- // If the class derives from "Generic" directly, it will provide
11034
- // all of the type parameters in the specified order.
11035
- let genericTypeParameters;
11036
- let protocolTypeParameters;
11037
- const initSubclassArgs = [];
11038
- let metaclassNode;
11039
- let exprFlags = 128 /* ExpectingInstantiableType */ |
11040
- 1024 /* AllowGenericClassType */ |
11041
- 262144 /* DisallowNakedGeneric */ |
11042
- 2048 /* DisallowTypeVarsWithScopeId */ |
11043
- 8192 /* AssociateTypeVarsWithCurrentScope */ |
11044
- 16384 /* EnforceTypeVarVarianceConsistency */ |
11045
- 16777216 /* DisallowPep695TypeAlias */;
11046
- if (fileInfo.isStubFile) {
11047
- exprFlags |= 4 /* AllowForwardReferences */;
11048
- }
11049
- node.arguments.forEach((arg) => {
11050
- // Ignore unpacked arguments.
11051
- if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
11052
- // Evaluate the expression's type so symbols are marked accessed
11053
- // and errors are reported.
11054
- getTypeOfExpression(arg.valueExpression);
11055
- return;
11112
+ try {
11113
+ writeTypeCache(node, { type: classType }, /* flags */ undefined);
11114
+ writeTypeCache(node.name, { type: classType }, /* flags */ undefined);
11115
+ // Keep a list of unique type parameters that are used in the
11116
+ // base class arguments.
11117
+ let typeParameters = [];
11118
+ if (node.typeParameters) {
11119
+ typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
11120
+ }
11121
+ // If the class derives from "Generic" directly, it will provide
11122
+ // all of the type parameters in the specified order.
11123
+ let genericTypeParameters;
11124
+ let protocolTypeParameters;
11125
+ const initSubclassArgs = [];
11126
+ let metaclassNode;
11127
+ let exprFlags = 128 /* ExpectingInstantiableType */ |
11128
+ 1024 /* AllowGenericClassType */ |
11129
+ 262144 /* DisallowNakedGeneric */ |
11130
+ 2048 /* DisallowTypeVarsWithScopeId */ |
11131
+ 8192 /* AssociateTypeVarsWithCurrentScope */ |
11132
+ 16384 /* EnforceTypeVarVarianceConsistency */ |
11133
+ 16777216 /* DisallowPep695TypeAlias */;
11134
+ if (fileInfo.isStubFile) {
11135
+ exprFlags |= 4 /* AllowForwardReferences */;
11056
11136
  }
11057
- if (!arg.name) {
11058
- let argType;
11059
- if (arg.argumentCategory === 1 /* UnpackedList */) {
11137
+ node.arguments.forEach((arg) => {
11138
+ // Ignore unpacked arguments.
11139
+ if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
11140
+ // Evaluate the expression's type so symbols are marked accessed
11141
+ // and errors are reported.
11060
11142
  getTypeOfExpression(arg.valueExpression);
11061
- argType = types_1.UnknownType.create();
11143
+ return;
11062
11144
  }
11063
- else {
11064
- argType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(arg.valueExpression, exprFlags).type);
11065
- }
11066
- // In some stub files, classes are conditionally defined (e.g. based
11067
- // on platform type). We'll assume that the conditional logic is correct
11068
- // and strip off the "unbound" union.
11069
- if ((0, types_1.isUnion)(argType)) {
11070
- argType = (0, types_1.removeUnbound)(argType);
11071
- }
11072
- if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
11073
- if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
11074
- (0, debug_1.assert)((0, types_1.isClassInstance)(argType));
11075
- argType =
11076
- argType.typeArguments && argType.typeArguments.length > 0
11077
- ? argType.typeArguments[0]
11078
- : types_1.UnknownType.create();
11079
- }
11080
- else if (!(0, types_1.isInstantiableClass)(argType)) {
11081
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
11145
+ if (!arg.name) {
11146
+ let argType;
11147
+ if (arg.argumentCategory === 1 /* UnpackedList */) {
11148
+ getTypeOfExpression(arg.valueExpression);
11082
11149
  argType = types_1.UnknownType.create();
11083
11150
  }
11084
11151
  else {
11085
- if (types_1.ClassType.isPartiallyEvaluated(argType) ||
11086
- argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
11087
- // If the base class is partially evaluated, install a callback
11088
- // so we can fix up this class (e.g. compute the MRO) when the
11089
- // dependent class is completed.
11090
- registerDeferredClassCompletion(node, argType);
11152
+ argType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(arg.valueExpression, exprFlags).type);
11153
+ }
11154
+ // In some stub files, classes are conditionally defined (e.g. based
11155
+ // on platform type). We'll assume that the conditional logic is correct
11156
+ // and strip off the "unbound" union.
11157
+ if ((0, types_1.isUnion)(argType)) {
11158
+ argType = (0, types_1.removeUnbound)(argType);
11159
+ }
11160
+ if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
11161
+ if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
11162
+ (0, debug_1.assert)((0, types_1.isClassInstance)(argType));
11163
+ argType =
11164
+ argType.typeArguments && argType.typeArguments.length > 0
11165
+ ? argType.typeArguments[0]
11166
+ : types_1.UnknownType.create();
11091
11167
  }
11092
- if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
11093
- if (!fileInfo.isStubFile &&
11094
- !types_1.ClassType.isTypingExtensionClass(argType) &&
11095
- fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_7) {
11096
- addError(localize_1.Localizer.Diagnostic.protocolIllegal(), arg.valueExpression);
11168
+ else if (!(0, types_1.isInstantiableClass)(argType)) {
11169
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
11170
+ argType = types_1.UnknownType.create();
11171
+ }
11172
+ else {
11173
+ if (types_1.ClassType.isPartiallyEvaluated(argType) ||
11174
+ argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
11175
+ // If the base class is partially evaluated, install a callback
11176
+ // so we can fix up this class (e.g. compute the MRO) when the
11177
+ // dependent class is completed.
11178
+ registerDeferredClassCompletion(node, argType);
11179
+ }
11180
+ if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
11181
+ if (!fileInfo.isStubFile &&
11182
+ !types_1.ClassType.isTypingExtensionClass(argType) &&
11183
+ fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_7) {
11184
+ addError(localize_1.Localizer.Diagnostic.protocolIllegal(), arg.valueExpression);
11185
+ }
11186
+ classType.details.flags |= 8192 /* ProtocolClass */;
11187
+ }
11188
+ if (types_1.ClassType.isBuiltIn(argType, 'property')) {
11189
+ classType.details.flags |= 2048 /* PropertyClass */;
11190
+ }
11191
+ // If the class directly derives from NamedTuple (in Python 3.6 or
11192
+ // newer), it's considered a (read-only) dataclass.
11193
+ if (fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
11194
+ if (types_1.ClassType.isBuiltIn(argType, 'NamedTuple')) {
11195
+ classType.details.flags |=
11196
+ 4 /* DataClass */ |
11197
+ 32 /* SkipSynthesizedDataClassEq */ |
11198
+ 16777216 /* ReadOnlyInstanceVariables */;
11199
+ }
11200
+ }
11201
+ // If the class directly derives from TypedDict or from a class that is
11202
+ // a TypedDict, it is considered a TypedDict.
11203
+ if (types_1.ClassType.isBuiltIn(argType, 'TypedDict') || types_1.ClassType.isTypedDictClass(argType)) {
11204
+ classType.details.flags |= 128 /* TypedDictClass */;
11205
+ }
11206
+ else if (types_1.ClassType.isTypedDictClass(classType) && !types_1.ClassType.isTypedDictClass(argType)) {
11207
+ // Exempt Generic from this test. As of Python 3.11, generic TypedDict
11208
+ // classes are supported.
11209
+ if (!(0, types_1.isInstantiableClass)(argType) || !types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11210
+ // TypedDict classes must derive only from other TypedDict classes.
11211
+ addError(localize_1.Localizer.Diagnostic.typedDictBaseClass(), arg);
11212
+ }
11213
+ }
11214
+ // Validate that the class isn't deriving from itself, creating a
11215
+ // circular dependency.
11216
+ if ((0, typeUtils_1.derivesFromClassRecursive)(argType, classType, /* ignoreUnknown */ true)) {
11217
+ addError(localize_1.Localizer.Diagnostic.baseClassCircular(), arg);
11218
+ argType = types_1.UnknownType.create();
11097
11219
  }
11098
- classType.details.flags |= 8192 /* ProtocolClass */;
11099
11220
  }
11100
- if (types_1.ClassType.isBuiltIn(argType, 'property')) {
11101
- classType.details.flags |= 2048 /* PropertyClass */;
11221
+ }
11222
+ if ((0, types_1.isUnknown)(argType)) {
11223
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedBaseClass, diagnosticRules_1.DiagnosticRule.reportUntypedBaseClass, localize_1.Localizer.Diagnostic.baseClassUnknown(), arg);
11224
+ }
11225
+ // Check for a duplicate class.
11226
+ if (classType.details.baseClasses.some((prevBaseClass) => {
11227
+ return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
11228
+ (0, types_1.isInstantiableClass)(argType) &&
11229
+ types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
11230
+ })) {
11231
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
11232
+ }
11233
+ classType.details.baseClasses.push(argType);
11234
+ if ((0, types_1.isInstantiableClass)(argType)) {
11235
+ if (types_1.ClassType.isEnumClass(argType)) {
11236
+ classType.details.flags |= 1048576 /* EnumClass */;
11102
11237
  }
11103
- // If the class directly derives from NamedTuple (in Python 3.6 or
11104
- // newer), it's considered a (read-only) dataclass.
11105
- if (fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
11106
- if (types_1.ClassType.isBuiltIn(argType, 'NamedTuple')) {
11107
- classType.details.flags |=
11108
- 4 /* DataClass */ |
11109
- 32 /* SkipSynthesizedDataClassEq */ |
11110
- 16777216 /* ReadOnlyInstanceVariables */;
11111
- }
11238
+ // Determine if the class is abstract. Protocol classes support abstract methods
11239
+ // even though they don't derive from the ABCMeta class. We'll exclude built-in
11240
+ // protocol classes because these are known not to contain any abstract methods
11241
+ // and getAbstractMethods causes problems because of dependencies on some of these
11242
+ // built-in protocol classes.
11243
+ if (types_1.ClassType.supportsAbstractMethods(argType) ||
11244
+ (types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
11245
+ classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11112
11246
  }
11113
- // If the class directly derives from TypedDict or from a class that is
11114
- // a TypedDict, it is considered a TypedDict.
11115
- if (types_1.ClassType.isBuiltIn(argType, 'TypedDict') || types_1.ClassType.isTypedDictClass(argType)) {
11116
- classType.details.flags |= 128 /* TypedDictClass */;
11247
+ if (types_1.ClassType.isPropertyClass(argType)) {
11248
+ classType.details.flags |= 2048 /* PropertyClass */;
11249
+ }
11250
+ if (types_1.ClassType.isFinal(argType)) {
11251
+ const className = printObjectTypeForClass(argType);
11252
+ addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
11117
11253
  }
11118
- else if (types_1.ClassType.isTypedDictClass(classType) && !types_1.ClassType.isTypedDictClass(argType)) {
11119
- // Exempt Generic from this test. As of Python 3.11, generic TypedDict
11120
- // classes are supported.
11121
- if (!(0, types_1.isInstantiableClass)(argType) || !types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11122
- // TypedDict classes must derive only from other TypedDict classes.
11123
- addError(localize_1.Localizer.Diagnostic.typedDictBaseClass(), arg);
11254
+ }
11255
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11256
+ if ((0, types_1.isInstantiableClass)(argType)) {
11257
+ if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11258
+ // 'Generic' is implicitly added if type parameter syntax is used.
11259
+ if (node.typeParameters) {
11260
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
11261
+ }
11262
+ else {
11263
+ if (!genericTypeParameters) {
11264
+ if (protocolTypeParameters) {
11265
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11266
+ }
11267
+ genericTypeParameters = [];
11268
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11269
+ }
11124
11270
  }
11125
11271
  }
11126
- // Validate that the class isn't deriving from itself, creating a
11127
- // circular dependency.
11128
- if ((0, typeUtils_1.derivesFromClassRecursive)(argType, classType, /* ignoreUnknown */ true)) {
11129
- addError(localize_1.Localizer.Diagnostic.baseClassCircular(), arg);
11130
- argType = types_1.UnknownType.create();
11272
+ else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
11273
+ argType.typeArguments &&
11274
+ argType.typeArguments.length > 0) {
11275
+ if (!protocolTypeParameters) {
11276
+ if (genericTypeParameters) {
11277
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11278
+ }
11279
+ protocolTypeParameters = [];
11280
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11281
+ if (node.typeParameters && protocolTypeParameters.length > 0) {
11282
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
11283
+ protocolTypeParameters = [];
11284
+ }
11285
+ }
11131
11286
  }
11132
11287
  }
11133
11288
  }
11134
- if ((0, types_1.isUnknown)(argType)) {
11135
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedBaseClass, diagnosticRules_1.DiagnosticRule.reportUntypedBaseClass, localize_1.Localizer.Diagnostic.baseClassUnknown(), arg);
11136
- }
11137
- // Check for a duplicate class.
11138
- if (classType.details.baseClasses.some((prevBaseClass) => {
11139
- return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
11140
- (0, types_1.isInstantiableClass)(argType) &&
11141
- types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
11142
- })) {
11143
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
11144
- }
11145
- classType.details.baseClasses.push(argType);
11146
- if ((0, types_1.isInstantiableClass)(argType)) {
11147
- if (types_1.ClassType.isEnumClass(argType)) {
11148
- classType.details.flags |= 1048576 /* EnumClass */;
11289
+ else if (arg.name.value === 'metaclass') {
11290
+ if (metaclassNode) {
11291
+ addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
11149
11292
  }
11150
- // Determine if the class is abstract. Protocol classes support abstract methods
11151
- // even though they don't derive from the ABCMeta class. We'll exclude built-in
11152
- // protocol classes because these are known not to contain any abstract methods
11153
- // and getAbstractMethods causes problems because of dependencies on some of these
11154
- // built-in protocol classes.
11155
- if (types_1.ClassType.supportsAbstractMethods(argType) ||
11156
- (types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
11157
- classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11293
+ else {
11294
+ metaclassNode = arg.valueExpression;
11295
+ }
11296
+ }
11297
+ else if (types_1.ClassType.isTypedDictClass(classType) &&
11298
+ (arg.name.value === 'total' || arg.name.value === 'readonly')) {
11299
+ // The "total" and "readonly" parameters apply only for TypedDict classes.
11300
+ // PEP 589 specifies that the parameter must be either True or False.
11301
+ const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
11302
+ if (constArgValue === undefined) {
11303
+ addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
11158
11304
  }
11159
- if (types_1.ClassType.isPropertyClass(argType)) {
11160
- classType.details.flags |= 2048 /* PropertyClass */;
11305
+ else if (arg.name.value === 'total' && !constArgValue) {
11306
+ classType.details.flags |= 256 /* CanOmitDictValues */;
11161
11307
  }
11162
- if (types_1.ClassType.isFinal(argType)) {
11163
- const className = printObjectTypeForClass(argType);
11164
- addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
11308
+ else if (arg.name.value === 'readonly' && constArgValue) {
11309
+ classType.details.flags |= 512 /* DictValuesReadOnly */;
11165
11310
  }
11166
11311
  }
11167
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11168
- if ((0, types_1.isInstantiableClass)(argType)) {
11169
- if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11170
- // 'Generic' is implicitly added if type parameter syntax is used.
11171
- if (node.typeParameters) {
11172
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
11312
+ else {
11313
+ // Collect arguments that will be passed to the `__init_subclass__`
11314
+ // method described in PEP 487.
11315
+ initSubclassArgs.push({
11316
+ argumentCategory: 0 /* Simple */,
11317
+ node: arg,
11318
+ name: arg.name,
11319
+ valueExpression: arg.valueExpression,
11320
+ });
11321
+ }
11322
+ });
11323
+ // Check for NamedTuple multiple inheritance.
11324
+ if (classType.details.baseClasses.length > 1) {
11325
+ let derivesFromNamedTuple = false;
11326
+ let foundIllegalBaseClass = false;
11327
+ classType.details.baseClasses.forEach((baseClass) => {
11328
+ if ((0, types_1.isInstantiableClass)(baseClass)) {
11329
+ if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
11330
+ derivesFromNamedTuple = true;
11173
11331
  }
11174
- else {
11175
- if (!genericTypeParameters) {
11176
- if (protocolTypeParameters) {
11177
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11178
- }
11179
- genericTypeParameters = [];
11180
- (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11181
- }
11332
+ else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11333
+ foundIllegalBaseClass = true;
11182
11334
  }
11183
11335
  }
11184
- else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
11185
- argType.typeArguments &&
11186
- argType.typeArguments.length > 0) {
11187
- if (!protocolTypeParameters) {
11188
- if (genericTypeParameters) {
11189
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11190
- }
11191
- protocolTypeParameters = [];
11192
- (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11193
- if (node.typeParameters && protocolTypeParameters.length > 0) {
11194
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
11195
- protocolTypeParameters = [];
11336
+ });
11337
+ if (derivesFromNamedTuple && foundIllegalBaseClass) {
11338
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedTupleMultipleInheritance(), node.name);
11339
+ }
11340
+ }
11341
+ // Make sure we don't have 'object' derive from itself. Infinite
11342
+ // recursion will result.
11343
+ if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
11344
+ classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
11345
+ // If there are no other (known) base classes, the class implicitly derives from object.
11346
+ classType.details.baseClasses.push(getBuiltInType(node, 'object'));
11347
+ }
11348
+ // If genericTypeParameters or protocolTypeParameters are provided,
11349
+ // make sure that typeParameters is a proper subset.
11350
+ genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
11351
+ if (genericTypeParameters && !node.typeParameters) {
11352
+ verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
11353
+ }
11354
+ classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
11355
+ // Determine if one or more type parameters is autovariance.
11356
+ if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
11357
+ classType.details.requiresVarianceInference = true;
11358
+ }
11359
+ // Make sure there's at most one variadic type parameter.
11360
+ const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
11361
+ if (variadics.length > 1) {
11362
+ addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
11363
+ names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11364
+ }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11365
+ }
11366
+ // Validate the default types for all type parameters.
11367
+ classType.details.typeParameters.forEach((typeParam, index) => {
11368
+ var _a;
11369
+ let bestErrorNode = node.name;
11370
+ if (node.typeParameters && index < node.typeParameters.parameters.length) {
11371
+ const typeParamNode = node.typeParameters.parameters[index];
11372
+ bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
11373
+ }
11374
+ validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
11375
+ });
11376
+ if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11377
+ addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11378
+ }
11379
+ // The scope for this class becomes the "fields" for the corresponding type.
11380
+ const innerScope = ScopeUtils.getScopeForNode(node.suite);
11381
+ classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
11382
+ ? new Map(innerScope.symbolTable)
11383
+ : new Map();
11384
+ // Determine whether the class should inherit __hash__. If a class defines
11385
+ // __eq__ but doesn't define __hash__ then __hash__ is set to None.
11386
+ if (classType.details.fields.has('__eq__') && !classType.details.fields.has('__hash__')) {
11387
+ classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ |
11388
+ 128 /* ClassVar */ |
11389
+ 64 /* IgnoredForProtocolMatch */ |
11390
+ 4096 /* IgnoredForOverrideChecks */, types_1.NoneType.createInstance()));
11391
+ }
11392
+ // Determine whether the class's instance variables are constrained
11393
+ // to those defined by __slots__. We need to do this prior to dataclass
11394
+ // processing because dataclasses can implicitly add to the slots
11395
+ // list.
11396
+ const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
11397
+ if (slotsNames) {
11398
+ classType.details.localSlotsNames = slotsNames;
11399
+ }
11400
+ // Determine if the class should be a "pseudo-generic" class, characterized
11401
+ // by having an __init__ method with parameters that lack type annotations.
11402
+ // For such classes, we'll treat them as generic, with the type arguments provided
11403
+ // by the callers of the constructor.
11404
+ if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
11405
+ const initMethod = classType.details.fields.get('__init__');
11406
+ if (initMethod) {
11407
+ const initDecls = initMethod.getTypedDeclarations();
11408
+ if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
11409
+ const initDeclNode = initDecls[0].node;
11410
+ const initParams = initDeclNode.parameters;
11411
+ if (initParams.length > 1 &&
11412
+ !initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
11413
+ const genericParams = initParams.filter((param, index) => index > 0 &&
11414
+ param.name &&
11415
+ param.category === 0 /* Simple */ &&
11416
+ !param.defaultValue);
11417
+ if (genericParams.length > 0) {
11418
+ classType.details.flags |= 16384 /* PseudoGenericClass */;
11419
+ // Create a type parameter for each simple, named parameter
11420
+ // in the __init__ method.
11421
+ classType.details.typeParameters = genericParams.map((param) => {
11422
+ const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
11423
+ typeVar.details.isSynthesized = true;
11424
+ typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
11425
+ typeVar.details.boundType = types_1.UnknownType.create();
11426
+ return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
11427
+ });
11196
11428
  }
11197
11429
  }
11198
11430
  }
11199
11431
  }
11200
11432
  }
11201
- else if (arg.name.value === 'metaclass') {
11202
- if (metaclassNode) {
11203
- addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
11433
+ // Determine if the class has a custom __class_getitem__ method. This applies
11434
+ // only to classes that have no type parameters, since those with type parameters
11435
+ // are assumed to follow normal subscripting semantics for generic classes.
11436
+ if (classType.details.typeParameters.length === 0 && !types_1.ClassType.isBuiltIn(classType, 'type')) {
11437
+ if (classType.details.baseClasses.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.hasCustomClassGetItem(baseClass)) ||
11438
+ classType.details.fields.has('__class_getitem__')) {
11439
+ classType.details.flags |= 262144 /* HasCustomClassGetItem */;
11204
11440
  }
11205
- else {
11206
- metaclassNode = arg.valueExpression;
11207
- }
11208
- }
11209
- else if (types_1.ClassType.isTypedDictClass(classType) &&
11210
- (arg.name.value === 'total' || arg.name.value === 'readonly')) {
11211
- // The "total" and "readonly" parameters apply only for TypedDict classes.
11212
- // PEP 589 specifies that the parameter must be either True or False.
11213
- const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
11214
- if (constArgValue === undefined) {
11215
- addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
11216
- }
11217
- else if (arg.name.value === 'total' && !constArgValue) {
11218
- classType.details.flags |= 256 /* CanOmitDictValues */;
11219
- }
11220
- else if (arg.name.value === 'readonly' && constArgValue) {
11221
- classType.details.flags |= 512 /* DictValuesReadOnly */;
11222
- }
11223
- }
11224
- else {
11225
- // Collect arguments that will be passed to the `__init_subclass__`
11226
- // method described in PEP 487.
11227
- initSubclassArgs.push({
11228
- argumentCategory: 0 /* Simple */,
11229
- node: arg,
11230
- name: arg.name,
11231
- valueExpression: arg.valueExpression,
11232
- });
11233
11441
  }
11234
- });
11235
- // Check for NamedTuple multiple inheritance.
11236
- if (classType.details.baseClasses.length > 1) {
11237
- let derivesFromNamedTuple = false;
11238
- let foundIllegalBaseClass = false;
11239
- classType.details.baseClasses.forEach((baseClass) => {
11240
- if ((0, types_1.isInstantiableClass)(baseClass)) {
11241
- if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
11242
- derivesFromNamedTuple = true;
11243
- }
11244
- else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11245
- foundIllegalBaseClass = true;
11442
+ // Determine the effective metaclass.
11443
+ if (metaclassNode) {
11444
+ const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
11445
+ if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
11446
+ if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
11447
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
11246
11448
  }
11247
- }
11248
- });
11249
- if (derivesFromNamedTuple && foundIllegalBaseClass) {
11250
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedTupleMultipleInheritance(), node.name);
11251
- }
11252
- }
11253
- // Make sure we don't have 'object' derive from itself. Infinite
11254
- // recursion will result.
11255
- if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
11256
- classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
11257
- // If there are no other (known) base classes, the class implicitly derives from object.
11258
- classType.details.baseClasses.push(getBuiltInType(node, 'object'));
11259
- }
11260
- // If genericTypeParameters or protocolTypeParameters are provided,
11261
- // make sure that typeParameters is a proper subset.
11262
- genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
11263
- if (genericTypeParameters && !node.typeParameters) {
11264
- verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
11265
- }
11266
- classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
11267
- // Determine if one or more type parameters is autovariance.
11268
- if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
11269
- classType.details.requiresVarianceInference = true;
11270
- }
11271
- // Make sure there's at most one variadic type parameter.
11272
- const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
11273
- if (variadics.length > 1) {
11274
- addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
11275
- names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11276
- }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11277
- }
11278
- // Validate the default types for all type parameters.
11279
- classType.details.typeParameters.forEach((typeParam, index) => {
11280
- var _a;
11281
- let bestErrorNode = node.name;
11282
- if (node.typeParameters && index < node.typeParameters.parameters.length) {
11283
- const typeParamNode = node.typeParameters.parameters[index];
11284
- bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
11285
- }
11286
- validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
11287
- });
11288
- if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11289
- addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11290
- }
11291
- // The scope for this class becomes the "fields" for the corresponding type.
11292
- const innerScope = ScopeUtils.getScopeForNode(node.suite);
11293
- classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
11294
- ? new Map(innerScope.symbolTable)
11295
- : new Map();
11296
- // Determine whether the class should inherit __hash__. If a class defines
11297
- // __eq__ but doesn't define __hash__ then __hash__ is set to None.
11298
- if (classType.details.fields.has('__eq__') && !classType.details.fields.has('__hash__')) {
11299
- classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ | 128 /* ClassVar */ | 64 /* IgnoredForProtocolMatch */, types_1.NoneType.createInstance()));
11300
- }
11301
- // Determine whether the class's instance variables are constrained
11302
- // to those defined by __slots__. We need to do this prior to dataclass
11303
- // processing because dataclasses can implicitly add to the slots
11304
- // list.
11305
- const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
11306
- if (slotsNames) {
11307
- classType.details.localSlotsNames = slotsNames;
11308
- }
11309
- // Determine if the class should be a "pseudo-generic" class, characterized
11310
- // by having an __init__ method with parameters that lack type annotations.
11311
- // For such classes, we'll treat them as generic, with the type arguments provided
11312
- // by the callers of the constructor.
11313
- if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
11314
- const initMethod = classType.details.fields.get('__init__');
11315
- if (initMethod) {
11316
- const initDecls = initMethod.getTypedDeclarations();
11317
- if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
11318
- const initDeclNode = initDecls[0].node;
11319
- const initParams = initDeclNode.parameters;
11320
- if (initParams.length > 1 &&
11321
- !initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
11322
- const genericParams = initParams.filter((param, index) => index > 0 &&
11323
- param.name &&
11324
- param.category === 0 /* Simple */ &&
11325
- !param.defaultValue);
11326
- if (genericParams.length > 0) {
11327
- classType.details.flags |= 16384 /* PseudoGenericClass */;
11328
- // Create a type parameter for each simple, named parameter
11329
- // in the __init__ method.
11330
- classType.details.typeParameters = genericParams.map((param) => {
11331
- const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
11332
- typeVar.details.isSynthesized = true;
11333
- typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
11334
- typeVar.details.boundType = types_1.UnknownType.create();
11335
- return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
11336
- });
11449
+ classType.details.declaredMetaclass = metaclassType;
11450
+ if ((0, types_1.isInstantiableClass)(metaclassType)) {
11451
+ if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
11452
+ classType.details.flags |= 1048576 /* EnumClass */;
11453
+ }
11454
+ else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
11455
+ classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11337
11456
  }
11338
11457
  }
11339
11458
  }
11340
11459
  }
11341
- }
11342
- // Determine if the class has a custom __class_getitem__ method. This applies
11343
- // only to classes that have no type parameters, since those with type parameters
11344
- // are assumed to follow normal subscripting semantics for generic classes.
11345
- if (classType.details.typeParameters.length === 0 && !types_1.ClassType.isBuiltIn(classType, 'type')) {
11346
- if (classType.details.baseClasses.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.hasCustomClassGetItem(baseClass)) ||
11347
- classType.details.fields.has('__class_getitem__')) {
11348
- classType.details.flags |= 262144 /* HasCustomClassGetItem */;
11349
- }
11350
- }
11351
- // Determine the effective metaclass.
11352
- if (metaclassNode) {
11353
- const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
11354
- if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
11355
- if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
11356
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
11357
- }
11358
- classType.details.declaredMetaclass = metaclassType;
11359
- if ((0, types_1.isInstantiableClass)(metaclassType)) {
11360
- if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
11361
- classType.details.flags |= 1048576 /* EnumClass */;
11362
- }
11363
- else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
11364
- classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11460
+ const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
11461
+ // Clear the "partially constructed" flag.
11462
+ classType.details.flags &= ~131072 /* PartiallyEvaluated */;
11463
+ // Now determine the decorated type of the class.
11464
+ let decoratedType = classType;
11465
+ let foundUnknown = false;
11466
+ for (let i = node.decorators.length - 1; i >= 0; i--) {
11467
+ const decorator = node.decorators[i];
11468
+ const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
11469
+ const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
11470
+ if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
11471
+ // Report this error only on the first unknown type.
11472
+ if (!foundUnknown) {
11473
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
11474
+ foundUnknown = true;
11365
11475
  }
11366
11476
  }
11367
- }
11368
- }
11369
- const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
11370
- // Clear the "partially constructed" flag.
11371
- classType.details.flags &= ~131072 /* PartiallyEvaluated */;
11372
- // Now determine the decorated type of the class.
11373
- let decoratedType = classType;
11374
- let foundUnknown = false;
11375
- for (let i = node.decorators.length - 1; i >= 0; i--) {
11376
- const decorator = node.decorators[i];
11377
- const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
11378
- const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
11379
- if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
11380
- // Report this error only on the first unknown type.
11381
- if (!foundUnknown) {
11382
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
11383
- foundUnknown = true;
11477
+ else {
11478
+ // Apply the decorator only if the type is known.
11479
+ decoratedType = newDecoratedType;
11384
11480
  }
11385
11481
  }
11386
- else {
11387
- // Apply the decorator only if the type is known.
11388
- decoratedType = newDecoratedType;
11482
+ // Determine whether this class derives from (or has a metaclass) that imbues
11483
+ // it with dataclass-like behaviors. If so, we'll apply those here.
11484
+ let dataClassBehaviors;
11485
+ if ((0, types_1.isInstantiableClass)(effectiveMetaclass) && effectiveMetaclass.details.classDataClassTransform) {
11486
+ dataClassBehaviors = effectiveMetaclass.details.classDataClassTransform;
11389
11487
  }
11390
- }
11391
- // Determine whether this class derives from (or has a metaclass) that imbues
11392
- // it with dataclass-like behaviors. If so, we'll apply those here.
11393
- let dataClassBehaviors;
11394
- if ((0, types_1.isInstantiableClass)(effectiveMetaclass) && effectiveMetaclass.details.classDataClassTransform) {
11395
- dataClassBehaviors = effectiveMetaclass.details.classDataClassTransform;
11396
- }
11397
- else {
11398
- const baseClassDataTransform = classType.details.mro.find((mroClass) => {
11399
- return ((0, types_1.isClass)(mroClass) &&
11400
- mroClass.details.classDataClassTransform !== undefined &&
11401
- !types_1.ClassType.isSameGenericClass(mroClass, classType));
11402
- });
11403
- if (baseClassDataTransform) {
11404
- dataClassBehaviors = baseClassDataTransform.details.classDataClassTransform;
11405
- }
11406
- }
11407
- if (dataClassBehaviors) {
11408
- (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11409
- (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11410
- }
11411
- // Run any deferred class completions that depend on this class.
11412
- runDeferredClassCompletions(classType);
11413
- // If there are any outstanding deferred class completions registered that
11414
- // were not removed by the call to runDeferredClassCompletions, assume that
11415
- // the current class may depend on them and register for deferred completion.
11416
- registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
11417
- // Synthesize TypedDict methods.
11418
- if (types_1.ClassType.isTypedDictClass(classType)) {
11419
- (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
11420
- }
11421
- // Synthesize dataclass methods.
11422
- if (types_1.ClassType.isDataClass(classType)) {
11423
- const skipSynthesizedInit = types_1.ClassType.isSkipSynthesizedDataClassInit(classType);
11424
- let hasExistingInitMethod = skipSynthesizedInit;
11425
- // See if there's already a non-synthesized __init__ method.
11426
- // We shouldn't override it.
11427
- if (!skipSynthesizedInit) {
11428
- const initSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 2 /* SkipBaseClasses */);
11429
- if (initSymbol) {
11430
- hasExistingInitMethod = true;
11431
- }
11432
- }
11433
- let skipSynthesizeHash = false;
11434
- const hashSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__hash__', 2 /* SkipBaseClasses */);
11435
- if (hashSymbol) {
11436
- skipSynthesizeHash = true;
11437
- }
11438
- (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
11439
- }
11440
- // Build a complete list of all slots names defined by the class hierarchy.
11441
- // This needs to be done after dataclass processing.
11442
- if (classType.details.localSlotsNames) {
11443
- let isLimitedToSlots = true;
11444
- const extendedSlotsNames = Array.from(classType.details.localSlotsNames);
11445
- classType.details.baseClasses.forEach((baseClass) => {
11446
- if ((0, types_1.isInstantiableClass)(baseClass)) {
11447
- if (!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
11448
- !types_1.ClassType.isBuiltIn(baseClass, 'type') &&
11449
- !types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11450
- if (baseClass.details.inheritedSlotsNames === undefined) {
11451
- isLimitedToSlots = false;
11452
- }
11453
- else {
11454
- (0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
11488
+ else {
11489
+ const baseClassDataTransform = classType.details.mro.find((mroClass) => {
11490
+ return ((0, types_1.isClass)(mroClass) &&
11491
+ mroClass.details.classDataClassTransform !== undefined &&
11492
+ !types_1.ClassType.isSameGenericClass(mroClass, classType));
11493
+ });
11494
+ if (baseClassDataTransform) {
11495
+ dataClassBehaviors = baseClassDataTransform.details.classDataClassTransform;
11496
+ }
11497
+ }
11498
+ if (dataClassBehaviors) {
11499
+ (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11500
+ (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11501
+ }
11502
+ // Run any deferred class completions that depend on this class.
11503
+ runDeferredClassCompletions(classType);
11504
+ // If there are any outstanding deferred class completions registered that
11505
+ // were not removed by the call to runDeferredClassCompletions, assume that
11506
+ // the current class may depend on them and register for deferred completion.
11507
+ registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
11508
+ // Synthesize TypedDict methods.
11509
+ if (types_1.ClassType.isTypedDictClass(classType)) {
11510
+ (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
11511
+ }
11512
+ // Synthesize dataclass methods.
11513
+ if (types_1.ClassType.isDataClass(classType)) {
11514
+ const skipSynthesizedInit = types_1.ClassType.isSkipSynthesizedDataClassInit(classType);
11515
+ let hasExistingInitMethod = skipSynthesizedInit;
11516
+ // See if there's already a non-synthesized __init__ method.
11517
+ // We shouldn't override it.
11518
+ if (!skipSynthesizedInit) {
11519
+ const initSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 2 /* SkipBaseClasses */);
11520
+ if (initSymbol) {
11521
+ hasExistingInitMethod = true;
11522
+ }
11523
+ }
11524
+ let skipSynthesizeHash = false;
11525
+ const hashSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__hash__', 2 /* SkipBaseClasses */);
11526
+ if (hashSymbol) {
11527
+ skipSynthesizeHash = true;
11528
+ }
11529
+ (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
11530
+ }
11531
+ // Build a complete list of all slots names defined by the class hierarchy.
11532
+ // This needs to be done after dataclass processing.
11533
+ if (classType.details.localSlotsNames) {
11534
+ let isLimitedToSlots = true;
11535
+ const extendedSlotsNames = Array.from(classType.details.localSlotsNames);
11536
+ classType.details.baseClasses.forEach((baseClass) => {
11537
+ if ((0, types_1.isInstantiableClass)(baseClass)) {
11538
+ if (!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
11539
+ !types_1.ClassType.isBuiltIn(baseClass, 'type') &&
11540
+ !types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11541
+ if (baseClass.details.inheritedSlotsNames === undefined) {
11542
+ isLimitedToSlots = false;
11543
+ }
11544
+ else {
11545
+ (0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
11546
+ }
11455
11547
  }
11456
11548
  }
11549
+ else {
11550
+ isLimitedToSlots = false;
11551
+ }
11552
+ });
11553
+ if (isLimitedToSlots) {
11554
+ classType.details.inheritedSlotsNames = extendedSlotsNames;
11457
11555
  }
11458
- else {
11459
- isLimitedToSlots = false;
11460
- }
11461
- });
11462
- if (isLimitedToSlots) {
11463
- classType.details.inheritedSlotsNames = extendedSlotsNames;
11464
11556
  }
11557
+ // Update the undecorated class type.
11558
+ writeTypeCache(node.name, { type: classType }, 0 /* None */);
11559
+ // Update the decorated class type.
11560
+ writeTypeCache(node, { type: decoratedType }, 0 /* None */);
11561
+ return { classType, decoratedType };
11562
+ }
11563
+ catch (e) {
11564
+ if (cancellationUtils_1.OperationCanceledException.is(e)) {
11565
+ // If the work was canceled before the class types were updated, the
11566
+ // class type in the type cache is in an invalid, partially-constructed state.
11567
+ e.isTypeCacheInvalid = true;
11568
+ }
11569
+ throw e;
11465
11570
  }
11466
- // Update the undecorated class type.
11467
- writeTypeCache(node.name, { type: classType }, 0 /* None */);
11468
- // Update the decorated class type.
11469
- writeTypeCache(node, { type: decoratedType }, 0 /* None */);
11470
- return { classType, decoratedType };
11471
11571
  }
11472
11572
  // Determines whether the type parameters has a default that refers to another
11473
11573
  // type parameter. If so, validates that it is in the list of "live" type
@@ -12761,6 +12861,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12761
12861
  setSymbolAccessed(fileInfo, symbolInScope.symbol, node);
12762
12862
  }
12763
12863
  }
12864
+ // If this is an import into a class scope, mark the symbol as accessed.
12865
+ const classNode = ParseTreeUtils.getEnclosingClass(node, /* stopAtFunction */ true);
12866
+ if (classNode) {
12867
+ const symbolInScope = lookUpSymbolRecursive(node, aliasNode.value, /* honorCodeFlow */ true);
12868
+ if (symbolInScope) {
12869
+ setSymbolAccessed(fileInfo, symbolInScope.symbol, node);
12870
+ }
12871
+ }
12764
12872
  let symbolType = getAliasedSymbolTypeForName(node, aliasNode.value);
12765
12873
  if (!symbolType) {
12766
12874
  const parentNode = node.parent;
@@ -14753,6 +14861,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14753
14861
  isIncomplete,
14754
14862
  includesVariableDecl: typedDecls.some((decl) => decl.type === 1 /* Variable */),
14755
14863
  includesIllegalTypeAliasDecl: !typedDecls.every((decl) => isPossibleTypeAliasDeclaration(decl)),
14864
+ includesSpeculativeResult: false,
14756
14865
  isRecursiveDefinition: !declaredType,
14757
14866
  };
14758
14867
  return result;
@@ -14771,12 +14880,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14771
14880
  }
14772
14881
  }
14773
14882
  // Infer the type.
14774
- const typesToCombine = [];
14775
14883
  const decls = symbol.getDeclarations();
14776
- let isIncomplete = false;
14777
- let sawPendingEvaluation = false;
14778
- let includesVariableDecl = false;
14779
- let includesSpeculativeResult = false;
14780
14884
  let declIndexToConsider;
14781
14885
  // Limit the number of declarations to explore.
14782
14886
  if (decls.length > maxDeclarationsToUseForInference) {
@@ -14785,6 +14889,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14785
14889
  isIncomplete: false,
14786
14890
  includesVariableDecl: false,
14787
14891
  includesIllegalTypeAliasDecl: !decls.every((decl) => isPossibleTypeAliasDeclaration(decl)),
14892
+ includesSpeculativeResult: false,
14788
14893
  isRecursiveDefinition: false,
14789
14894
  };
14790
14895
  addToEffectiveTypeCache(result);
@@ -14811,22 +14916,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14811
14916
  }
14812
14917
  }
14813
14918
  }
14919
+ // Determine which declarations to use for inference.
14920
+ const declsToConsider = [];
14814
14921
  let sawExplicitTypeAlias = false;
14815
14922
  decls.forEach((decl, index) => {
14816
14923
  var _a, _b, _c;
14817
- let considerDecl = declIndexToConsider === undefined || index === declIndexToConsider;
14924
+ if (declIndexToConsider !== undefined && declIndexToConsider !== index) {
14925
+ return;
14926
+ }
14818
14927
  // If we have already seen an explicit type alias, do not consider
14819
14928
  // additional decls. This can happen if multiple TypeAlias declarations
14820
14929
  // are provided -- normally an error, but it can happen in stdlib stubs
14821
14930
  // if the user sets the pythonPlatform to "All".
14822
14931
  if (sawExplicitTypeAlias) {
14823
- considerDecl = false;
14932
+ return;
14824
14933
  }
14825
14934
  // If the symbol is explicitly marked as a ClassVar, consider only the
14826
14935
  // declarations that assign to it from within the class body, not through
14827
14936
  // a member access expression.
14828
14937
  if (symbol.isClassVar() && decl.type === 1 /* Variable */ && decl.isDefinedByMemberAccess) {
14829
- considerDecl = false;
14938
+ return;
14830
14939
  }
14831
14940
  if (usageNode !== undefined) {
14832
14941
  if (decl.type !== 8 /* Alias */) {
@@ -14835,122 +14944,133 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14835
14944
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
14836
14945
  if (usageScope === declScope) {
14837
14946
  if (!isFlowPathBetweenNodes(decl.node, usageNode)) {
14838
- considerDecl = false;
14947
+ return;
14839
14948
  }
14840
14949
  }
14841
14950
  }
14842
14951
  }
14843
- if (considerDecl) {
14844
- const resolvedDecl = (_a = resolveAliasDeclaration(decl, /* resolveLocalNames */ true, {
14845
- allowExternallyHiddenAccess: AnalyzerNodeInfo.getFileInfo(decl.node).isStubFile,
14846
- })) !== null && _a !== void 0 ? _a : decl;
14847
- const isExplicitTypeAlias = isExplicitTypeAliasDeclaration(resolvedDecl);
14848
- const isTypeAlias = isExplicitTypeAlias || isPossibleTypeAliasOrTypedDict(resolvedDecl);
14849
- if (isExplicitTypeAlias) {
14850
- sawExplicitTypeAlias = true;
14851
- }
14852
- // If this is a type alias, evaluate it outside of the recursive symbol
14853
- // resolution check so we can evaluate the full assignment statement.
14854
- if (isTypeAlias &&
14855
- resolvedDecl.type === 1 /* Variable */ &&
14856
- ((_c = (_b = resolvedDecl.inferredTypeSource) === null || _b === void 0 ? void 0 : _b.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
14857
- evaluateTypesForAssignmentStatement(resolvedDecl.inferredTypeSource.parent);
14858
- }
14859
- if (pushSymbolResolution(symbol, decl)) {
14860
- try {
14861
- let type = getInferredTypeOfDeclaration(symbol, decl);
14862
- if (!popSymbolResolution(symbol)) {
14863
- isIncomplete = true;
14864
- }
14865
- if (type) {
14866
- if (resolvedDecl.type === 1 /* Variable */) {
14867
- // Exempt typing.pyi, which uses variables to define some
14868
- // special forms like Any.
14869
- const fileInfo = AnalyzerNodeInfo.getFileInfo(resolvedDecl.node);
14870
- if (!fileInfo.isTypingStubFile) {
14871
- includesVariableDecl = true;
14872
- }
14873
- let isConstant = false;
14874
- if (resolvedDecl.type === 1 /* Variable */) {
14875
- if (resolvedDecl.isConstant || isFinalVariableDeclaration(resolvedDecl)) {
14876
- isConstant = true;
14877
- }
14878
- }
14879
- // Treat enum values declared within an enum class as though they are const even
14880
- // though they may not be named as such.
14881
- if ((0, types_1.isClassInstance)(type) &&
14882
- types_1.ClassType.isEnumClass(type) &&
14883
- (0, enums_1.isDeclInEnumClass)(evaluatorInterface, resolvedDecl)) {
14952
+ const resolvedDecl = (_a = resolveAliasDeclaration(decl, /* resolveLocalNames */ true, {
14953
+ allowExternallyHiddenAccess: AnalyzerNodeInfo.getFileInfo(decl.node).isStubFile,
14954
+ })) !== null && _a !== void 0 ? _a : decl;
14955
+ const isExplicitTypeAlias = isExplicitTypeAliasDeclaration(resolvedDecl);
14956
+ const isTypeAlias = isExplicitTypeAlias || isPossibleTypeAliasOrTypedDict(resolvedDecl);
14957
+ if (isExplicitTypeAlias) {
14958
+ sawExplicitTypeAlias = true;
14959
+ }
14960
+ // If this is a type alias, evaluate it outside of the recursive symbol
14961
+ // resolution check so we can evaluate the full assignment statement.
14962
+ if (isTypeAlias &&
14963
+ resolvedDecl.type === 1 /* Variable */ &&
14964
+ ((_c = (_b = resolvedDecl.inferredTypeSource) === null || _b === void 0 ? void 0 : _b.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 3 /* Assignment */) {
14965
+ evaluateTypesForAssignmentStatement(resolvedDecl.inferredTypeSource.parent);
14966
+ }
14967
+ declsToConsider.push(resolvedDecl);
14968
+ });
14969
+ const evaluationAttempts = ((_b = (_a = cacheEntries === null || cacheEntries === void 0 ? void 0 : cacheEntries.get(effectiveTypeCacheKey)) === null || _a === void 0 ? void 0 : _a.evaluationAttempts) !== null && _b !== void 0 ? _b : 0) + 1;
14970
+ const result = getTypeOfSymbolForDecls(symbol, declsToConsider, evaluationAttempts);
14971
+ // Add the result to the effective type cache if it doesn't include speculative results.
14972
+ if (!result.includesSpeculativeResult) {
14973
+ addToEffectiveTypeCache(result);
14974
+ }
14975
+ return result;
14976
+ function addToEffectiveTypeCache(result) {
14977
+ // Add the entry to the cache so we don't need to compute it next time.
14978
+ if (!cacheEntries) {
14979
+ cacheEntries = new Map();
14980
+ effectiveTypeCache.set(symbol.id, cacheEntries);
14981
+ }
14982
+ cacheEntries.set(effectiveTypeCacheKey, result);
14983
+ }
14984
+ }
14985
+ // Returns the type of a symbol based on a subset of its declarations.
14986
+ function getTypeOfSymbolForDecls(symbol, decls, evaluationAttempts) {
14987
+ const typesToCombine = [];
14988
+ let isIncomplete = false;
14989
+ let sawPendingEvaluation = false;
14990
+ let includesVariableDecl = false;
14991
+ let includesSpeculativeResult = false;
14992
+ decls.forEach((decl) => {
14993
+ if (pushSymbolResolution(symbol, decl)) {
14994
+ try {
14995
+ let type = getInferredTypeOfDeclaration(symbol, decl);
14996
+ if (!popSymbolResolution(symbol)) {
14997
+ isIncomplete = true;
14998
+ }
14999
+ if (type) {
15000
+ if (decl.type === 1 /* Variable */) {
15001
+ // Exempt typing.pyi, which uses variables to define some
15002
+ // special forms like Any.
15003
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(decl.node);
15004
+ if (!fileInfo.isTypingStubFile) {
15005
+ includesVariableDecl = true;
15006
+ }
15007
+ let isConstant = false;
15008
+ if (decl.type === 1 /* Variable */) {
15009
+ if (decl.isConstant || isFinalVariableDeclaration(decl)) {
14884
15010
  isConstant = true;
14885
15011
  }
14886
- // If the symbol is constant, we can retain the literal
14887
- // value. Otherwise, strip literal values to widen the type.
14888
- if (types_1.TypeBase.isInstance(type) && !isExplicitTypeAlias && !isConstant) {
14889
- type = stripLiteralValue(type);
14890
- }
14891
15012
  }
14892
- typesToCombine.push(type);
14893
- if (isSpeculativeModeInUse(decl.node)) {
14894
- includesSpeculativeResult = true;
15013
+ // Treat enum values declared within an enum class as though they are const even
15014
+ // though they may not be named as such.
15015
+ if ((0, types_1.isClassInstance)(type) &&
15016
+ types_1.ClassType.isEnumClass(type) &&
15017
+ (0, enums_1.isDeclInEnumClass)(evaluatorInterface, decl)) {
15018
+ isConstant = true;
15019
+ }
15020
+ // If the symbol is constant, we can retain the literal
15021
+ // value. Otherwise, strip literal values to widen the type.
15022
+ if (types_1.TypeBase.isInstance(type) && !isConstant && !isExplicitTypeAliasDeclaration(decl)) {
15023
+ type = stripLiteralValue(type);
14895
15024
  }
14896
15025
  }
14897
- else {
14898
- isIncomplete = true;
15026
+ typesToCombine.push(type);
15027
+ if (isSpeculativeModeInUse(decl.node)) {
15028
+ includesSpeculativeResult = true;
14899
15029
  }
14900
15030
  }
14901
- catch (e) {
14902
- // Clean up the stack before rethrowing.
14903
- popSymbolResolution(symbol);
14904
- throw e;
15031
+ else {
15032
+ isIncomplete = true;
14905
15033
  }
14906
15034
  }
14907
- else {
14908
- if (resolvedDecl.type === 6 /* Class */) {
14909
- const classTypeInfo = getTypeOfClass(resolvedDecl.node);
14910
- if (classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.decoratedType) {
14911
- typesToCombine.push(classTypeInfo.decoratedType);
14912
- }
15035
+ catch (e) {
15036
+ // Clean up the stack before rethrowing.
15037
+ popSymbolResolution(symbol);
15038
+ throw e;
15039
+ }
15040
+ }
15041
+ else {
15042
+ if (decl.type === 6 /* Class */) {
15043
+ const classTypeInfo = getTypeOfClass(decl.node);
15044
+ if (classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.decoratedType) {
15045
+ typesToCombine.push(classTypeInfo.decoratedType);
14913
15046
  }
14914
- isIncomplete = true;
14915
- // Note that at least one decl could not be evaluated because
14916
- // it was already in the process of being evaluated.
14917
- sawPendingEvaluation = true;
14918
15047
  }
15048
+ isIncomplete = true;
15049
+ // Note that at least one decl could not be evaluated because
15050
+ // it was already in the process of being evaluated.
15051
+ sawPendingEvaluation = true;
14919
15052
  }
14920
15053
  });
14921
- // How many times have we already attempted to evaluate this declaration already?
14922
- const evaluationAttempts = ((_b = (_a = cacheEntries === null || cacheEntries === void 0 ? void 0 : cacheEntries.get(effectiveTypeCacheKey)) === null || _a === void 0 ? void 0 : _a.evaluationAttempts) !== null && _b !== void 0 ? _b : 0) + 1;
14923
- let resultType;
15054
+ let type;
14924
15055
  if (typesToCombine.length > 0) {
14925
15056
  // Ignore the pending evaluation flag if we've already attempted the
14926
15057
  // type evaluation many times because this probably means there's a
14927
15058
  // cyclical dependency that cannot be broken.
14928
15059
  isIncomplete = sawPendingEvaluation && evaluationAttempts < maxEffectiveTypeEvaluationAttempts;
14929
- resultType = (0, types_1.combineTypes)(typesToCombine);
15060
+ type = (0, types_1.combineTypes)(typesToCombine);
14930
15061
  }
14931
15062
  else {
14932
- resultType = types_1.UnboundType.create();
15063
+ type = types_1.UnboundType.create();
14933
15064
  }
14934
- const result = {
14935
- type: resultType,
15065
+ return {
15066
+ type,
14936
15067
  isIncomplete,
14937
15068
  includesVariableDecl,
14938
15069
  includesIllegalTypeAliasDecl: !decls.every((decl) => isPossibleTypeAliasDeclaration(decl)),
15070
+ includesSpeculativeResult,
14939
15071
  isRecursiveDefinition: false,
14940
15072
  evaluationAttempts,
14941
15073
  };
14942
- if (!includesSpeculativeResult) {
14943
- addToEffectiveTypeCache(result);
14944
- }
14945
- return result;
14946
- function addToEffectiveTypeCache(result) {
14947
- // Add the entry to the cache so we don't need to compute it next time.
14948
- if (!cacheEntries) {
14949
- cacheEntries = new Map();
14950
- effectiveTypeCache.set(symbol.id, cacheEntries);
14951
- }
14952
- cacheEntries.set(effectiveTypeCacheKey, result);
14953
- }
14954
15074
  }
14955
15075
  // If a declaration has an explicit type (e.g. a variable with an annotation),
14956
15076
  // this function evaluates the type and returns it. If the symbol has no
@@ -15504,72 +15624,65 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15504
15624
  });
15505
15625
  return isAssignable;
15506
15626
  }
15507
- // Adjusts the source type arguments list to match the length of the
15508
- // dest type arguments list if the dest list contains an unbounded
15509
- // or variadic entry.
15510
- function adjustSourceTupleTypeArgs(destTypeArgs, srcTypeArgs) {
15511
- const destVariadicIndex = destTypeArgs.findIndex((t) => (0, types_1.isVariadicTypeVar)(t.type));
15512
- const destUnboundedIndex = destTypeArgs.findIndex((t) => t.isUnbounded);
15627
+ // Adjusts the source and/or dest type arguments list to attempt to match
15628
+ // the length of the src type arguments list if the dest or source contain
15629
+ // entries with indeterminate length or variadic entries. It returns true
15630
+ // if the source is potentially compatible with the dest type, false otherwise.
15631
+ function adjustSrcTupleTypeArgs(destTypeArgs, srcTypeArgs) {
15632
+ const destUnboundedIndex = destTypeArgs.findIndex((t) => t.isUnbounded || (0, types_1.isVariadicTypeVar)(t.type));
15513
15633
  const srcUnboundedIndex = srcTypeArgs.findIndex((t) => t.isUnbounded);
15514
- // If the source is unbounded, expand the unbounded argument to try
15515
- // to make the source and dest arg counts match.
15634
+ // If the src contains an unbounded type but the dest does not, it's incompatible.
15635
+ if (srcUnboundedIndex >= 0 && destUnboundedIndex < 0) {
15636
+ return false;
15637
+ }
15516
15638
  if (srcUnboundedIndex >= 0) {
15639
+ // The source is unbounded, so expand the unbounded argument to try
15640
+ // to make the source and dest arg counts match.
15517
15641
  const typeToReplicate = srcTypeArgs.length > 0 ? srcTypeArgs[srcUnboundedIndex].type : types_1.AnyType.create();
15518
15642
  while (srcTypeArgs.length < destTypeArgs.length) {
15519
15643
  srcTypeArgs.splice(srcUnboundedIndex, 0, { type: typeToReplicate, isUnbounded: true });
15520
15644
  }
15521
15645
  }
15522
- // If the dest is unbounded or contains a variadic, determine which
15523
- // source args map to the unbounded or variadic arg.
15524
- if (destUnboundedIndex >= 0 || destVariadicIndex >= 0) {
15525
- // If there's a variadic within the destination, package up the corresponding
15526
- // source arguments into a tuple.
15527
- const srcArgsToCapture = srcTypeArgs.length - destTypeArgs.length + 1;
15528
- if (srcArgsToCapture >= 0) {
15529
- if (destVariadicIndex >= 0) {
15530
- if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
15531
- const removedArgs = srcTypeArgs.splice(destVariadicIndex, srcArgsToCapture);
15532
- // Package up the remaining type arguments into a tuple object.
15533
- const variadicTuple = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, removedArgs.map((typeArg) => {
15534
- return { type: typeArg.type, isUnbounded: typeArg.isUnbounded };
15535
- }),
15536
- /* isTypeArgumentExplicit */ true,
15537
- /* isUnpackedTuple */ true));
15538
- srcTypeArgs.splice(destVariadicIndex, 0, {
15539
- type: variadicTuple,
15540
- isUnbounded: false,
15541
- });
15542
- }
15543
- }
15544
- else {
15545
- const removedArgTypes = srcTypeArgs.splice(destUnboundedIndex, srcArgsToCapture).map((t) => {
15546
- if ((0, types_1.isTypeVar)(t.type) && (0, types_1.isUnpackedVariadicTypeVar)(t.type) && !t.type.isVariadicInUnion) {
15547
- return types_1.TypeVarType.cloneForUnpacked(t.type, /* isInUnion */ true);
15548
- }
15549
- return t.type;
15550
- });
15646
+ const srcArgsToCapture = srcTypeArgs.length - destTypeArgs.length + 1;
15647
+ if (destUnboundedIndex >= 0 && srcArgsToCapture >= 0) {
15648
+ // If the dest contains a variadic element, determine which source
15649
+ // args map to this element and package them up into an unpacked tuple.
15650
+ if ((0, types_1.isVariadicTypeVar)(destTypeArgs[destUnboundedIndex].type)) {
15651
+ if (tupleClassType && (0, types_1.isInstantiableClass)(tupleClassType)) {
15652
+ const removedArgs = srcTypeArgs.splice(destUnboundedIndex, srcArgsToCapture);
15653
+ // Package up the remaining type arguments into a tuple object.
15654
+ const variadicTuple = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, removedArgs.map((typeArg) => {
15655
+ return { type: typeArg.type, isUnbounded: typeArg.isUnbounded };
15656
+ }),
15657
+ /* isTypeArgumentExplicit */ true,
15658
+ /* isUnpackedTuple */ true));
15551
15659
  srcTypeArgs.splice(destUnboundedIndex, 0, {
15552
- type: removedArgTypes.length > 0 ? (0, types_1.combineTypes)(removedArgTypes) : types_1.AnyType.create(),
15660
+ type: variadicTuple,
15553
15661
  isUnbounded: false,
15554
15662
  });
15555
15663
  }
15556
15664
  }
15665
+ else {
15666
+ const removedArgTypes = srcTypeArgs.splice(destUnboundedIndex, srcArgsToCapture).map((t) => {
15667
+ if ((0, types_1.isTypeVar)(t.type) && (0, types_1.isUnpackedVariadicTypeVar)(t.type) && !t.type.isVariadicInUnion) {
15668
+ return types_1.TypeVarType.cloneForUnpacked(t.type, /* isInUnion */ true);
15669
+ }
15670
+ return t.type;
15671
+ });
15672
+ srcTypeArgs.splice(destUnboundedIndex, 0, {
15673
+ type: removedArgTypes.length > 0 ? (0, types_1.combineTypes)(removedArgTypes) : types_1.AnyType.create(),
15674
+ isUnbounded: false,
15675
+ });
15676
+ }
15557
15677
  }
15678
+ return destTypeArgs.length === srcTypeArgs.length;
15558
15679
  }
15559
15680
  function assignTupleTypeArguments(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
15560
15681
  var _a, _b;
15561
15682
  const destTypeArgs = [...((_a = destType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [])];
15562
15683
  const srcTypeArgs = [...((_b = srcType.tupleTypeArguments) !== null && _b !== void 0 ? _b : [])];
15563
- let srcUnboundedIndex;
15564
- if (flags & 2 /* ReverseTypeVarMatching */) {
15565
- adjustSourceTupleTypeArgs(srcTypeArgs, destTypeArgs);
15566
- srcUnboundedIndex = destTypeArgs.findIndex((t) => t.isUnbounded);
15567
- }
15568
- else {
15569
- adjustSourceTupleTypeArgs(destTypeArgs, srcTypeArgs);
15570
- srcUnboundedIndex = srcTypeArgs.findIndex((t) => t.isUnbounded);
15571
- }
15572
- if (srcTypeArgs.length === destTypeArgs.length) {
15684
+ const reverseMapping = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
15685
+ if (adjustSrcTupleTypeArgs(reverseMapping ? srcTypeArgs : destTypeArgs, reverseMapping ? destTypeArgs : srcTypeArgs)) {
15573
15686
  for (let argIndex = 0; argIndex < srcTypeArgs.length; argIndex++) {
15574
15687
  const entryDiag = diag === null || diag === void 0 ? void 0 : diag.createAddendum();
15575
15688
  if (!assignType(destTypeArgs[argIndex].type, srcTypeArgs[argIndex].type, entryDiag === null || entryDiag === void 0 ? void 0 : entryDiag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
@@ -15583,13 +15696,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15583
15696
  }
15584
15697
  }
15585
15698
  else {
15586
- if (srcUnboundedIndex < 0) {
15699
+ if (srcTypeArgs.find((t) => t.isUnbounded)) {
15700
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.tupleSizeIndeterminate().format({
15701
+ expected: destTypeArgs.length,
15702
+ }));
15703
+ }
15704
+ else {
15587
15705
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.tupleSizeMismatch().format({
15588
15706
  expected: destTypeArgs.length,
15589
15707
  received: srcTypeArgs.length,
15590
15708
  }));
15591
- return false;
15592
15709
  }
15710
+ return false;
15593
15711
  }
15594
15712
  return true;
15595
15713
  }
@@ -15720,6 +15838,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15720
15838
  const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
15721
15839
  let effectiveFlags;
15722
15840
  let errorSource;
15841
+ let includeDiagAddendum = true;
15723
15842
  if (variance === 3 /* Covariant */) {
15724
15843
  effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
15725
15844
  errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
@@ -15732,6 +15851,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15732
15851
  else {
15733
15852
  effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
15734
15853
  errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
15854
+ // Omit the diagnostic addendum for the invariant case because it's obvious
15855
+ // why two types are not the same.
15856
+ includeDiagAddendum = false;
15735
15857
  }
15736
15858
  if (!assignType(variance === 4 /* Contravariant */ ? srcTypeArg : destTypeArg, variance === 4 /* Contravariant */ ? destTypeArg : srcTypeArg, assignmentDiag, variance === 4 /* Contravariant */ ? srcTypeVarContext : destTypeVarContext, variance === 4 /* Contravariant */ ? destTypeVarContext : srcTypeVarContext, effectiveFlags, recursionCount)) {
15737
15859
  // Don't report errors with type variables in "pseudo-random"
@@ -15744,6 +15866,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15744
15866
  name: types_1.TypeVarType.getReadableName(destTypeParam),
15745
15867
  ...printSrcDestTypes(srcTypeArg, destTypeArg),
15746
15868
  }));
15869
+ if (includeDiagAddendum) {
15870
+ childDiag.addAddendum(assignmentDiag);
15871
+ }
15747
15872
  }
15748
15873
  else {
15749
15874
  diag.addAddendum(assignmentDiag);
@@ -15841,7 +15966,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15841
15966
  if ((0, types_1.isTypeVar)(destType)) {
15842
15967
  if ((0, typeUtils_1.isTypeVarSame)(destType, srcType)) {
15843
15968
  if (destType.scopeId && (destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.hasSolveForScope(destType.scopeId))) {
15844
- return (0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, destType, srcType, diag, destTypeVarContext, flags, recursionCount);
15969
+ // If the dest TypeVar has no current value bound to it, bind itself.
15970
+ if (!destTypeVarContext.getPrimarySignature().getTypeVar(destType)) {
15971
+ return (0, constraintSolver_1.assignTypeToTypeVar)(evaluatorInterface, destType, srcType, diag, destTypeVarContext, flags, recursionCount);
15972
+ }
15845
15973
  }
15846
15974
  return true;
15847
15975
  }
@@ -15942,6 +16070,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15942
16070
  destType.details.parameters.length <= 2) {
15943
16071
  return true;
15944
16072
  }
16073
+ // If the source is an unpacked TypeVarTuple and the dest is a
16074
+ // *tuple[Any, ...], we'll treat it as compatible.
16075
+ if ((0, types_1.isUnpackedVariadicTypeVar)(srcType) &&
16076
+ (0, types_1.isClassInstance)(destType) &&
16077
+ (0, types_1.isUnpackedClass)(destType) &&
16078
+ destType.tupleTypeArguments &&
16079
+ destType.tupleTypeArguments.length === 1 &&
16080
+ destType.tupleTypeArguments[0].isUnbounded &&
16081
+ (0, types_1.isAnyOrUnknown)(destType.tupleTypeArguments[0].type)) {
16082
+ return true;
16083
+ }
15945
16084
  if (!(0, types_1.isUnion)(destType)) {
15946
16085
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
15947
16086
  return false;
@@ -16965,7 +17104,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16965
17104
  }
16966
17105
  }
16967
17106
  }
16968
- else {
17107
+ else if (!srcParamDetails.paramSpec) {
16969
17108
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.functionTooManyParams().format({
16970
17109
  expected: srcPositionalCount,
16971
17110
  received: destPositionalCount,
@@ -17672,8 +17811,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17672
17811
  if (!targetParamType) {
17673
17812
  targetParamType = overrideParamDetails.params[overrideParamDetails.kwargsIndex].type;
17674
17813
  }
17675
- if (!assignType(targetParamType, paramInfo.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)),
17676
- /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
17814
+ if (!assignType(targetParamType, paramInfo.type, 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 */)) {
17677
17815
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamKeywordType().format({
17678
17816
  name: (_b = paramInfo.param.name) !== null && _b !== void 0 ? _b : '?',
17679
17817
  baseType: printType(paramInfo.type),
@@ -17731,8 +17869,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17731
17869
  // Now check the return type.
17732
17870
  const baseReturnType = getFunctionEffectiveReturnType(baseMethod);
17733
17871
  const overrideReturnType = getFunctionEffectiveReturnType(overrideMethod);
17734
- if (!assignType(baseReturnType, overrideReturnType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)),
17735
- /* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */)) {
17872
+ if (!assignType(baseReturnType, overrideReturnType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), 8 /* SkipSolveTypeVars */)) {
17736
17873
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideReturnType().format({
17737
17874
  baseType: printType(baseReturnType),
17738
17875
  overrideType: printType(overrideReturnType),