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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/dist/analyzer/binder.js +8 -2
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +1 -0
  4. package/dist/analyzer/checker.js +123 -70
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +23 -1
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolver.js +2 -1
  9. package/dist/analyzer/constraintSolver.js.map +1 -1
  10. package/dist/analyzer/constructorTransform.js +1 -1
  11. package/dist/analyzer/constructorTransform.js.map +1 -1
  12. package/dist/analyzer/dataClasses.js +242 -236
  13. package/dist/analyzer/dataClasses.js.map +1 -1
  14. package/dist/analyzer/decorators.js +11 -6
  15. package/dist/analyzer/decorators.js.map +1 -1
  16. package/dist/analyzer/deprecatedSymbols.d.ts +9 -0
  17. package/dist/analyzer/deprecatedSymbols.js +292 -0
  18. package/dist/analyzer/deprecatedSymbols.js.map +1 -0
  19. package/dist/analyzer/docStringConversion.js +7 -1
  20. package/dist/analyzer/docStringConversion.js.map +1 -1
  21. package/dist/analyzer/enums.js +12 -0
  22. package/dist/analyzer/enums.js.map +1 -1
  23. package/dist/analyzer/importResolver.js +8 -1
  24. package/dist/analyzer/importResolver.js.map +1 -1
  25. package/dist/analyzer/namedTuples.js +6 -0
  26. package/dist/analyzer/namedTuples.js.map +1 -1
  27. package/dist/analyzer/operations.d.ts +1 -1
  28. package/dist/analyzer/operations.js +2 -2
  29. package/dist/analyzer/operations.js.map +1 -1
  30. package/dist/analyzer/parameterUtils.d.ts +2 -1
  31. package/dist/analyzer/parameterUtils.js +15 -0
  32. package/dist/analyzer/parameterUtils.js.map +1 -1
  33. package/dist/analyzer/program.d.ts +3 -3
  34. package/dist/analyzer/program.js +5 -9
  35. package/dist/analyzer/program.js.map +1 -1
  36. package/dist/analyzer/protocols.js +14 -0
  37. package/dist/analyzer/protocols.js.map +1 -1
  38. package/dist/analyzer/service.js +2 -2
  39. package/dist/analyzer/service.js.map +1 -1
  40. package/dist/analyzer/sourceFile.js +1 -0
  41. package/dist/analyzer/sourceFile.js.map +1 -1
  42. package/dist/analyzer/typeEvaluator.js +713 -529
  43. package/dist/analyzer/typeEvaluator.js.map +1 -1
  44. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
  45. package/dist/analyzer/typeEvaluatorTypes.js +2 -2
  46. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  47. package/dist/analyzer/typeGuards.js +18 -4
  48. package/dist/analyzer/typeGuards.js.map +1 -1
  49. package/dist/analyzer/typePrinter.js +3 -0
  50. package/dist/analyzer/typePrinter.js.map +1 -1
  51. package/dist/analyzer/typeUtils.d.ts +3 -2
  52. package/dist/analyzer/typeUtils.js +30 -7
  53. package/dist/analyzer/typeUtils.js.map +1 -1
  54. package/dist/analyzer/typeVarContext.js +3 -1
  55. package/dist/analyzer/typeVarContext.js.map +1 -1
  56. package/dist/analyzer/types.d.ts +6 -1
  57. package/dist/analyzer/types.js +20 -0
  58. package/dist/analyzer/types.js.map +1 -1
  59. package/dist/common/cancellationUtils.d.ts +2 -1
  60. package/dist/common/cancellationUtils.js +3 -0
  61. package/dist/common/cancellationUtils.js.map +1 -1
  62. package/dist/common/configOptions.d.ts +1 -0
  63. package/dist/common/configOptions.js +5 -1
  64. package/dist/common/configOptions.js.map +1 -1
  65. package/dist/common/diagnosticRules.d.ts +1 -0
  66. package/dist/common/diagnosticRules.js +1 -0
  67. package/dist/common/diagnosticRules.js.map +1 -1
  68. package/dist/common/serviceProvider.d.ts +4 -3
  69. package/dist/languageServerBase.d.ts +2 -2
  70. package/dist/languageServerBase.js +4 -2
  71. package/dist/languageServerBase.js.map +1 -1
  72. package/dist/languageService/completionProvider.js +9 -3
  73. package/dist/languageService/completionProvider.js.map +1 -1
  74. package/dist/localization/localize.d.ts +25 -4
  75. package/dist/localization/localize.js +8 -2
  76. package/dist/localization/localize.js.map +1 -1
  77. package/dist/localization/package.nls.cs.json +15 -12
  78. package/dist/localization/package.nls.de.json +15 -12
  79. package/dist/localization/package.nls.en-us.json +18 -12
  80. package/dist/localization/package.nls.es.json +15 -12
  81. package/dist/localization/package.nls.fr.json +15 -12
  82. package/dist/localization/package.nls.it.json +15 -12
  83. package/dist/localization/package.nls.ja.json +15 -12
  84. package/dist/localization/package.nls.ko.json +15 -12
  85. package/dist/localization/package.nls.pl.json +15 -12
  86. package/dist/localization/package.nls.pt-br.json +15 -12
  87. package/dist/localization/package.nls.qps-ploc.json +15 -12
  88. package/dist/localization/package.nls.ru.json +15 -12
  89. package/dist/localization/package.nls.tr.json +15 -12
  90. package/dist/localization/package.nls.zh-cn.json +15 -12
  91. package/dist/localization/package.nls.zh-tw.json +14 -11
  92. package/dist/parser/parser.d.ts +1 -0
  93. package/dist/parser/parser.js +80 -18
  94. package/dist/parser/parser.js.map +1 -1
  95. package/dist/parser/tokenizer.d.ts +1 -1
  96. package/dist/parser/tokenizer.js +9 -5
  97. package/dist/parser/tokenizer.js.map +1 -1
  98. package/dist/server.js +1 -1
  99. package/dist/server.js.map +1 -1
  100. package/dist/tests/checker.test.js +34 -13
  101. package/dist/tests/checker.test.js.map +1 -1
  102. package/dist/tests/completions.test.js +39 -2
  103. package/dist/tests/completions.test.js.map +1 -1
  104. package/dist/tests/docStringConversion.test.js +23 -0
  105. package/dist/tests/docStringConversion.test.js.map +1 -1
  106. package/dist/tests/harness/fourslash/testState.d.ts +1 -1
  107. package/dist/tests/harness/fourslash/testState.js +2 -2
  108. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  109. package/dist/tests/typeEvaluator1.test.js +8 -4
  110. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  111. package/dist/tests/typeEvaluator2.test.js +13 -1
  112. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  113. package/dist/tests/typeEvaluator3.test.js +21 -23
  114. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  115. package/dist/tests/typeEvaluator4.test.js +21 -1
  116. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  117. package/dist/tests/typeEvaluator5.test.js +33 -1
  118. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  119. package/dist/workspaceFactory.d.ts +1 -1
  120. package/dist/workspaceFactory.js +3 -3
  121. package/dist/workspaceFactory.js.map +1 -1
  122. package/package.json +1 -1
@@ -683,10 +683,30 @@ 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.
689
- if (((_a = type.typeAliasInfo) === null || _a === void 0 ? void 0 : _a.name) && type.typeAliasInfo.isPep695Syntax) {
709
+ if (((_a = type.typeAliasInfo) === null || _a === void 0 ? void 0 : _a.name) && type.typeAliasInfo.isPep695Syntax && types_1.TypeBase.isSpecialForm(type)) {
690
710
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasNotAllowed().format({ name: type.typeAliasInfo.name }), node);
691
711
  return true;
692
712
  }
@@ -980,9 +1000,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
980
1000
  if (options === null || options === void 0 ? void 0 : options.associateTypeVarsWithScope) {
981
1001
  evaluatorFlags |= 8192 /* AssociateTypeVarsWithCurrentScope */;
982
1002
  }
983
- else {
984
- evaluatorFlags |= 4096 /* DisallowTypeVarsWithoutScopeId */;
985
- }
986
1003
  if (options === null || options === void 0 ? void 0 : options.allowUnpackedTypedDict) {
987
1004
  evaluatorFlags |= 8388608 /* AllowUnpackedTypedDict */;
988
1005
  }
@@ -1237,11 +1254,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1237
1254
  let memberInfo;
1238
1255
  const classDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1239
1256
  const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1257
+ let considerMetaclassOnly = (memberAccessFlags & 32 /* ConsiderMetaclassOnly */) !== 0;
1240
1258
  if (types_1.ClassType.isPartiallyEvaluated(classType)) {
1241
1259
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), errorNode);
1242
1260
  return { type: types_1.UnknownType.create() };
1243
1261
  }
1244
- if ((memberAccessFlags & 32 /* ConsiderMetaclassOnly */) === 0) {
1262
+ const metaclass = classType.details.effectiveMetaclass;
1263
+ // Look up the attribute in the metaclass first. If the member is a descriptor
1264
+ // (an object with a __get__ method) and the access is a 'get', the Python runtime
1265
+ // uses this metaclass descriptor to satisfy the lookup. Skip this costly lookup
1266
+ // in the common case where the metaclass is 'type' since we know that `type` doesn't
1267
+ // have any attributes that are descriptors.
1268
+ if (usage.method === 'get' &&
1269
+ metaclass &&
1270
+ (0, types_1.isInstantiableClass)(metaclass) &&
1271
+ !types_1.ClassType.isBuiltIn(metaclass, 'type') &&
1272
+ !types_1.ClassType.isSameGenericClass(metaclass, classType)) {
1273
+ const metaclassMemberInfo = getTypeOfClassMemberName(errorNode, metaclass,
1274
+ /* isAccessedThroughObject */ false, memberName, usage, metaclassDiag, memberAccessFlags, classType);
1275
+ if (metaclassMemberInfo && (0, typeUtils_1.isDescriptorInstance)(metaclassMemberInfo.type)) {
1276
+ considerMetaclassOnly = true;
1277
+ }
1278
+ }
1279
+ // Look up the attribute in the class object.
1280
+ if (!memberInfo && !considerMetaclassOnly) {
1245
1281
  memberInfo = getTypeOfClassMemberName(errorNode, classType,
1246
1282
  /* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
1247
1283
  }
@@ -2507,14 +2543,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2507
2543
  (types_1.ClassType.isBuiltIn(callType, 'TypeVar') ||
2508
2544
  types_1.ClassType.isBuiltIn(callType, 'TypeVarTuple') ||
2509
2545
  types_1.ClassType.isBuiltIn(callType, 'ParamSpec'))) {
2510
- if (target.nodeType !== 38 /* Name */ || target.value !== type.details.name) {
2546
+ const typeVarTarget = target.nodeType === 54 /* TypeAnnotation */ ? target.valueExpression : target;
2547
+ if (typeVarTarget.nodeType !== 38 /* Name */ || typeVarTarget.value !== type.details.name) {
2511
2548
  addError(type.details.isParamSpec
2512
2549
  ? localize_1.Localizer.Diagnostic.paramSpecAssignedName().format({
2513
2550
  name: types_1.TypeVarType.getReadableName(type),
2514
2551
  })
2515
2552
  : localize_1.Localizer.Diagnostic.typeVarAssignedName().format({
2516
2553
  name: types_1.TypeVarType.getReadableName(type),
2517
- }), target);
2554
+ }), typeVarTarget);
2518
2555
  }
2519
2556
  }
2520
2557
  }
@@ -2922,6 +2959,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2922
2959
  }
2923
2960
  }
2924
2961
  }
2962
+ if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
2963
+ reportUseOfTypeCheckOnly(type, node);
2964
+ }
2925
2965
  if ((flags & 16777216 /* DisallowPep695TypeAlias */) !== 0) {
2926
2966
  if (reportInvalidUseOfPep695TypeAlias(type, node)) {
2927
2967
  type = types_1.UnknownType.create();
@@ -3079,7 +3119,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3079
3119
  }
3080
3120
  }
3081
3121
  }
3082
- else if ((flags & 4096 /* DisallowTypeVarsWithoutScopeId */) !== 0) {
3122
+ else if ((flags & 4096 /* AllowTypeVarsWithoutScopeId */) === 0) {
3083
3123
  if ((type.scopeId === undefined || scopedTypeVarInfo.foundInterveningClass) &&
3084
3124
  !type.details.isSynthesized) {
3085
3125
  let message;
@@ -3271,7 +3311,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3271
3311
  4 /* AllowForwardReferences */ |
3272
3312
  524288 /* NotParsedByInterpreter */ |
3273
3313
  2048 /* DisallowTypeVarsWithScopeId */ |
3274
- 4096 /* DisallowTypeVarsWithoutScopeId */ |
3275
3314
  8192 /* AssociateTypeVarsWithCurrentScope */));
3276
3315
  const baseTypeResult = getTypeOfExpression(node.leftExpression, baseTypeFlags);
3277
3316
  if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
@@ -3392,7 +3431,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3392
3431
  }
3393
3432
  return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3394
3433
  }
3395
- if (flags & 256 /* ExpectingTypeAnnotation */) {
3434
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
3396
3435
  if (!isIncomplete) {
3397
3436
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
3398
3437
  type: printType(baseType),
@@ -3616,6 +3655,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3616
3655
  // additional reportUnknownMemberType diagnostics.
3617
3656
  type = isFunctionRule ? types_1.AnyType.create() : types_1.UnknownType.create();
3618
3657
  }
3658
+ if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
3659
+ reportUseOfTypeCheckOnly(type, node.memberName);
3660
+ }
3619
3661
  // Should we specialize the class?
3620
3662
  if ((flags & 2 /* DoNotSpecialize */) === 0) {
3621
3663
  if ((0, types_1.isInstantiableClass)(type) && !type.typeArguments) {
@@ -3708,13 +3750,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3708
3750
  }
3709
3751
  }
3710
3752
  if (!type) {
3753
+ let selfClass = classType;
3711
3754
  // Determine whether to replace Self variables with a specific
3712
3755
  // class. Avoid doing this if there's a "bindToType" specified
3713
3756
  // because that case is used for super() calls where we want
3714
3757
  // to leave the Self type generic (not specialized). We'll also
3715
3758
  // skip this for __new__ methods because they are not bound
3716
3759
  // to the class but rather assume the type of the cls argument.
3717
- const selfClass = !!bindToType || memberName === '__new__' ? undefined : classType;
3760
+ if (bindToType) {
3761
+ if ((0, types_1.isTypeVar)(bindToType) && bindToType.details.isSynthesizedSelf) {
3762
+ selfClass = bindToType;
3763
+ }
3764
+ else {
3765
+ selfClass = undefined;
3766
+ }
3767
+ }
3768
+ else if (memberName === '__new__') {
3769
+ selfClass = undefined;
3770
+ }
3718
3771
  const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3719
3772
  if (typeResult) {
3720
3773
  type = typeResult.type;
@@ -3888,10 +3941,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3888
3941
  },
3889
3942
  ];
3890
3943
  if (usage.method === 'get') {
3891
- // Provide "objtype" argument.
3944
+ // Provide "owner" argument.
3892
3945
  argList.push({
3893
3946
  argumentCategory: 0 /* Simple */,
3894
- typeResult: { type: baseTypeClass },
3947
+ typeResult: {
3948
+ type: baseTypeClass,
3949
+ },
3895
3950
  });
3896
3951
  }
3897
3952
  else if (usage.method === 'set') {
@@ -4248,14 +4303,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4248
4303
  function getTypeOfIndex(node, flags = 0 /* None */) {
4249
4304
  const baseTypeResult = getTypeOfExpression(node.baseExpression, flags | 2 /* IndexBaseDefaults */);
4250
4305
  // If this is meant to be a type and the base expression is a string expression,
4251
- // emit an error because this will generate a runtime exception in Python versions
4252
- // less than 3.10.
4306
+ // emit an error because this is an illegal annotation form and will generate a
4307
+ // runtime exception.
4253
4308
  if (flags & 128 /* ExpectingInstantiableType */) {
4254
4309
  if (node.baseExpression.nodeType === 48 /* StringList */) {
4255
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4256
- if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
4257
- addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
4258
- }
4310
+ addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
4259
4311
  }
4260
4312
  }
4261
4313
  // Check for builtin classes that will generate runtime exceptions if subscripted.
@@ -4487,6 +4539,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4487
4539
  if ((0, types_1.isParamSpec)(typeArg)) {
4488
4540
  functionType.details.paramSpec = typeArg;
4489
4541
  }
4542
+ else if ((0, typeUtils_1.isEllipsisType)(typeArg)) {
4543
+ types_1.FunctionType.addDefaultParameters(functionType);
4544
+ functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
4545
+ }
4490
4546
  }
4491
4547
  else {
4492
4548
  types_1.FunctionType.addParameter(functionType, {
@@ -4601,7 +4657,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4601
4657
  const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
4602
4658
  /* usage */ undefined,
4603
4659
  /* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 32 /* ConsiderMetaclassOnly */);
4604
- if (flags & 256 /* ExpectingTypeAnnotation */) {
4660
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
4605
4661
  // If the class doesn't derive from Generic, a type argument should not be allowed.
4606
4662
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
4607
4663
  name: printType(types_1.ClassType.cloneAsInstance(concreteSubtype)),
@@ -4653,9 +4709,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4653
4709
  // Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
4654
4710
  // This feature is currently experimental.
4655
4711
  const supportsTypedDictTypeArg = AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
4656
- (0, types_1.isInstantiableClass)(concreteSubtype) &&
4657
- types_1.ClassType.isBuiltIn(concreteSubtype, 'dict') &&
4658
- !concreteSubtype.aliasName;
4712
+ types_1.ClassType.isBuiltIn(concreteSubtype, ['dict', 'TypedDict']) &&
4713
+ !types_1.ClassType.isBuiltIn(concreteSubtype, 'Dict');
4659
4714
  let typeArgs = getTypeArgs(node, flags, {
4660
4715
  isAnnotatedClass,
4661
4716
  hasCustomClassGetItem: hasCustomClassGetItem || !isGenericClass,
@@ -4866,14 +4921,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4866
4921
  typeof valueType.literalValue === 'number') {
4867
4922
  const indexValue = valueType.literalValue;
4868
4923
  const tupleType = (0, typeUtils_1.getSpecializedTupleType)(baseType);
4869
- if (tupleType && tupleType.tupleTypeArguments && !(0, typeUtils_1.isUnboundedTupleClass)(tupleType)) {
4870
- if (indexValue >= 0 && indexValue < tupleType.tupleTypeArguments.length) {
4871
- return { type: tupleType.tupleTypeArguments[indexValue].type };
4872
- }
4873
- else if (indexValue < 0 && tupleType.tupleTypeArguments.length + indexValue >= 0) {
4874
- return {
4875
- type: tupleType.tupleTypeArguments[tupleType.tupleTypeArguments.length + indexValue].type,
4876
- };
4924
+ if (tupleType && tupleType.tupleTypeArguments) {
4925
+ if ((0, typeUtils_1.isTupleIndexUnambiguous)(tupleType, indexValue)) {
4926
+ if (indexValue >= 0 && indexValue < tupleType.tupleTypeArguments.length) {
4927
+ return { type: tupleType.tupleTypeArguments[indexValue].type };
4928
+ }
4929
+ else if (indexValue < 0 && tupleType.tupleTypeArguments.length + indexValue >= 0) {
4930
+ return {
4931
+ type: tupleType.tupleTypeArguments[tupleType.tupleTypeArguments.length + indexValue]
4932
+ .type,
4933
+ };
4934
+ }
4877
4935
  }
4878
4936
  }
4879
4937
  }
@@ -5623,7 +5681,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5623
5681
  if (node.arguments.length > 2) {
5624
5682
  addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
5625
5683
  }
5626
- const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
5684
+ const enclosingFunction = ParseTreeUtils.getEnclosingFunction(node);
5685
+ const enclosingClass = enclosingFunction
5686
+ ? ParseTreeUtils.getEnclosingClass(enclosingFunction, /* stopAtFunction */ true)
5687
+ : undefined;
5627
5688
  const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
5628
5689
  // Determine which class the "super" call is applied to. If
5629
5690
  // there is no first argument, then the class is implicit.
@@ -5663,7 +5724,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5663
5724
  }
5664
5725
  else if ((0, types_1.isInstantiableClass)(secondArgType)) {
5665
5726
  if ((0, types_1.isInstantiableClass)(targetClassType)) {
5666
- if (!(0, typeUtils_1.derivesFromClassRecursive)(secondArgType, targetClassType, /* ignoreUnknown */ true)) {
5727
+ if (!types_1.ClassType.isBuiltIn(targetClassType, 'type') &&
5728
+ !(0, typeUtils_1.derivesFromClassRecursive)(secondArgType, targetClassType, /* ignoreUnknown */ true)) {
5667
5729
  reportError = true;
5668
5730
  }
5669
5731
  }
@@ -5793,13 +5855,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5793
5855
  return argParamCopy;
5794
5856
  });
5795
5857
  }
5796
- // Clone the typeVarContext so we don't modify the original. If this is
5797
- // not the first time through the loop, clone the type var context
5798
- // from the previous successful match.
5799
- const typeVarContextToClone = matchedOverloads.length > 0
5800
- ? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
5801
- : typeVarContext;
5802
- 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));
5858
+ // Clone the typeVarContext so we don't modify the original.
5859
+ 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));
5803
5860
  effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
5804
5861
  effectiveTypeVarContext.unlock();
5805
5862
  // Use speculative mode so we don't output any diagnostics or
@@ -6294,23 +6351,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6294
6351
  }
6295
6352
  }
6296
6353
  }
6354
+ let effectiveTypeVarContext = typeVarContext;
6355
+ if (!effectiveTypeVarContext) {
6356
+ // If a typeVarContext wasn't provided by the caller, allocate one here.
6357
+ effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
6358
+ }
6297
6359
  // The stdlib collections/__init__.pyi stub file defines namedtuple
6298
6360
  // as a function rather than a class, so we need to check for it here.
6299
6361
  if (expandedCallType.details.builtInName === 'namedtuple') {
6300
6362
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
6301
- return {
6363
+ const result = {
6302
6364
  returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ false),
6303
6365
  };
6366
+ validateFunctionArguments(errorNode, argList, { type: expandedCallType }, effectiveTypeVarContext, skipUnknownArgCheck);
6367
+ return result;
6304
6368
  }
6305
6369
  // Handle the NewType specially, replacing the normal return type.
6306
6370
  if (expandedCallType.details.builtInName === 'NewType') {
6307
6371
  return { returnType: createNewType(errorNode, argList) };
6308
6372
  }
6309
- let effectiveTypeVarContext = typeVarContext;
6310
- if (!effectiveTypeVarContext) {
6311
- // If a typeVarContext wasn't provided by the caller, allocate one here.
6312
- effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
6313
- }
6314
6373
  const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
6315
6374
  let isTypeIncomplete = !!functionResult.isTypeIncomplete;
6316
6375
  let returnType = functionResult.returnType;
@@ -6437,9 +6496,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6437
6496
  }
6438
6497
  }
6439
6498
  if (className === 'NamedTuple') {
6440
- return {
6499
+ const result = {
6441
6500
  returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
6442
6501
  };
6502
+ const initTypeResult = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(expandedCallType), '__init__');
6503
+ if (initTypeResult && (0, types_1.isOverloadedFunction)(initTypeResult.type)) {
6504
+ validateOverloadedFunctionArguments(errorNode, argList, { type: initTypeResult.type },
6505
+ /* typeVarContext */ undefined, skipUnknownArgCheck,
6506
+ /* inferenceContext */ undefined);
6507
+ }
6508
+ return result;
6443
6509
  }
6444
6510
  if (className === 'NewType') {
6445
6511
  return { returnType: createNewType(errorNode, argList) };
@@ -6537,7 +6603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6537
6603
  var _a, _b;
6538
6604
  const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6539
6605
  /* usage */ undefined,
6540
- /* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
6606
+ /* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 1 /* AccessClassMembersOnly */)) === null || _a === void 0 ? void 0 : _a.type;
6541
6607
  if (!memberType) {
6542
6608
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6543
6609
  type: printType(expandedCallType),
@@ -7940,6 +8006,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7940
8006
  const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
7941
8007
  const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
7942
8008
  const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
8009
+ const nestedArgList = [];
7943
8010
  argList.forEach((arg) => {
7944
8011
  var _a;
7945
8012
  if (arg.argumentCategory === 0 /* Simple */) {
@@ -7969,6 +8036,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7969
8036
  else if (argsParam) {
7970
8037
  paramType = argsParam.type;
7971
8038
  }
8039
+ else if (paramSpecType.details.paramSpec) {
8040
+ nestedArgList.push(arg);
8041
+ }
7972
8042
  else {
7973
8043
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, paramSpecParams.length === 1
7974
8044
  ? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
@@ -8014,6 +8084,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8014
8084
  }
8015
8085
  }
8016
8086
  });
8087
+ // Handle recursive ParamSpecs.
8088
+ if (paramSpecType.details.paramSpec) {
8089
+ const boundTypeForParamSpec = srcTypeVarContext
8090
+ .getPrimarySignature()
8091
+ .getParamSpecType(paramSpecType.details.paramSpec);
8092
+ if (boundTypeForParamSpec) {
8093
+ const paramSpecArgResult = validateFunctionArgumentsForParamSpec(errorNode, nestedArgList, paramSpecType.details.paramSpec, srcTypeVarContext, conditionFilter);
8094
+ if (paramSpecArgResult.argumentErrors) {
8095
+ reportedArgError = true;
8096
+ }
8097
+ }
8098
+ }
8017
8099
  });
8018
8100
  }
8019
8101
  // Report any missing parameters.
@@ -8051,10 +8133,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8051
8133
  let isCompatible = true;
8052
8134
  const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
8053
8135
  let skippedBareTypeVarExpectedType = false;
8136
+ let skipSolveTypeVars = false;
8054
8137
  if (argParam.argument.valueExpression) {
8055
8138
  let expectedType;
8056
- const isBareTypeVarExpectedType = (0, types_1.isTypeVar)(argParam.paramType) && argParam.paramType.scopeId === (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId);
8057
- if (!options.skipBareTypeVarExpectedType || !isBareTypeVarExpectedType) {
8139
+ // Is the expected type a "bare" in-scope TypeVar or a union of bare in-scope TypeVars?
8140
+ let isExpectedTypeBareTypeVar = true;
8141
+ (0, typeUtils_1.doForEachSubtype)(argParam.paramType, (subtype) => {
8142
+ if (!(0, types_1.isTypeVar)(subtype) || subtype.scopeId !== (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId)) {
8143
+ isExpectedTypeBareTypeVar = false;
8144
+ }
8145
+ });
8146
+ if (!options.skipBareTypeVarExpectedType || !isExpectedTypeBareTypeVar) {
8058
8147
  expectedType = argParam.paramType;
8059
8148
  // If the parameter type is a function with a ParamSpec, don't apply
8060
8149
  // the solved TypeVars if the typeVarContext has more than one signature.
@@ -8070,6 +8159,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8070
8159
  }
8071
8160
  else {
8072
8161
  skippedBareTypeVarExpectedType = true;
8162
+ // If the expected type is a union of bare TypeVars, it's not clear which of the two
8163
+ // (or both) should be constrained. We'll skip any attempt to solve the TypeVars during
8164
+ // this pass and hope that subsequent arg assignments will help us establish the correct
8165
+ // constraints.
8166
+ if ((0, types_1.isUnion)(argParam.paramType)) {
8167
+ skipSolveTypeVars = true;
8168
+ }
8073
8169
  }
8074
8170
  // If the expected type is unknown, don't use an expected type. Instead,
8075
8171
  // use default rules for evaluating the expression type.
@@ -8186,7 +8282,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8186
8282
  }
8187
8283
  }
8188
8284
  if ((0, types_1.isClassInstance)(argType)) {
8189
- const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__');
8285
+ const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 8 /* SkipInstanceVariables */);
8190
8286
  if (callMember) {
8191
8287
  const memberType = getTypeOfMember(callMember);
8192
8288
  if ((0, types_1.isOverloadedFunction)(memberType)) {
@@ -8203,7 +8299,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8203
8299
  }
8204
8300
  }
8205
8301
  }
8206
- if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext)) {
8302
+ if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext,
8303
+ /* srcTypeVarContext */ undefined, skipSolveTypeVars ? 8 /* SkipSolveTypeVars */ : undefined)) {
8207
8304
  // Mismatching parameter types are common in untyped code; don't bother spending time
8208
8305
  // printing types if the diagnostic is disabled.
8209
8306
  const fileInfo = AnalyzerNodeInfo.getFileInfo(argParam.errorNode);
@@ -8637,7 +8734,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8637
8734
  typeParameters = [];
8638
8735
  let isTypeParamListValid = true;
8639
8736
  typeParamsExpr.expressions.map((expr) => {
8640
- let entryType = getTypeOfExpression(expr, 128 /* ExpectingInstantiableType */).type;
8737
+ let entryType = getTypeOfExpression(expr, 128 /* ExpectingInstantiableType */ | 4096 /* AllowTypeVarsWithoutScopeId */).type;
8641
8738
  if ((0, types_1.isTypeVar)(entryType)) {
8642
8739
  if (entryType.scopeId) {
8643
8740
  isTypeParamListValid = false;
@@ -8937,7 +9034,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8937
9034
  }
8938
9035
  function getTypeOfDictionaryWithContext(node, inferenceContext, expectedDiagAddendum) {
8939
9036
  inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
8940
- const concreteExpectedType = makeTopLevelTypeVarsConcrete(inferenceContext.expectedType);
9037
+ let concreteExpectedType = makeTopLevelTypeVarsConcrete(inferenceContext.expectedType);
8941
9038
  if (!(0, types_1.isClassInstance)(concreteExpectedType)) {
8942
9039
  return undefined;
8943
9040
  }
@@ -8946,6 +9043,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8946
9043
  let isIncomplete = false;
8947
9044
  // Handle TypedDict's as a special case.
8948
9045
  if (types_1.ClassType.isTypedDictClass(concreteExpectedType)) {
9046
+ // Remove any conditions associated with the type so the resulting type isn't
9047
+ // considered compatible with a bound TypeVar.
9048
+ concreteExpectedType = types_1.TypeBase.cloneForCondition(concreteExpectedType, undefined);
8949
9049
  const expectedTypedDictEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface, concreteExpectedType);
8950
9050
  // Infer the key and value types if possible.
8951
9051
  if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
@@ -8955,17 +9055,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8955
9055
  /* expectedValueType */ undefined, expectedTypedDictEntries, expectedDiagAddendum)) {
8956
9056
  isIncomplete = true;
8957
9057
  }
8958
- if (types_1.ClassType.isTypedDictClass(concreteExpectedType)) {
8959
- const resultTypedDict = (0, typedDicts_1.assignToTypedDict)(evaluatorInterface, concreteExpectedType, keyTypes, valueTypes,
8960
- // Don't overwrite existing expectedDiagAddendum messages if they were
8961
- // already provided by getKeyValueTypesFromDictionary.
8962
- (expectedDiagAddendum === null || expectedDiagAddendum === void 0 ? void 0 : expectedDiagAddendum.isEmpty()) ? expectedDiagAddendum : undefined);
8963
- if (resultTypedDict) {
8964
- return {
8965
- type: resultTypedDict,
8966
- isIncomplete,
8967
- };
8968
- }
9058
+ const resultTypedDict = (0, typedDicts_1.assignToTypedDict)(evaluatorInterface, concreteExpectedType, keyTypes, valueTypes,
9059
+ // Don't overwrite existing expectedDiagAddendum messages if they were
9060
+ // already provided by getKeyValueTypesFromDictionary.
9061
+ (expectedDiagAddendum === null || expectedDiagAddendum === void 0 ? void 0 : expectedDiagAddendum.isEmpty()) ? expectedDiagAddendum : undefined);
9062
+ if (resultTypedDict) {
9063
+ return {
9064
+ type: resultTypedDict,
9065
+ isIncomplete,
9066
+ };
8969
9067
  }
8970
9068
  return undefined;
8971
9069
  }
@@ -9901,6 +9999,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9901
9999
  if ((0, types_1.isParamSpec)(typeArg)) {
9902
10000
  functionType.details.paramSpec = typeArg;
9903
10001
  }
10002
+ else if ((0, typeUtils_1.isEllipsisType)(typeArg)) {
10003
+ types_1.FunctionType.addDefaultParameters(functionType);
10004
+ functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
10005
+ }
9904
10006
  }
9905
10007
  else {
9906
10008
  types_1.FunctionType.addParameter(functionType, {
@@ -10279,7 +10381,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10279
10381
  else {
10280
10382
  typeArgs.forEach((typeArg, index) => {
10281
10383
  if (index === typeArgs.length - 1) {
10282
- if (!(0, types_1.isParamSpec)(typeArg.type)) {
10384
+ if (!(0, types_1.isParamSpec)(typeArg.type) && !(0, typeUtils_1.isEllipsisType)(typeArg.type)) {
10283
10385
  addError(localize_1.Localizer.Diagnostic.concatenateParamSpecMissing(), typeArg.node);
10284
10386
  }
10285
10387
  }
@@ -10337,7 +10439,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10337
10439
  typeArgs.forEach((typeArg, index) => {
10338
10440
  if ((0, typeUtils_1.isEllipsisType)(typeArg.type)) {
10339
10441
  if (!isTupleTypeParam) {
10340
- addError(localize_1.Localizer.Diagnostic.ellipsisContext(), typeArg.node);
10442
+ if (!allowParamSpec) {
10443
+ addError(localize_1.Localizer.Diagnostic.ellipsisContext(), typeArg.node);
10444
+ }
10341
10445
  }
10342
10446
  else if (typeArgs.length !== 2 || index !== 1) {
10343
10447
  addError(localize_1.Localizer.Diagnostic.ellipsisSecondArg(), typeArg.node);
@@ -10555,7 +10659,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10555
10659
  names: boundTypeVars.map((t) => `${t.details.name}`).join(', '),
10556
10660
  }), errorNode);
10557
10661
  }
10558
- return types_1.TypeBase.cloneForTypeAlias(type, name.value, ParseTreeUtils.getClassFullName(name, fileInfo.moduleName, name.value), typeAliasScopeId, isPep695Syntax, typeParameters.length > 0 ? typeParameters : undefined);
10662
+ const typeAlias = types_1.TypeBase.cloneForTypeAlias(type, name.value, ParseTreeUtils.getClassFullName(name, fileInfo.moduleName, name.value), typeAliasScopeId, isPep695Syntax, typeParameters.length > 0 ? typeParameters : undefined);
10663
+ // All PEP 695 type aliases are special forms because they are
10664
+ // TypeAliasType objects at runtime.
10665
+ if (isPep695Syntax) {
10666
+ typeAlias.flags |= 8 /* SpecialForm */;
10667
+ }
10668
+ return typeAlias;
10559
10669
  }
10560
10670
  function createSpecialBuiltInClass(node, assignedName, aliasMapEntry) {
10561
10671
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
@@ -10583,7 +10693,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10583
10693
  // methods that are abstract are overridden and shouldn't
10584
10694
  // cause the TypedDict to be marked as abstract.
10585
10695
  if ((0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, '_TypedDict')) {
10586
- baseClass.details.flags &= ~1024 /* SupportsAbstractMethods */;
10696
+ baseClass = types_1.ClassType.cloneWithNewFlags(baseClass, baseClass.details.flags &
10697
+ ~(1024 /* SupportsAbstractMethods */ | 134217728 /* TypeCheckOnly */));
10587
10698
  }
10588
10699
  }
10589
10700
  }
@@ -10701,7 +10812,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10701
10812
  return undefined;
10702
10813
  }
10703
10814
  function evaluateTypesForAssignmentStatement(node) {
10704
- var _a;
10815
+ var _a, _b;
10705
10816
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
10706
10817
  // If the entire statement has already been evaluated, don't
10707
10818
  // re-evaluate it.
@@ -10800,20 +10911,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10800
10911
  srcType = types_1.ClassType.cloneWithLiteral(boolType, constExprValue);
10801
10912
  }
10802
10913
  }
10803
- // If there was a declared type, make sure the RHS value is compatible.
10804
- if (declaredType) {
10805
- if (assignType(declaredType, srcType)) {
10806
- // Narrow the resulting type if possible.
10807
- if (!(0, types_1.isAnyOrUnknown)(srcType)) {
10808
- srcType = narrowTypeBasedOnAssignment(node, declaredType, srcType);
10809
- }
10810
- }
10811
- }
10812
10914
  // If this is an enum, transform the type as required.
10813
10915
  rightHandType = srcType;
10814
10916
  if (node.leftExpression.nodeType === 38 /* Name */ && !node.typeAnnotationComment) {
10815
10917
  rightHandType =
10816
- (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, node.leftExpression, () => rightHandType) || rightHandType;
10918
+ (_a = (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, node.leftExpression, () => rightHandType)) !== null && _a !== void 0 ? _a : rightHandType;
10817
10919
  }
10818
10920
  if (typeAliasNameNode) {
10819
10921
  // If this was a speculative type alias, it becomes a real type alias
@@ -10834,7 +10936,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10834
10936
  typeAliasTypeVar.details.boundType = rightHandType;
10835
10937
  // Record the type parameters within the recursive type alias so it
10836
10938
  // can be specialized.
10837
- typeAliasTypeVar.details.recursiveTypeParameters = (_a = rightHandType.typeAliasInfo) === null || _a === void 0 ? void 0 : _a.typeParameters;
10939
+ typeAliasTypeVar.details.recursiveTypeParameters = (_b = rightHandType.typeAliasInfo) === null || _b === void 0 ? void 0 : _b.typeParameters;
10838
10940
  }
10839
10941
  }
10840
10942
  }
@@ -10998,447 +11100,465 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10998
11100
  setSymbolResolutionPartialType(classSymbol, classDecl, classType);
10999
11101
  }
11000
11102
  classType.details.flags |= 131072 /* PartiallyEvaluated */;
11001
- writeTypeCache(node, { type: classType }, /* flags */ undefined);
11002
- writeTypeCache(node.name, { type: classType }, /* flags */ undefined);
11003
- // Keep a list of unique type parameters that are used in the
11004
- // base class arguments.
11005
- let typeParameters = [];
11006
- if (node.typeParameters) {
11007
- typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
11008
- }
11009
- // If the class derives from "Generic" directly, it will provide
11010
- // all of the type parameters in the specified order.
11011
- let genericTypeParameters;
11012
- let protocolTypeParameters;
11013
- const initSubclassArgs = [];
11014
- let metaclassNode;
11015
- let exprFlags = 128 /* ExpectingInstantiableType */ |
11016
- 1024 /* AllowGenericClassType */ |
11017
- 262144 /* DisallowNakedGeneric */ |
11018
- 2048 /* DisallowTypeVarsWithScopeId */ |
11019
- 8192 /* AssociateTypeVarsWithCurrentScope */ |
11020
- 16384 /* EnforceTypeVarVarianceConsistency */ |
11021
- 16777216 /* DisallowPep695TypeAlias */;
11022
- if (fileInfo.isStubFile) {
11023
- exprFlags |= 4 /* AllowForwardReferences */;
11024
- }
11025
- node.arguments.forEach((arg) => {
11026
- // Ignore unpacked arguments.
11027
- if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
11028
- // Evaluate the expression's type so symbols are marked accessed
11029
- // and errors are reported.
11030
- getTypeOfExpression(arg.valueExpression);
11031
- return;
11103
+ try {
11104
+ writeTypeCache(node, { type: classType }, /* flags */ undefined);
11105
+ writeTypeCache(node.name, { type: classType }, /* flags */ undefined);
11106
+ // Keep a list of unique type parameters that are used in the
11107
+ // base class arguments.
11108
+ let typeParameters = [];
11109
+ if (node.typeParameters) {
11110
+ typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
11111
+ }
11112
+ // If the class derives from "Generic" directly, it will provide
11113
+ // all of the type parameters in the specified order.
11114
+ let genericTypeParameters;
11115
+ let protocolTypeParameters;
11116
+ const initSubclassArgs = [];
11117
+ let metaclassNode;
11118
+ let exprFlags = 128 /* ExpectingInstantiableType */ |
11119
+ 1024 /* AllowGenericClassType */ |
11120
+ 262144 /* DisallowNakedGeneric */ |
11121
+ 2048 /* DisallowTypeVarsWithScopeId */ |
11122
+ 8192 /* AssociateTypeVarsWithCurrentScope */ |
11123
+ 16384 /* EnforceTypeVarVarianceConsistency */ |
11124
+ 16777216 /* DisallowPep695TypeAlias */;
11125
+ if (fileInfo.isStubFile) {
11126
+ exprFlags |= 4 /* AllowForwardReferences */;
11032
11127
  }
11033
- if (!arg.name) {
11034
- let argType;
11035
- if (arg.argumentCategory === 1 /* UnpackedList */) {
11128
+ node.arguments.forEach((arg) => {
11129
+ // Ignore unpacked arguments.
11130
+ if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
11131
+ // Evaluate the expression's type so symbols are marked accessed
11132
+ // and errors are reported.
11036
11133
  getTypeOfExpression(arg.valueExpression);
11037
- argType = types_1.UnknownType.create();
11134
+ return;
11038
11135
  }
11039
- else {
11040
- argType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(arg.valueExpression, exprFlags).type);
11041
- }
11042
- // In some stub files, classes are conditionally defined (e.g. based
11043
- // on platform type). We'll assume that the conditional logic is correct
11044
- // and strip off the "unbound" union.
11045
- if ((0, types_1.isUnion)(argType)) {
11046
- argType = (0, types_1.removeUnbound)(argType);
11047
- }
11048
- if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
11049
- if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
11050
- (0, debug_1.assert)((0, types_1.isClassInstance)(argType));
11051
- argType =
11052
- argType.typeArguments && argType.typeArguments.length > 0
11053
- ? argType.typeArguments[0]
11054
- : types_1.UnknownType.create();
11055
- }
11056
- else if (!(0, types_1.isInstantiableClass)(argType)) {
11057
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
11136
+ if (!arg.name) {
11137
+ let argType;
11138
+ if (arg.argumentCategory === 1 /* UnpackedList */) {
11139
+ getTypeOfExpression(arg.valueExpression);
11058
11140
  argType = types_1.UnknownType.create();
11059
11141
  }
11060
11142
  else {
11061
- if (types_1.ClassType.isPartiallyEvaluated(argType) ||
11062
- argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
11063
- // If the base class is partially evaluated, install a callback
11064
- // so we can fix up this class (e.g. compute the MRO) when the
11065
- // dependent class is completed.
11066
- registerDeferredClassCompletion(node, argType);
11143
+ argType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(arg.valueExpression, exprFlags).type);
11144
+ }
11145
+ // In some stub files, classes are conditionally defined (e.g. based
11146
+ // on platform type). We'll assume that the conditional logic is correct
11147
+ // and strip off the "unbound" union.
11148
+ if ((0, types_1.isUnion)(argType)) {
11149
+ argType = (0, types_1.removeUnbound)(argType);
11150
+ }
11151
+ if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
11152
+ if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
11153
+ (0, debug_1.assert)((0, types_1.isClassInstance)(argType));
11154
+ argType =
11155
+ argType.typeArguments && argType.typeArguments.length > 0
11156
+ ? argType.typeArguments[0]
11157
+ : types_1.UnknownType.create();
11067
11158
  }
11068
- if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
11069
- if (!fileInfo.isStubFile &&
11070
- !types_1.ClassType.isTypingExtensionClass(argType) &&
11071
- fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_7) {
11072
- addError(localize_1.Localizer.Diagnostic.protocolIllegal(), arg.valueExpression);
11159
+ else if (!(0, types_1.isInstantiableClass)(argType)) {
11160
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
11161
+ argType = types_1.UnknownType.create();
11162
+ }
11163
+ else {
11164
+ if (types_1.ClassType.isPartiallyEvaluated(argType) ||
11165
+ argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
11166
+ // If the base class is partially evaluated, install a callback
11167
+ // so we can fix up this class (e.g. compute the MRO) when the
11168
+ // dependent class is completed.
11169
+ registerDeferredClassCompletion(node, argType);
11170
+ }
11171
+ if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
11172
+ if (!fileInfo.isStubFile &&
11173
+ !types_1.ClassType.isTypingExtensionClass(argType) &&
11174
+ fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_7) {
11175
+ addError(localize_1.Localizer.Diagnostic.protocolIllegal(), arg.valueExpression);
11176
+ }
11177
+ classType.details.flags |= 8192 /* ProtocolClass */;
11178
+ }
11179
+ if (types_1.ClassType.isBuiltIn(argType, 'property')) {
11180
+ classType.details.flags |= 2048 /* PropertyClass */;
11181
+ }
11182
+ // If the class directly derives from NamedTuple (in Python 3.6 or
11183
+ // newer), it's considered a (read-only) dataclass.
11184
+ if (fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
11185
+ if (types_1.ClassType.isBuiltIn(argType, 'NamedTuple')) {
11186
+ classType.details.flags |=
11187
+ 4 /* DataClass */ |
11188
+ 32 /* SkipSynthesizedDataClassEq */ |
11189
+ 16777216 /* ReadOnlyInstanceVariables */;
11190
+ }
11191
+ }
11192
+ // If the class directly derives from TypedDict or from a class that is
11193
+ // a TypedDict, it is considered a TypedDict.
11194
+ if (types_1.ClassType.isBuiltIn(argType, 'TypedDict') || types_1.ClassType.isTypedDictClass(argType)) {
11195
+ classType.details.flags |= 128 /* TypedDictClass */;
11196
+ }
11197
+ else if (types_1.ClassType.isTypedDictClass(classType) && !types_1.ClassType.isTypedDictClass(argType)) {
11198
+ // Exempt Generic from this test. As of Python 3.11, generic TypedDict
11199
+ // classes are supported.
11200
+ if (!(0, types_1.isInstantiableClass)(argType) || !types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11201
+ // TypedDict classes must derive only from other TypedDict classes.
11202
+ addError(localize_1.Localizer.Diagnostic.typedDictBaseClass(), arg);
11203
+ }
11204
+ }
11205
+ // Validate that the class isn't deriving from itself, creating a
11206
+ // circular dependency.
11207
+ if ((0, typeUtils_1.derivesFromClassRecursive)(argType, classType, /* ignoreUnknown */ true)) {
11208
+ addError(localize_1.Localizer.Diagnostic.baseClassCircular(), arg);
11209
+ argType = types_1.UnknownType.create();
11073
11210
  }
11074
- classType.details.flags |= 8192 /* ProtocolClass */;
11075
11211
  }
11076
- if (types_1.ClassType.isBuiltIn(argType, 'property')) {
11077
- classType.details.flags |= 2048 /* PropertyClass */;
11212
+ }
11213
+ if ((0, types_1.isUnknown)(argType)) {
11214
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedBaseClass, diagnosticRules_1.DiagnosticRule.reportUntypedBaseClass, localize_1.Localizer.Diagnostic.baseClassUnknown(), arg);
11215
+ }
11216
+ // Check for a duplicate class.
11217
+ if (classType.details.baseClasses.some((prevBaseClass) => {
11218
+ return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
11219
+ (0, types_1.isInstantiableClass)(argType) &&
11220
+ types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
11221
+ })) {
11222
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
11223
+ }
11224
+ classType.details.baseClasses.push(argType);
11225
+ if ((0, types_1.isInstantiableClass)(argType)) {
11226
+ if (types_1.ClassType.isEnumClass(argType)) {
11227
+ classType.details.flags |= 1048576 /* EnumClass */;
11078
11228
  }
11079
- // If the class directly derives from NamedTuple (in Python 3.6 or
11080
- // newer), it's considered a (read-only) dataclass.
11081
- if (fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
11082
- if (types_1.ClassType.isBuiltIn(argType, 'NamedTuple')) {
11083
- classType.details.flags |=
11084
- 4 /* DataClass */ |
11085
- 32 /* SkipSynthesizedDataClassEq */ |
11086
- 16777216 /* ReadOnlyInstanceVariables */;
11087
- }
11229
+ // Determine if the class is abstract. Protocol classes support abstract methods
11230
+ // even though they don't derive from the ABCMeta class. We'll exclude built-in
11231
+ // protocol classes because these are known not to contain any abstract methods
11232
+ // and getAbstractMethods causes problems because of dependencies on some of these
11233
+ // built-in protocol classes.
11234
+ if (types_1.ClassType.supportsAbstractMethods(argType) ||
11235
+ (types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
11236
+ classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11237
+ }
11238
+ if (types_1.ClassType.isPropertyClass(argType)) {
11239
+ classType.details.flags |= 2048 /* PropertyClass */;
11088
11240
  }
11089
- // If the class directly derives from TypedDict or from a class that is
11090
- // a TypedDict, it is considered a TypedDict.
11091
- if (types_1.ClassType.isBuiltIn(argType, 'TypedDict') || types_1.ClassType.isTypedDictClass(argType)) {
11092
- classType.details.flags |= 128 /* TypedDictClass */;
11241
+ if (types_1.ClassType.isFinal(argType)) {
11242
+ const className = printObjectTypeForClass(argType);
11243
+ addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
11093
11244
  }
11094
- else if (types_1.ClassType.isTypedDictClass(classType) && !types_1.ClassType.isTypedDictClass(argType)) {
11095
- // Exempt Generic from this test. As of Python 3.11, generic TypedDict
11096
- // classes are supported.
11097
- if (!(0, types_1.isInstantiableClass)(argType) || !types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11098
- // TypedDict classes must derive only from other TypedDict classes.
11099
- addError(localize_1.Localizer.Diagnostic.typedDictBaseClass(), arg);
11245
+ }
11246
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11247
+ if ((0, types_1.isInstantiableClass)(argType)) {
11248
+ if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11249
+ // 'Generic' is implicitly added if type parameter syntax is used.
11250
+ if (node.typeParameters) {
11251
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
11252
+ }
11253
+ else {
11254
+ if (!genericTypeParameters) {
11255
+ if (protocolTypeParameters) {
11256
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11257
+ }
11258
+ genericTypeParameters = [];
11259
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11260
+ }
11100
11261
  }
11101
11262
  }
11102
- // Validate that the class isn't deriving from itself, creating a
11103
- // circular dependency.
11104
- if ((0, typeUtils_1.derivesFromClassRecursive)(argType, classType, /* ignoreUnknown */ true)) {
11105
- addError(localize_1.Localizer.Diagnostic.baseClassCircular(), arg);
11106
- argType = types_1.UnknownType.create();
11263
+ else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
11264
+ argType.typeArguments &&
11265
+ argType.typeArguments.length > 0) {
11266
+ if (!protocolTypeParameters) {
11267
+ if (genericTypeParameters) {
11268
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11269
+ }
11270
+ protocolTypeParameters = [];
11271
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11272
+ if (node.typeParameters && protocolTypeParameters.length > 0) {
11273
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
11274
+ protocolTypeParameters = [];
11275
+ }
11276
+ }
11107
11277
  }
11108
11278
  }
11109
11279
  }
11110
- if ((0, types_1.isUnknown)(argType)) {
11111
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedBaseClass, diagnosticRules_1.DiagnosticRule.reportUntypedBaseClass, localize_1.Localizer.Diagnostic.baseClassUnknown(), arg);
11112
- }
11113
- // Check for a duplicate class.
11114
- if (classType.details.baseClasses.some((prevBaseClass) => {
11115
- return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
11116
- (0, types_1.isInstantiableClass)(argType) &&
11117
- types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
11118
- })) {
11119
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
11120
- }
11121
- classType.details.baseClasses.push(argType);
11122
- if ((0, types_1.isInstantiableClass)(argType)) {
11123
- if (types_1.ClassType.isEnumClass(argType)) {
11124
- classType.details.flags |= 1048576 /* EnumClass */;
11280
+ else if (arg.name.value === 'metaclass') {
11281
+ if (metaclassNode) {
11282
+ addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
11283
+ }
11284
+ else {
11285
+ metaclassNode = arg.valueExpression;
11125
11286
  }
11126
- // Determine if the class is abstract. Protocol classes support abstract methods
11127
- // even though they don't derive from the ABCMeta class. We'll exclude built-in
11128
- // protocol classes because these are known not to contain any abstract methods
11129
- // and getAbstractMethods causes problems because of dependencies on some of these
11130
- // built-in protocol classes.
11131
- if (types_1.ClassType.supportsAbstractMethods(argType) ||
11132
- (types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
11133
- classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11287
+ }
11288
+ else if (types_1.ClassType.isTypedDictClass(classType) &&
11289
+ (arg.name.value === 'total' || arg.name.value === 'readonly')) {
11290
+ // The "total" and "readonly" parameters apply only for TypedDict classes.
11291
+ // PEP 589 specifies that the parameter must be either True or False.
11292
+ const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
11293
+ if (constArgValue === undefined) {
11294
+ addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
11134
11295
  }
11135
- if (types_1.ClassType.isPropertyClass(argType)) {
11136
- classType.details.flags |= 2048 /* PropertyClass */;
11296
+ else if (arg.name.value === 'total' && !constArgValue) {
11297
+ classType.details.flags |= 256 /* CanOmitDictValues */;
11137
11298
  }
11138
- if (types_1.ClassType.isFinal(argType)) {
11139
- const className = printObjectTypeForClass(argType);
11140
- addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
11299
+ else if (arg.name.value === 'readonly' && constArgValue) {
11300
+ classType.details.flags |= 512 /* DictValuesReadOnly */;
11141
11301
  }
11142
11302
  }
11143
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11144
- if ((0, types_1.isInstantiableClass)(argType)) {
11145
- if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11146
- // 'Generic' is implicitly added if type parameter syntax is used.
11147
- if (node.typeParameters) {
11148
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
11303
+ else {
11304
+ // Collect arguments that will be passed to the `__init_subclass__`
11305
+ // method described in PEP 487.
11306
+ initSubclassArgs.push({
11307
+ argumentCategory: 0 /* Simple */,
11308
+ node: arg,
11309
+ name: arg.name,
11310
+ valueExpression: arg.valueExpression,
11311
+ });
11312
+ }
11313
+ });
11314
+ // Check for NamedTuple multiple inheritance.
11315
+ if (classType.details.baseClasses.length > 1) {
11316
+ let derivesFromNamedTuple = false;
11317
+ let foundIllegalBaseClass = false;
11318
+ classType.details.baseClasses.forEach((baseClass) => {
11319
+ if ((0, types_1.isInstantiableClass)(baseClass)) {
11320
+ if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
11321
+ derivesFromNamedTuple = true;
11149
11322
  }
11150
- else {
11151
- if (!genericTypeParameters) {
11152
- if (protocolTypeParameters) {
11153
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11154
- }
11155
- genericTypeParameters = [];
11156
- (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11157
- }
11323
+ else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11324
+ foundIllegalBaseClass = true;
11158
11325
  }
11159
11326
  }
11160
- else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
11161
- argType.typeArguments &&
11162
- argType.typeArguments.length > 0) {
11163
- if (!protocolTypeParameters) {
11164
- if (genericTypeParameters) {
11165
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11166
- }
11167
- protocolTypeParameters = [];
11168
- (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11169
- if (node.typeParameters && protocolTypeParameters.length > 0) {
11170
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
11171
- protocolTypeParameters = [];
11327
+ });
11328
+ if (derivesFromNamedTuple && foundIllegalBaseClass) {
11329
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedTupleMultipleInheritance(), node.name);
11330
+ }
11331
+ }
11332
+ // Make sure we don't have 'object' derive from itself. Infinite
11333
+ // recursion will result.
11334
+ if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
11335
+ classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
11336
+ // If there are no other (known) base classes, the class implicitly derives from object.
11337
+ classType.details.baseClasses.push(getBuiltInType(node, 'object'));
11338
+ }
11339
+ // If genericTypeParameters or protocolTypeParameters are provided,
11340
+ // make sure that typeParameters is a proper subset.
11341
+ genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
11342
+ if (genericTypeParameters && !node.typeParameters) {
11343
+ verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
11344
+ }
11345
+ classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
11346
+ // Determine if one or more type parameters is autovariance.
11347
+ if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
11348
+ classType.details.requiresVarianceInference = true;
11349
+ }
11350
+ // Make sure there's at most one variadic type parameter.
11351
+ const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
11352
+ if (variadics.length > 1) {
11353
+ addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
11354
+ names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11355
+ }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11356
+ }
11357
+ // Validate the default types for all type parameters.
11358
+ classType.details.typeParameters.forEach((typeParam, index) => {
11359
+ var _a;
11360
+ let bestErrorNode = node.name;
11361
+ if (node.typeParameters && index < node.typeParameters.parameters.length) {
11362
+ const typeParamNode = node.typeParameters.parameters[index];
11363
+ bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
11364
+ }
11365
+ validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
11366
+ });
11367
+ if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11368
+ addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11369
+ }
11370
+ // The scope for this class becomes the "fields" for the corresponding type.
11371
+ const innerScope = ScopeUtils.getScopeForNode(node.suite);
11372
+ classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
11373
+ ? new Map(innerScope.symbolTable)
11374
+ : new Map();
11375
+ // Determine whether the class should inherit __hash__. If a class defines
11376
+ // __eq__ but doesn't define __hash__ then __hash__ is set to None.
11377
+ if (classType.details.fields.has('__eq__') && !classType.details.fields.has('__hash__')) {
11378
+ classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ |
11379
+ 128 /* ClassVar */ |
11380
+ 64 /* IgnoredForProtocolMatch */ |
11381
+ 4096 /* IgnoredForOverrideChecks */, types_1.NoneType.createInstance()));
11382
+ }
11383
+ // Determine whether the class's instance variables are constrained
11384
+ // to those defined by __slots__. We need to do this prior to dataclass
11385
+ // processing because dataclasses can implicitly add to the slots
11386
+ // list.
11387
+ const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
11388
+ if (slotsNames) {
11389
+ classType.details.localSlotsNames = slotsNames;
11390
+ }
11391
+ // Determine if the class should be a "pseudo-generic" class, characterized
11392
+ // by having an __init__ method with parameters that lack type annotations.
11393
+ // For such classes, we'll treat them as generic, with the type arguments provided
11394
+ // by the callers of the constructor.
11395
+ if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
11396
+ const initMethod = classType.details.fields.get('__init__');
11397
+ if (initMethod) {
11398
+ const initDecls = initMethod.getTypedDeclarations();
11399
+ if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
11400
+ const initDeclNode = initDecls[0].node;
11401
+ const initParams = initDeclNode.parameters;
11402
+ if (initParams.length > 1 &&
11403
+ !initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
11404
+ const genericParams = initParams.filter((param, index) => index > 0 &&
11405
+ param.name &&
11406
+ param.category === 0 /* Simple */ &&
11407
+ !param.defaultValue);
11408
+ if (genericParams.length > 0) {
11409
+ classType.details.flags |= 16384 /* PseudoGenericClass */;
11410
+ // Create a type parameter for each simple, named parameter
11411
+ // in the __init__ method.
11412
+ classType.details.typeParameters = genericParams.map((param) => {
11413
+ const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
11414
+ typeVar.details.isSynthesized = true;
11415
+ typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
11416
+ typeVar.details.boundType = types_1.UnknownType.create();
11417
+ return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
11418
+ });
11172
11419
  }
11173
11420
  }
11174
11421
  }
11175
11422
  }
11176
11423
  }
11177
- else if (arg.name.value === 'metaclass') {
11178
- if (metaclassNode) {
11179
- addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
11180
- }
11181
- else {
11182
- metaclassNode = arg.valueExpression;
11183
- }
11184
- }
11185
- else if (types_1.ClassType.isTypedDictClass(classType) &&
11186
- (arg.name.value === 'total' || arg.name.value === 'readonly')) {
11187
- // The "total" and "readonly" parameters apply only for TypedDict classes.
11188
- // PEP 589 specifies that the parameter must be either True or False.
11189
- const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
11190
- if (constArgValue === undefined) {
11191
- addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
11424
+ // Determine if the class has a custom __class_getitem__ method. This applies
11425
+ // only to classes that have no type parameters, since those with type parameters
11426
+ // are assumed to follow normal subscripting semantics for generic classes.
11427
+ if (classType.details.typeParameters.length === 0 && !types_1.ClassType.isBuiltIn(classType, 'type')) {
11428
+ if (classType.details.baseClasses.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.hasCustomClassGetItem(baseClass)) ||
11429
+ classType.details.fields.has('__class_getitem__')) {
11430
+ classType.details.flags |= 262144 /* HasCustomClassGetItem */;
11192
11431
  }
11193
- else if (arg.name.value === 'total' && !constArgValue) {
11194
- classType.details.flags |= 256 /* CanOmitDictValues */;
11195
- }
11196
- else if (arg.name.value === 'readonly' && constArgValue) {
11197
- classType.details.flags |= 512 /* DictValuesReadOnly */;
11198
- }
11199
- }
11200
- else {
11201
- // Collect arguments that will be passed to the `__init_subclass__`
11202
- // method described in PEP 487.
11203
- initSubclassArgs.push({
11204
- argumentCategory: 0 /* Simple */,
11205
- node: arg,
11206
- name: arg.name,
11207
- valueExpression: arg.valueExpression,
11208
- });
11209
11432
  }
11210
- });
11211
- // Check for NamedTuple multiple inheritance.
11212
- if (classType.details.baseClasses.length > 1) {
11213
- let derivesFromNamedTuple = false;
11214
- let foundIllegalBaseClass = false;
11215
- classType.details.baseClasses.forEach((baseClass) => {
11216
- if ((0, types_1.isInstantiableClass)(baseClass)) {
11217
- if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
11218
- derivesFromNamedTuple = true;
11433
+ // Determine the effective metaclass.
11434
+ if (metaclassNode) {
11435
+ const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
11436
+ if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
11437
+ if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
11438
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
11219
11439
  }
11220
- else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11221
- foundIllegalBaseClass = true;
11222
- }
11223
- }
11224
- });
11225
- if (derivesFromNamedTuple && foundIllegalBaseClass) {
11226
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedTupleMultipleInheritance(), node.name);
11227
- }
11228
- }
11229
- // Make sure we don't have 'object' derive from itself. Infinite
11230
- // recursion will result.
11231
- if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
11232
- classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
11233
- // If there are no other (known) base classes, the class implicitly derives from object.
11234
- classType.details.baseClasses.push(getBuiltInType(node, 'object'));
11235
- }
11236
- // If genericTypeParameters or protocolTypeParameters are provided,
11237
- // make sure that typeParameters is a proper subset.
11238
- genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
11239
- if (genericTypeParameters && !node.typeParameters) {
11240
- verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
11241
- }
11242
- classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
11243
- // Determine if one or more type parameters is autovariance.
11244
- if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
11245
- classType.details.requiresVarianceInference = true;
11246
- }
11247
- // Make sure there's at most one variadic type parameter.
11248
- const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
11249
- if (variadics.length > 1) {
11250
- addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
11251
- names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11252
- }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11253
- }
11254
- // Validate the default types for all type parameters.
11255
- classType.details.typeParameters.forEach((typeParam, index) => {
11256
- var _a;
11257
- let bestErrorNode = node.name;
11258
- if (node.typeParameters && index < node.typeParameters.parameters.length) {
11259
- const typeParamNode = node.typeParameters.parameters[index];
11260
- bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
11261
- }
11262
- validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
11263
- });
11264
- if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11265
- addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11266
- }
11267
- // The scope for this class becomes the "fields" for the corresponding type.
11268
- const innerScope = ScopeUtils.getScopeForNode(node.suite);
11269
- classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
11270
- ? new Map(innerScope.symbolTable)
11271
- : new Map();
11272
- // Determine whether the class's instance variables are constrained
11273
- // to those defined by __slots__. We need to do this prior to dataclass
11274
- // processing because dataclasses can implicitly add to the slots
11275
- // list.
11276
- const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
11277
- if (slotsNames) {
11278
- classType.details.localSlotsNames = slotsNames;
11279
- }
11280
- // Determine if the class should be a "pseudo-generic" class, characterized
11281
- // by having an __init__ method with parameters that lack type annotations.
11282
- // For such classes, we'll treat them as generic, with the type arguments provided
11283
- // by the callers of the constructor.
11284
- if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
11285
- const initMethod = classType.details.fields.get('__init__');
11286
- if (initMethod) {
11287
- const initDecls = initMethod.getTypedDeclarations();
11288
- if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
11289
- const initDeclNode = initDecls[0].node;
11290
- const initParams = initDeclNode.parameters;
11291
- if (initParams.length > 1 &&
11292
- !initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
11293
- const genericParams = initParams.filter((param, index) => index > 0 &&
11294
- param.name &&
11295
- param.category === 0 /* Simple */ &&
11296
- !param.defaultValue);
11297
- if (genericParams.length > 0) {
11298
- classType.details.flags |= 16384 /* PseudoGenericClass */;
11299
- // Create a type parameter for each simple, named parameter
11300
- // in the __init__ method.
11301
- classType.details.typeParameters = genericParams.map((param) => {
11302
- const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
11303
- typeVar.details.isSynthesized = true;
11304
- typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
11305
- typeVar.details.boundType = types_1.UnknownType.create();
11306
- return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
11307
- });
11440
+ classType.details.declaredMetaclass = metaclassType;
11441
+ if ((0, types_1.isInstantiableClass)(metaclassType)) {
11442
+ if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
11443
+ classType.details.flags |= 1048576 /* EnumClass */;
11444
+ }
11445
+ else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
11446
+ classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11308
11447
  }
11309
11448
  }
11310
11449
  }
11311
11450
  }
11312
- }
11313
- // Determine if the class has a custom __class_getitem__ method. This applies
11314
- // only to classes that have no type parameters, since those with type parameters
11315
- // are assumed to follow normal subscripting semantics for generic classes.
11316
- if (classType.details.typeParameters.length === 0 && !types_1.ClassType.isBuiltIn(classType, 'type')) {
11317
- if (classType.details.baseClasses.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.hasCustomClassGetItem(baseClass)) ||
11318
- classType.details.fields.has('__class_getitem__')) {
11319
- classType.details.flags |= 262144 /* HasCustomClassGetItem */;
11320
- }
11321
- }
11322
- // Determine the effective metaclass and detect metaclass conflicts.
11323
- if (metaclassNode) {
11324
- const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
11325
- if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
11326
- if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
11327
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
11328
- }
11329
- classType.details.declaredMetaclass = metaclassType;
11330
- if ((0, types_1.isInstantiableClass)(metaclassType)) {
11331
- if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
11332
- classType.details.flags |= 1048576 /* EnumClass */;
11333
- }
11334
- else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
11335
- classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11451
+ const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
11452
+ // Clear the "partially constructed" flag.
11453
+ classType.details.flags &= ~131072 /* PartiallyEvaluated */;
11454
+ // Now determine the decorated type of the class.
11455
+ let decoratedType = classType;
11456
+ let foundUnknown = false;
11457
+ for (let i = node.decorators.length - 1; i >= 0; i--) {
11458
+ const decorator = node.decorators[i];
11459
+ const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
11460
+ const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
11461
+ if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
11462
+ // Report this error only on the first unknown type.
11463
+ if (!foundUnknown) {
11464
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
11465
+ foundUnknown = true;
11336
11466
  }
11337
11467
  }
11338
- }
11339
- }
11340
- const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
11341
- // Clear the "partially constructed" flag.
11342
- classType.details.flags &= ~131072 /* PartiallyEvaluated */;
11343
- // Now determine the decorated type of the class.
11344
- let decoratedType = classType;
11345
- let foundUnknown = false;
11346
- for (let i = node.decorators.length - 1; i >= 0; i--) {
11347
- const decorator = node.decorators[i];
11348
- const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
11349
- const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
11350
- if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
11351
- // Report this error only on the first unknown type.
11352
- if (!foundUnknown) {
11353
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
11354
- foundUnknown = true;
11468
+ else {
11469
+ // Apply the decorator only if the type is known.
11470
+ decoratedType = newDecoratedType;
11355
11471
  }
11356
11472
  }
11357
- else {
11358
- // Apply the decorator only if the type is known.
11359
- decoratedType = newDecoratedType;
11473
+ // Determine whether this class derives from (or has a metaclass) that imbues
11474
+ // it with dataclass-like behaviors. If so, we'll apply those here.
11475
+ let dataClassBehaviors;
11476
+ if ((0, types_1.isInstantiableClass)(effectiveMetaclass) && effectiveMetaclass.details.classDataClassTransform) {
11477
+ dataClassBehaviors = effectiveMetaclass.details.classDataClassTransform;
11360
11478
  }
11361
- }
11362
- // Determine whether this class derives from (or has a metaclass) that imbues
11363
- // it with dataclass-like behaviors. If so, we'll apply those here.
11364
- let dataClassBehaviors;
11365
- if ((0, types_1.isInstantiableClass)(effectiveMetaclass) && effectiveMetaclass.details.classDataClassTransform) {
11366
- dataClassBehaviors = effectiveMetaclass.details.classDataClassTransform;
11367
- }
11368
- else {
11369
- const baseClassDataTransform = classType.details.mro.find((mroClass) => {
11370
- return ((0, types_1.isClass)(mroClass) &&
11371
- mroClass.details.classDataClassTransform !== undefined &&
11372
- !types_1.ClassType.isSameGenericClass(mroClass, classType));
11373
- });
11374
- if (baseClassDataTransform) {
11375
- dataClassBehaviors = baseClassDataTransform.details.classDataClassTransform;
11376
- }
11377
- }
11378
- if (dataClassBehaviors) {
11379
- (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11380
- (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11381
- }
11382
- // Run any deferred class completions that depend on this class.
11383
- runDeferredClassCompletions(classType);
11384
- // If there are any outstanding deferred class completions registered that
11385
- // were not removed by the call to runDeferredClassCompletions, assume that
11386
- // the current class may depend on them and register for deferred completion.
11387
- registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
11388
- // Synthesize TypedDict methods.
11389
- if (types_1.ClassType.isTypedDictClass(classType)) {
11390
- (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
11391
- }
11392
- // Synthesize dataclass methods.
11393
- if (types_1.ClassType.isDataClass(classType)) {
11394
- const skipSynthesizedInit = types_1.ClassType.isSkipSynthesizedDataClassInit(classType);
11395
- let hasExistingInitMethod = skipSynthesizedInit;
11396
- // See if there's already a non-synthesized __init__ method.
11397
- // We shouldn't override it.
11398
- if (!skipSynthesizedInit) {
11399
- const initSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 2 /* SkipBaseClasses */);
11400
- if (initSymbol) {
11401
- hasExistingInitMethod = true;
11402
- }
11403
- }
11404
- let skipSynthesizeHash = false;
11405
- const hashSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__hash__', 2 /* SkipBaseClasses */);
11406
- if (hashSymbol) {
11407
- skipSynthesizeHash = true;
11408
- }
11409
- (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
11410
- }
11411
- // Build a complete list of all slots names defined by the class hierarchy.
11412
- // This needs to be done after dataclass processing.
11413
- if (classType.details.localSlotsNames) {
11414
- let isLimitedToSlots = true;
11415
- const extendedSlotsNames = Array.from(classType.details.localSlotsNames);
11416
- classType.details.baseClasses.forEach((baseClass) => {
11417
- if ((0, types_1.isInstantiableClass)(baseClass)) {
11418
- if (!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
11419
- !types_1.ClassType.isBuiltIn(baseClass, 'type') &&
11420
- !types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11421
- if (baseClass.details.inheritedSlotsNames === undefined) {
11422
- isLimitedToSlots = false;
11423
- }
11424
- else {
11425
- (0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
11479
+ else {
11480
+ const baseClassDataTransform = classType.details.mro.find((mroClass) => {
11481
+ return ((0, types_1.isClass)(mroClass) &&
11482
+ mroClass.details.classDataClassTransform !== undefined &&
11483
+ !types_1.ClassType.isSameGenericClass(mroClass, classType));
11484
+ });
11485
+ if (baseClassDataTransform) {
11486
+ dataClassBehaviors = baseClassDataTransform.details.classDataClassTransform;
11487
+ }
11488
+ }
11489
+ if (dataClassBehaviors) {
11490
+ (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11491
+ (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11492
+ }
11493
+ // Run any deferred class completions that depend on this class.
11494
+ runDeferredClassCompletions(classType);
11495
+ // If there are any outstanding deferred class completions registered that
11496
+ // were not removed by the call to runDeferredClassCompletions, assume that
11497
+ // the current class may depend on them and register for deferred completion.
11498
+ registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
11499
+ // Synthesize TypedDict methods.
11500
+ if (types_1.ClassType.isTypedDictClass(classType)) {
11501
+ (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
11502
+ }
11503
+ // Synthesize dataclass methods.
11504
+ if (types_1.ClassType.isDataClass(classType)) {
11505
+ const skipSynthesizedInit = types_1.ClassType.isSkipSynthesizedDataClassInit(classType);
11506
+ let hasExistingInitMethod = skipSynthesizedInit;
11507
+ // See if there's already a non-synthesized __init__ method.
11508
+ // We shouldn't override it.
11509
+ if (!skipSynthesizedInit) {
11510
+ const initSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 2 /* SkipBaseClasses */);
11511
+ if (initSymbol) {
11512
+ hasExistingInitMethod = true;
11513
+ }
11514
+ }
11515
+ let skipSynthesizeHash = false;
11516
+ const hashSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__hash__', 2 /* SkipBaseClasses */);
11517
+ if (hashSymbol) {
11518
+ skipSynthesizeHash = true;
11519
+ }
11520
+ (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
11521
+ }
11522
+ // Build a complete list of all slots names defined by the class hierarchy.
11523
+ // This needs to be done after dataclass processing.
11524
+ if (classType.details.localSlotsNames) {
11525
+ let isLimitedToSlots = true;
11526
+ const extendedSlotsNames = Array.from(classType.details.localSlotsNames);
11527
+ classType.details.baseClasses.forEach((baseClass) => {
11528
+ if ((0, types_1.isInstantiableClass)(baseClass)) {
11529
+ if (!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
11530
+ !types_1.ClassType.isBuiltIn(baseClass, 'type') &&
11531
+ !types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11532
+ if (baseClass.details.inheritedSlotsNames === undefined) {
11533
+ isLimitedToSlots = false;
11534
+ }
11535
+ else {
11536
+ (0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
11537
+ }
11426
11538
  }
11427
11539
  }
11540
+ else {
11541
+ isLimitedToSlots = false;
11542
+ }
11543
+ });
11544
+ if (isLimitedToSlots) {
11545
+ classType.details.inheritedSlotsNames = extendedSlotsNames;
11428
11546
  }
11429
- else {
11430
- isLimitedToSlots = false;
11431
- }
11432
- });
11433
- if (isLimitedToSlots) {
11434
- classType.details.inheritedSlotsNames = extendedSlotsNames;
11435
11547
  }
11548
+ // Update the undecorated class type.
11549
+ writeTypeCache(node.name, { type: classType }, 0 /* None */);
11550
+ // Update the decorated class type.
11551
+ writeTypeCache(node, { type: decoratedType }, 0 /* None */);
11552
+ return { classType, decoratedType };
11553
+ }
11554
+ catch (e) {
11555
+ if (cancellationUtils_1.OperationCanceledException.is(e)) {
11556
+ // If the work was canceled before the class types were updated, the
11557
+ // class type in the type cache is in an invalid, partially-constructed state.
11558
+ e.isTypeCacheInvalid = true;
11559
+ }
11560
+ throw e;
11436
11561
  }
11437
- // Update the undecorated class type.
11438
- writeTypeCache(node.name, { type: classType }, 0 /* None */);
11439
- // Update the decorated class type.
11440
- writeTypeCache(node, { type: decoratedType }, 0 /* None */);
11441
- return { classType, decoratedType };
11442
11562
  }
11443
11563
  // Determines whether the type parameters has a default that refers to another
11444
11564
  // type parameter. If so, validates that it is in the list of "live" type
@@ -12105,11 +12225,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12105
12225
  }
12106
12226
  validateTypeParameterDefault(bestErrorNode, typeParam, functionType.details.typeParameters.slice(0, index));
12107
12227
  });
12228
+ // If it's an async function, wrap the return type in an Awaitable or Generator.
12229
+ const preDecoratedType = node.isAsync ? createAsyncFunction(node, functionType) : functionType;
12108
12230
  // Clear the "partially evaluated" flag to indicate that the functionType
12109
12231
  // is fully evaluated.
12110
12232
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
12111
- // If it's an async function, wrap the return type in an Awaitable or Generator.
12112
- const preDecoratedType = node.isAsync ? createAsyncFunction(node, functionType) : functionType;
12113
12233
  // Apply all of the decorators in reverse order.
12114
12234
  let decoratedType = preDecoratedType;
12115
12235
  let foundUnknown = false;
@@ -12322,7 +12442,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12322
12442
  (0, debug_1.assert)(types_1.FunctionType.isAsync(functionType));
12323
12443
  // Clone the original function and replace its return type with an
12324
12444
  // Awaitable[<returnType>]. Mark the new function as no longer async.
12325
- const awaitableFunctionType = types_1.FunctionType.cloneWithNewFlags(functionType, functionType.details.flags & ~512 /* Async */);
12445
+ const awaitableFunctionType = types_1.FunctionType.cloneWithNewFlags(functionType, functionType.details.flags & ~(512 /* Async */ | 131072 /* PartiallyEvaluated */));
12326
12446
  if (functionType.details.declaredReturnType) {
12327
12447
  awaitableFunctionType.details.declaredReturnType = createAwaitableReturnType(node, functionType.details.declaredReturnType, types_1.FunctionType.isGenerator(functionType));
12328
12448
  }
@@ -12805,7 +12925,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12805
12925
  for (const caseStatement of node.parent.cases) {
12806
12926
  if (caseStatement === node) {
12807
12927
  if (fileInfo.diagnosticRuleSet.reportUnnecessaryComparison !== 'none') {
12808
- (0, patternMatching_1.checkForUnusedPattern)(evaluatorInterface, node.pattern, subjectType);
12928
+ if (!subjectTypeResult.isIncomplete) {
12929
+ (0, patternMatching_1.checkForUnusedPattern)(evaluatorInterface, node.pattern, subjectType);
12930
+ }
12809
12931
  }
12810
12932
  break;
12811
12933
  }
@@ -12821,23 +12943,57 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12821
12943
  if (isTypeCached(node)) {
12822
12944
  return;
12823
12945
  }
12824
- // Use the first element of the name parts as the symbol.
12825
- const symbolNameNode = node.module.nameParts[0];
12826
- // Look up the symbol to find the alias declaration.
12827
- let symbolType = getAliasedSymbolTypeForName(node, symbolNameNode.value);
12828
- if (!symbolType) {
12829
- return;
12946
+ if (node.isWildcardImport) {
12947
+ // Write back a dummy type so we don't evaluate this node again.
12948
+ writeTypeCache(node, { type: types_1.AnyType.create() }, 0 /* None */);
12949
+ const flowNode = AnalyzerNodeInfo.getFlowNode(node);
12950
+ if (flowNode && (flowNode.flags & codeFlowTypes_1.FlowFlags.WildcardImport) !== 0) {
12951
+ const wildcardFlowNode = flowNode;
12952
+ wildcardFlowNode.names.forEach((name) => {
12953
+ var _a, _b;
12954
+ const importedSymbolType = getAliasedSymbolTypeForName(node, name);
12955
+ if (!importedSymbolType) {
12956
+ return;
12957
+ }
12958
+ const symbolWithScope = lookUpSymbolRecursive(node, name, /* honorCodeFlow */ false);
12959
+ if (!symbolWithScope) {
12960
+ return;
12961
+ }
12962
+ const declaredType = (_a = getDeclaredTypeOfSymbol(symbolWithScope.symbol)) === null || _a === void 0 ? void 0 : _a.type;
12963
+ if (!declaredType) {
12964
+ return;
12965
+ }
12966
+ const diagAddendum = new diagnostic_1.DiagnosticAddendum();
12967
+ if (!assignType(declaredType, importedSymbolType, diagAddendum)) {
12968
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAssignmentMismatchWildcard().format({
12969
+ ...printSrcDestTypes(importedSymbolType, declaredType),
12970
+ name,
12971
+ }) + diagAddendum.getString(), node, (_b = node.wildcardToken) !== null && _b !== void 0 ? _b : node);
12972
+ }
12973
+ });
12974
+ }
12830
12975
  }
12831
- // Is there a cached module type associated with this node? If so, use
12832
- // it instead of the type we just created.
12833
- const cachedModuleType = readTypeCache(node, 0 /* None */);
12834
- if (cachedModuleType && (0, types_1.isModule)(cachedModuleType) && symbolType) {
12835
- if ((0, types_1.isTypeSame)(symbolType, cachedModuleType)) {
12836
- symbolType = cachedModuleType;
12976
+ else {
12977
+ // Use the first element of the name parts as the symbol.
12978
+ const symbolNameNode = node.module.nameParts[0];
12979
+ // Look up the symbol to find the alias declaration.
12980
+ let symbolType = getAliasedSymbolTypeForName(node, symbolNameNode.value);
12981
+ if (!symbolType) {
12982
+ return;
12837
12983
  }
12984
+ // Is there a cached module type associated with this node? If so, use
12985
+ // it instead of the type we just created.
12986
+ const cachedModuleType = readTypeCache(node, 0 /* None */);
12987
+ if (cachedModuleType && (0, types_1.isModule)(cachedModuleType) && symbolType) {
12988
+ if ((0, types_1.isTypeSame)(symbolType, cachedModuleType)) {
12989
+ symbolType = cachedModuleType;
12990
+ }
12991
+ }
12992
+ assignTypeToNameNode(symbolNameNode, symbolType,
12993
+ /* isIncomplete */ false,
12994
+ /* ignoreEmptyContainers */ false);
12995
+ writeTypeCache(node, { type: symbolType }, 0 /* None */);
12838
12996
  }
12839
- assignTypeToNameNode(symbolNameNode, symbolType, /* isIncomplete */ false, /* ignoreEmptyContainers */ false);
12840
- writeTypeCache(node, { type: symbolType }, 0 /* None */);
12841
12997
  }
12842
12998
  function evaluateTypesForTypeAnnotationNode(node) {
12843
12999
  var _a;
@@ -13663,6 +13819,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13663
13819
  if ((0, types_1.isParamSpec)(typeArg)) {
13664
13820
  functionType.details.paramSpec = typeArg;
13665
13821
  }
13822
+ else if ((0, typeUtils_1.isEllipsisType)(typeArg)) {
13823
+ types_1.FunctionType.addDefaultParameters(functionType);
13824
+ functionType.details.flags |=
13825
+ 32768 /* SkipArgsKwargsCompatibilityCheck */;
13826
+ }
13666
13827
  }
13667
13828
  else {
13668
13829
  types_1.FunctionType.addParameter(functionType, {
@@ -13762,8 +13923,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13762
13923
  let flags = 128 /* ExpectingInstantiableType */ |
13763
13924
  8 /* EvaluateStringLiteralAsType */ |
13764
13925
  131072 /* DisallowClassVar */;
13765
- if (!(options === null || options === void 0 ? void 0 : options.allowTypeVarsWithoutScopeId)) {
13766
- flags |= 4096 /* DisallowTypeVarsWithoutScopeId */;
13926
+ if (options === null || options === void 0 ? void 0 : options.allowTypeVarsWithoutScopeId) {
13927
+ flags |= 4096 /* AllowTypeVarsWithoutScopeId */;
13767
13928
  }
13768
13929
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
13769
13930
  if (fileInfo.isStubFile || (options === null || options === void 0 ? void 0 : options.allowForwardReference)) {
@@ -15650,6 +15811,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15650
15811
  const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
15651
15812
  let effectiveFlags;
15652
15813
  let errorSource;
15814
+ let includeDiagAddendum = true;
15653
15815
  if (variance === 3 /* Covariant */) {
15654
15816
  effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
15655
15817
  errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
@@ -15662,6 +15824,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15662
15824
  else {
15663
15825
  effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
15664
15826
  errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
15827
+ // Omit the diagnostic addendum for the invariant case because it's obvious
15828
+ // why two types are not the same.
15829
+ includeDiagAddendum = false;
15665
15830
  }
15666
15831
  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)) {
15667
15832
  // Don't report errors with type variables in "pseudo-random"
@@ -15674,6 +15839,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15674
15839
  name: types_1.TypeVarType.getReadableName(destTypeParam),
15675
15840
  ...printSrcDestTypes(srcTypeArg, destTypeArg),
15676
15841
  }));
15842
+ if (includeDiagAddendum) {
15843
+ childDiag.addAddendum(assignmentDiag);
15844
+ }
15677
15845
  }
15678
15846
  else {
15679
15847
  diag.addAddendum(assignmentDiag);
@@ -16895,7 +17063,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16895
17063
  }
16896
17064
  }
16897
17065
  }
16898
- else {
17066
+ else if (!srcParamDetails.paramSpec) {
16899
17067
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.functionTooManyParams().format({
16900
17068
  expected: srcPositionalCount,
16901
17069
  received: destPositionalCount,
@@ -17044,16 +17212,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17044
17212
  // concatenated parameters must match.
17045
17213
  if (targetIncludesParamSpec &&
17046
17214
  ((_j = srcType.details.paramSpec) === null || _j === void 0 ? void 0 : _j.nameWithScope) === ((_k = destType.details.paramSpec) === null || _k === void 0 ? void 0 : _k.nameWithScope)) {
17047
- const srcParamCount = srcType.details.parameters.length;
17048
- const destParamCount = destType.details.parameters.length;
17049
- if (srcParamCount !== destParamCount) {
17050
- // If the dest has an extra position-only parameter separator appended
17051
- // to the end of the signature, it's OK.
17052
- if (srcParamCount !== destParamCount - 1 ||
17053
- destType.details.parameters[destParamCount - 1].category !== 0 /* Simple */ ||
17054
- !!destType.details.parameters[destParamCount - 1].name) {
17055
- canAssign = false;
17056
- }
17215
+ if (srcParamDetails.params.length !== destParamDetails.params.length) {
17216
+ canAssign = false;
17057
17217
  }
17058
17218
  }
17059
17219
  const effectiveSrcTypeVarContext = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? srcTypeVarContext : destTypeVarContext;
@@ -17245,6 +17405,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17245
17405
  return types_1.ClassType.cloneForSpecialization(assignedType, newTypeArgs, /* isTypeArgumentExplicit */ true);
17246
17406
  }
17247
17407
  }
17408
+ // If the declared and assigned types are the same generic type but the assigned type
17409
+ // contains one or more unknowns, use the declared type instead.
17410
+ if (types_1.ClassType.isSameGenericClass(declaredType, assignedType)) {
17411
+ if ((0, typeUtils_1.containsAnyRecursive)(assignedType) && !(0, typeUtils_1.containsAnyRecursive)(declaredType)) {
17412
+ return declaredType;
17413
+ }
17414
+ }
17248
17415
  return undefined;
17249
17416
  }
17250
17417
  // When a value is assigned to a variable with a declared type,
@@ -17257,29 +17424,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17257
17424
  return declaredSubtype;
17258
17425
  }
17259
17426
  if (assignType(declaredSubtype, assignedSubtype)) {
17260
- // If the source is generic and has unspecified type arguments,
17261
- // see if we can determine them based on the declared type.
17262
- if ((0, types_1.isInstantiableClass)(declaredSubtype) && (0, types_1.isInstantiableClass)(assignedSubtype)) {
17427
+ // If the assigned subtype is Any, stick with the declared type.
17428
+ if ((0, types_1.isAny)(assignedSubtype)) {
17429
+ return declaredSubtype;
17430
+ }
17431
+ if ((0, types_1.isClass)(declaredSubtype) &&
17432
+ (0, types_1.isClass)(assignedSubtype) &&
17433
+ types_1.TypeBase.isInstance(declaredSubtype) === types_1.TypeBase.isInstance(assignedSubtype)) {
17263
17434
  const result = replaceTypeArgsWithAny(node, declaredSubtype, assignedSubtype);
17264
17435
  if (result) {
17265
17436
  assignedSubtype = result;
17266
17437
  }
17438
+ return assignedSubtype;
17267
17439
  }
17268
- else if ((0, types_1.isClassInstance)(declaredSubtype) && (0, types_1.isClassInstance)(assignedSubtype)) {
17269
- const result = replaceTypeArgsWithAny(node, types_1.ClassType.cloneAsInstantiable(declaredSubtype), types_1.ClassType.cloneAsInstantiable(assignedSubtype));
17270
- if (result) {
17271
- assignedSubtype = types_1.ClassType.cloneAsInstance(result);
17272
- }
17273
- }
17274
- else if (!(0, types_1.isTypeVar)(declaredSubtype) && (0, types_1.isTypeVar)(assignedSubtype)) {
17440
+ if (!(0, types_1.isTypeVar)(declaredSubtype) && (0, types_1.isTypeVar)(assignedSubtype)) {
17275
17441
  // If the source is an unsolved TypeVar but the declared type is concrete,
17276
17442
  // use the concrete type.
17277
17443
  return declaredSubtype;
17278
17444
  }
17279
- // If the assigned subtype is Any, stick with the declared type.
17280
- if ((0, types_1.isAny)(assignedSubtype)) {
17281
- return declaredSubtype;
17282
- }
17283
17445
  // If the declared type doesn't contain any `Any` but the assigned
17284
17446
  // type does, stick with the declared type.
17285
17447
  if ((0, typeUtils_1.containsAnyRecursive)(assignedSubtype) && !(0, typeUtils_1.containsAnyRecursive)(declaredSubtype)) {
@@ -17347,28 +17509,42 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17347
17509
  // must all match and be in the correct order. It is OK if the base method
17348
17510
  // has additional overloads that are not present in the override.
17349
17511
  let previousMatchIndex = -1;
17350
- let overrideOverloadIndex = 0;
17351
17512
  const baseOverloads = types_1.OverloadedFunctionType.getOverloads(baseMethod);
17352
17513
  for (const overrideOverload of types_1.OverloadedFunctionType.getOverloads(overrideMethod)) {
17353
- const matchIndex = baseOverloads.findIndex((baseOverload) => {
17514
+ let possibleMatchIndex;
17515
+ let matchIndex = baseOverloads.findIndex((baseOverload, index) => {
17354
17516
  // If the override isn't applicable for this base class, skip the check.
17355
17517
  if (baseClass && !isOverrideMethodApplicable(baseOverload, baseClass)) {
17356
17518
  return false;
17357
17519
  }
17358
- return validateOverrideMethodInternal(baseOverload, overrideOverload,
17520
+ const isCompatible = validateOverrideMethodInternal(baseOverload, overrideOverload,
17359
17521
  /* diag */ undefined, enforceParamNames,
17360
17522
  /* exemptSelfClsParam */ false);
17523
+ // If the override is compatible but the match is one that is below the previous
17524
+ // matched index, keep looking for additional matches. Record the fact that
17525
+ // we found at least one match.
17526
+ if (isCompatible && index <= previousMatchIndex && possibleMatchIndex === undefined) {
17527
+ possibleMatchIndex = index;
17528
+ return false;
17529
+ }
17530
+ return isCompatible;
17361
17531
  });
17532
+ if (matchIndex < 0 && possibleMatchIndex !== undefined) {
17533
+ matchIndex = possibleMatchIndex;
17534
+ }
17362
17535
  if (matchIndex < 0) {
17363
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch().format({ index: overrideOverloadIndex + 1 }));
17364
- return false;
17536
+ continue;
17365
17537
  }
17366
17538
  if (matchIndex < previousMatchIndex) {
17367
17539
  diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadOrder());
17368
17540
  return false;
17369
17541
  }
17370
17542
  previousMatchIndex = matchIndex;
17371
- overrideOverloadIndex++;
17543
+ }
17544
+ if (previousMatchIndex < baseOverloads.length - 1) {
17545
+ // We didn't find matches for all of the base overloads.
17546
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch());
17547
+ return false;
17372
17548
  }
17373
17549
  return true;
17374
17550
  }
@@ -17638,9 +17814,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17638
17814
  }
17639
17815
  }
17640
17816
  // Verify that one or the other method doesn't contain a ParamSpec.
17641
- if (baseMethod.details.paramSpec && !overrideMethod.details.paramSpec) {
17642
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.paramSpecMissingInOverride());
17643
- canOverride = false;
17817
+ if (baseParamDetails.paramSpec && !overrideParamDetails.paramSpec) {
17818
+ // If the override uses an `*args: Any, **kwargs: Any` signature, we
17819
+ // will allow this as an acceptable overload for a `*args: P.args, **kwargs: P.kwargs`.
17820
+ const overrideHasArgsKwargs = overrideParamDetails.argsIndex !== undefined &&
17821
+ (0, types_1.isAnyOrUnknown)(overrideParamDetails.params[overrideParamDetails.argsIndex].type) &&
17822
+ overrideParamDetails.kwargsIndex !== undefined &&
17823
+ (0, types_1.isAnyOrUnknown)(overrideParamDetails.params[overrideParamDetails.kwargsIndex].type);
17824
+ if (!overrideHasArgsKwargs) {
17825
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.paramSpecMissingInOverride());
17826
+ canOverride = false;
17827
+ }
17644
17828
  }
17645
17829
  // Now check the return type.
17646
17830
  const baseReturnType = getFunctionEffectiveReturnType(baseMethod);