@zzzen/pyright-internal 1.2.0-dev.20230820 → 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 (88) hide show
  1. package/dist/analyzer/checker.js +46 -64
  2. package/dist/analyzer/checker.js.map +1 -1
  3. package/dist/analyzer/codeFlowEngine.js +23 -1
  4. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  5. package/dist/analyzer/constraintSolver.js +2 -1
  6. package/dist/analyzer/constraintSolver.js.map +1 -1
  7. package/dist/analyzer/constructorTransform.js +1 -1
  8. package/dist/analyzer/constructorTransform.js.map +1 -1
  9. package/dist/analyzer/decorators.js +11 -6
  10. package/dist/analyzer/decorators.js.map +1 -1
  11. package/dist/analyzer/deprecatedSymbols.d.ts +9 -0
  12. package/dist/analyzer/deprecatedSymbols.js +292 -0
  13. package/dist/analyzer/deprecatedSymbols.js.map +1 -0
  14. package/dist/analyzer/docStringConversion.js +7 -1
  15. package/dist/analyzer/docStringConversion.js.map +1 -1
  16. package/dist/analyzer/importResolver.js +5 -0
  17. package/dist/analyzer/importResolver.js.map +1 -1
  18. package/dist/analyzer/program.d.ts +3 -3
  19. package/dist/analyzer/program.js +5 -9
  20. package/dist/analyzer/program.js.map +1 -1
  21. package/dist/analyzer/sourceFile.js +1 -0
  22. package/dist/analyzer/sourceFile.js.map +1 -1
  23. package/dist/analyzer/typeEvaluator.js +530 -432
  24. package/dist/analyzer/typeEvaluator.js.map +1 -1
  25. package/dist/analyzer/typeGuards.js +15 -4
  26. package/dist/analyzer/typeGuards.js.map +1 -1
  27. package/dist/analyzer/typeUtils.d.ts +2 -2
  28. package/dist/analyzer/typeUtils.js +10 -5
  29. package/dist/analyzer/typeUtils.js.map +1 -1
  30. package/dist/analyzer/typeVarContext.js +3 -1
  31. package/dist/analyzer/typeVarContext.js.map +1 -1
  32. package/dist/analyzer/types.d.ts +6 -1
  33. package/dist/analyzer/types.js +19 -0
  34. package/dist/analyzer/types.js.map +1 -1
  35. package/dist/common/cancellationUtils.d.ts +2 -1
  36. package/dist/common/cancellationUtils.js +3 -0
  37. package/dist/common/cancellationUtils.js.map +1 -1
  38. package/dist/common/configOptions.d.ts +1 -0
  39. package/dist/common/configOptions.js +5 -1
  40. package/dist/common/configOptions.js.map +1 -1
  41. package/dist/common/diagnosticRules.d.ts +1 -0
  42. package/dist/common/diagnosticRules.js +1 -0
  43. package/dist/common/diagnosticRules.js.map +1 -1
  44. package/dist/languageService/completionProvider.js +9 -3
  45. package/dist/languageService/completionProvider.js.map +1 -1
  46. package/dist/localization/localize.d.ts +3 -0
  47. package/dist/localization/localize.js +1 -0
  48. package/dist/localization/localize.js.map +1 -1
  49. package/dist/localization/package.nls.cs.json +12 -10
  50. package/dist/localization/package.nls.de.json +12 -10
  51. package/dist/localization/package.nls.en-us.json +2 -1
  52. package/dist/localization/package.nls.es.json +12 -10
  53. package/dist/localization/package.nls.fr.json +12 -10
  54. package/dist/localization/package.nls.it.json +12 -10
  55. package/dist/localization/package.nls.ja.json +12 -10
  56. package/dist/localization/package.nls.ko.json +12 -10
  57. package/dist/localization/package.nls.pl.json +12 -10
  58. package/dist/localization/package.nls.pt-br.json +12 -10
  59. package/dist/localization/package.nls.qps-ploc.json +12 -10
  60. package/dist/localization/package.nls.ru.json +12 -10
  61. package/dist/localization/package.nls.tr.json +12 -10
  62. package/dist/localization/package.nls.zh-cn.json +12 -10
  63. package/dist/localization/package.nls.zh-tw.json +12 -10
  64. package/dist/parser/parser.js +2 -0
  65. package/dist/parser/parser.js.map +1 -1
  66. package/dist/parser/tokenizer.d.ts +1 -1
  67. package/dist/parser/tokenizer.js +9 -5
  68. package/dist/parser/tokenizer.js.map +1 -1
  69. package/dist/tests/checker.test.js +34 -13
  70. package/dist/tests/checker.test.js.map +1 -1
  71. package/dist/tests/completions.test.js +39 -2
  72. package/dist/tests/completions.test.js.map +1 -1
  73. package/dist/tests/docStringConversion.test.js +23 -0
  74. package/dist/tests/docStringConversion.test.js.map +1 -1
  75. package/dist/tests/typeEvaluator1.test.js +4 -0
  76. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  77. package/dist/tests/typeEvaluator2.test.js +4 -0
  78. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  79. package/dist/tests/typeEvaluator3.test.js +14 -20
  80. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  81. package/dist/tests/typeEvaluator4.test.js +12 -0
  82. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  83. package/dist/tests/typeEvaluator5.test.js +24 -0
  84. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  85. package/dist/workspaceFactory.d.ts +1 -1
  86. package/dist/workspaceFactory.js +3 -3
  87. package/dist/workspaceFactory.js.map +1 -1
  88. package/package.json +1 -1
@@ -683,6 +683,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
683
683
  }
684
684
  return typeResult;
685
685
  }
686
+ // Reports the case where a function or class has been decorated with
687
+ // @type_check_only and is used in a value expression.
688
+ function reportUseOfTypeCheckOnly(type, node) {
689
+ let isTypeCheckingOnly = false;
690
+ let name = '';
691
+ if ((0, types_1.isInstantiableClass)(type) && !type.includeSubclasses) {
692
+ isTypeCheckingOnly = types_1.ClassType.isTypeCheckOnly(type);
693
+ name = type.details.name;
694
+ }
695
+ else if ((0, types_1.isFunction)(type)) {
696
+ isTypeCheckingOnly = types_1.FunctionType.isTypeCheckOnly(type);
697
+ name = type.details.name;
698
+ }
699
+ if (isTypeCheckingOnly) {
700
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
701
+ if (!fileInfo.isStubFile) {
702
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeCheckOnly().format({ name }), node);
703
+ }
704
+ }
705
+ }
686
706
  function reportInvalidUseOfPep695TypeAlias(type, node) {
687
707
  var _a;
688
708
  // PEP 695 type aliases cannot be used as instantiable classes.
@@ -1234,11 +1254,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1234
1254
  let memberInfo;
1235
1255
  const classDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1236
1256
  const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1257
+ let considerMetaclassOnly = (memberAccessFlags & 32 /* ConsiderMetaclassOnly */) !== 0;
1237
1258
  if (types_1.ClassType.isPartiallyEvaluated(classType)) {
1238
1259
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), errorNode);
1239
1260
  return { type: types_1.UnknownType.create() };
1240
1261
  }
1241
- 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) {
1242
1281
  memberInfo = getTypeOfClassMemberName(errorNode, classType,
1243
1282
  /* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
1244
1283
  }
@@ -2920,6 +2959,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2920
2959
  }
2921
2960
  }
2922
2961
  }
2962
+ if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
2963
+ reportUseOfTypeCheckOnly(type, node);
2964
+ }
2923
2965
  if ((flags & 16777216 /* DisallowPep695TypeAlias */) !== 0) {
2924
2966
  if (reportInvalidUseOfPep695TypeAlias(type, node)) {
2925
2967
  type = types_1.UnknownType.create();
@@ -3389,7 +3431,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3389
3431
  }
3390
3432
  return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
3391
3433
  }
3392
- if (flags & 256 /* ExpectingTypeAnnotation */) {
3434
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
3393
3435
  if (!isIncomplete) {
3394
3436
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
3395
3437
  type: printType(baseType),
@@ -3613,6 +3655,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3613
3655
  // additional reportUnknownMemberType diagnostics.
3614
3656
  type = isFunctionRule ? types_1.AnyType.create() : types_1.UnknownType.create();
3615
3657
  }
3658
+ if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
3659
+ reportUseOfTypeCheckOnly(type, node.memberName);
3660
+ }
3616
3661
  // Should we specialize the class?
3617
3662
  if ((flags & 2 /* DoNotSpecialize */) === 0) {
3618
3663
  if ((0, types_1.isInstantiableClass)(type) && !type.typeArguments) {
@@ -3705,13 +3750,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3705
3750
  }
3706
3751
  }
3707
3752
  if (!type) {
3753
+ let selfClass = classType;
3708
3754
  // Determine whether to replace Self variables with a specific
3709
3755
  // class. Avoid doing this if there's a "bindToType" specified
3710
3756
  // because that case is used for super() calls where we want
3711
3757
  // to leave the Self type generic (not specialized). We'll also
3712
3758
  // skip this for __new__ methods because they are not bound
3713
3759
  // to the class but rather assume the type of the cls argument.
3714
- 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
+ }
3715
3771
  const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3716
3772
  if (typeResult) {
3717
3773
  type = typeResult.type;
@@ -3886,14 +3942,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3886
3942
  ];
3887
3943
  if (usage.method === 'get') {
3888
3944
  // Provide "owner" argument.
3889
- // Use Any rather than None for the owner argument if accessing through an object.
3890
- // None is more correct, but it doesn't really matter, and many descriptor classes
3891
- // incorrectly annotate the owner parameter. Rather than create a bunch of noise,
3892
- // we'll use Any here.
3893
3945
  argList.push({
3894
3946
  argumentCategory: 0 /* Simple */,
3895
3947
  typeResult: {
3896
- type: isAccessedThroughObject ? types_1.AnyType.create() : baseTypeClass,
3948
+ type: baseTypeClass,
3897
3949
  },
3898
3950
  });
3899
3951
  }
@@ -4251,14 +4303,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4251
4303
  function getTypeOfIndex(node, flags = 0 /* None */) {
4252
4304
  const baseTypeResult = getTypeOfExpression(node.baseExpression, flags | 2 /* IndexBaseDefaults */);
4253
4305
  // If this is meant to be a type and the base expression is a string expression,
4254
- // emit an error because this will generate a runtime exception in Python versions
4255
- // less than 3.10.
4306
+ // emit an error because this is an illegal annotation form and will generate a
4307
+ // runtime exception.
4256
4308
  if (flags & 128 /* ExpectingInstantiableType */) {
4257
4309
  if (node.baseExpression.nodeType === 48 /* StringList */) {
4258
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4259
- if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
4260
- addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
4261
- }
4310
+ addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
4262
4311
  }
4263
4312
  }
4264
4313
  // Check for builtin classes that will generate runtime exceptions if subscripted.
@@ -4608,7 +4657,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4608
4657
  const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
4609
4658
  /* usage */ undefined,
4610
4659
  /* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 32 /* ConsiderMetaclassOnly */);
4611
- if (flags & 256 /* ExpectingTypeAnnotation */) {
4660
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
4612
4661
  // If the class doesn't derive from Generic, a type argument should not be allowed.
4613
4662
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
4614
4663
  name: printType(types_1.ClassType.cloneAsInstance(concreteSubtype)),
@@ -4660,9 +4709,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4660
4709
  // Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
4661
4710
  // This feature is currently experimental.
4662
4711
  const supportsTypedDictTypeArg = AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
4663
- (0, types_1.isInstantiableClass)(concreteSubtype) &&
4664
- types_1.ClassType.isBuiltIn(concreteSubtype, 'dict') &&
4665
- !concreteSubtype.aliasName;
4712
+ types_1.ClassType.isBuiltIn(concreteSubtype, ['dict', 'TypedDict']) &&
4713
+ !types_1.ClassType.isBuiltIn(concreteSubtype, 'Dict');
4666
4714
  let typeArgs = getTypeArgs(node, flags, {
4667
4715
  isAnnotatedClass,
4668
4716
  hasCustomClassGetItem: hasCustomClassGetItem || !isGenericClass,
@@ -5633,7 +5681,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5633
5681
  if (node.arguments.length > 2) {
5634
5682
  addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
5635
5683
  }
5636
- const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
5684
+ const enclosingFunction = ParseTreeUtils.getEnclosingFunction(node);
5685
+ const enclosingClass = enclosingFunction
5686
+ ? ParseTreeUtils.getEnclosingClass(enclosingFunction, /* stopAtFunction */ true)
5687
+ : undefined;
5637
5688
  const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
5638
5689
  // Determine which class the "super" call is applied to. If
5639
5690
  // there is no first argument, then the class is implicit.
@@ -5804,13 +5855,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5804
5855
  return argParamCopy;
5805
5856
  });
5806
5857
  }
5807
- // Clone the typeVarContext so we don't modify the original. If this is
5808
- // not the first time through the loop, clone the type var context
5809
- // from the previous successful match.
5810
- const typeVarContextToClone = matchedOverloads.length > 0
5811
- ? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
5812
- : typeVarContext;
5813
- const effectiveTypeVarContext = (_a = typeVarContextToClone === null || typeVarContextToClone === void 0 ? void 0 : typeVarContextToClone.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
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));
5814
5860
  effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
5815
5861
  effectiveTypeVarContext.unlock();
5816
5862
  // Use speculative mode so we don't output any diagnostics or
@@ -6557,7 +6603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6557
6603
  var _a, _b;
6558
6604
  const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6559
6605
  /* usage */ undefined,
6560
- /* 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;
6561
6607
  if (!memberType) {
6562
6608
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6563
6609
  type: printType(expandedCallType),
@@ -7960,6 +8006,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7960
8006
  const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
7961
8007
  const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
7962
8008
  const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
8009
+ const nestedArgList = [];
7963
8010
  argList.forEach((arg) => {
7964
8011
  var _a;
7965
8012
  if (arg.argumentCategory === 0 /* Simple */) {
@@ -7989,6 +8036,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7989
8036
  else if (argsParam) {
7990
8037
  paramType = argsParam.type;
7991
8038
  }
8039
+ else if (paramSpecType.details.paramSpec) {
8040
+ nestedArgList.push(arg);
8041
+ }
7992
8042
  else {
7993
8043
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, paramSpecParams.length === 1
7994
8044
  ? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
@@ -8034,6 +8084,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8034
8084
  }
8035
8085
  }
8036
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
+ }
8037
8099
  });
8038
8100
  }
8039
8101
  // Report any missing parameters.
@@ -8071,10 +8133,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8071
8133
  let isCompatible = true;
8072
8134
  const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
8073
8135
  let skippedBareTypeVarExpectedType = false;
8136
+ let skipSolveTypeVars = false;
8074
8137
  if (argParam.argument.valueExpression) {
8075
8138
  let expectedType;
8076
- const isBareTypeVarExpectedType = (0, types_1.isTypeVar)(argParam.paramType) && argParam.paramType.scopeId === (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId);
8077
- if (!options.skipBareTypeVarExpectedType || !isBareTypeVarExpectedType) {
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) {
8078
8147
  expectedType = argParam.paramType;
8079
8148
  // If the parameter type is a function with a ParamSpec, don't apply
8080
8149
  // the solved TypeVars if the typeVarContext has more than one signature.
@@ -8090,6 +8159,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8090
8159
  }
8091
8160
  else {
8092
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
+ }
8093
8169
  }
8094
8170
  // If the expected type is unknown, don't use an expected type. Instead,
8095
8171
  // use default rules for evaluating the expression type.
@@ -8206,7 +8282,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8206
8282
  }
8207
8283
  }
8208
8284
  if ((0, types_1.isClassInstance)(argType)) {
8209
- const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__');
8285
+ const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 8 /* SkipInstanceVariables */);
8210
8286
  if (callMember) {
8211
8287
  const memberType = getTypeOfMember(callMember);
8212
8288
  if ((0, types_1.isOverloadedFunction)(memberType)) {
@@ -8223,7 +8299,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8223
8299
  }
8224
8300
  }
8225
8301
  }
8226
- if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext)) {
8302
+ if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext,
8303
+ /* srcTypeVarContext */ undefined, skipSolveTypeVars ? 8 /* SkipSolveTypeVars */ : undefined)) {
8227
8304
  // Mismatching parameter types are common in untyped code; don't bother spending time
8228
8305
  // printing types if the diagnostic is disabled.
8229
8306
  const fileInfo = AnalyzerNodeInfo.getFileInfo(argParam.errorNode);
@@ -10616,7 +10693,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10616
10693
  // methods that are abstract are overridden and shouldn't
10617
10694
  // cause the TypedDict to be marked as abstract.
10618
10695
  if ((0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, '_TypedDict')) {
10619
- baseClass.details.flags &= ~1024 /* SupportsAbstractMethods */;
10696
+ baseClass = types_1.ClassType.cloneWithNewFlags(baseClass, baseClass.details.flags &
10697
+ ~(1024 /* SupportsAbstractMethods */ | 134217728 /* TypeCheckOnly */));
10620
10698
  }
10621
10699
  }
10622
10700
  }
@@ -11022,452 +11100,465 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11022
11100
  setSymbolResolutionPartialType(classSymbol, classDecl, classType);
11023
11101
  }
11024
11102
  classType.details.flags |= 131072 /* PartiallyEvaluated */;
11025
- writeTypeCache(node, { type: classType }, /* flags */ undefined);
11026
- writeTypeCache(node.name, { type: classType }, /* flags */ undefined);
11027
- // Keep a list of unique type parameters that are used in the
11028
- // base class arguments.
11029
- let typeParameters = [];
11030
- if (node.typeParameters) {
11031
- typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
11032
- }
11033
- // If the class derives from "Generic" directly, it will provide
11034
- // all of the type parameters in the specified order.
11035
- let genericTypeParameters;
11036
- let protocolTypeParameters;
11037
- const initSubclassArgs = [];
11038
- let metaclassNode;
11039
- let exprFlags = 128 /* ExpectingInstantiableType */ |
11040
- 1024 /* AllowGenericClassType */ |
11041
- 262144 /* DisallowNakedGeneric */ |
11042
- 2048 /* DisallowTypeVarsWithScopeId */ |
11043
- 8192 /* AssociateTypeVarsWithCurrentScope */ |
11044
- 16384 /* EnforceTypeVarVarianceConsistency */ |
11045
- 16777216 /* DisallowPep695TypeAlias */;
11046
- if (fileInfo.isStubFile) {
11047
- exprFlags |= 4 /* AllowForwardReferences */;
11048
- }
11049
- node.arguments.forEach((arg) => {
11050
- // Ignore unpacked arguments.
11051
- if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
11052
- // Evaluate the expression's type so symbols are marked accessed
11053
- // and errors are reported.
11054
- getTypeOfExpression(arg.valueExpression);
11055
- return;
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 */;
11056
11127
  }
11057
- if (!arg.name) {
11058
- let argType;
11059
- 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.
11060
11133
  getTypeOfExpression(arg.valueExpression);
11061
- argType = types_1.UnknownType.create();
11134
+ return;
11062
11135
  }
11063
- else {
11064
- argType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(arg.valueExpression, exprFlags).type);
11065
- }
11066
- // In some stub files, classes are conditionally defined (e.g. based
11067
- // on platform type). We'll assume that the conditional logic is correct
11068
- // and strip off the "unbound" union.
11069
- if ((0, types_1.isUnion)(argType)) {
11070
- argType = (0, types_1.removeUnbound)(argType);
11071
- }
11072
- if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
11073
- if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
11074
- (0, debug_1.assert)((0, types_1.isClassInstance)(argType));
11075
- argType =
11076
- argType.typeArguments && argType.typeArguments.length > 0
11077
- ? argType.typeArguments[0]
11078
- : types_1.UnknownType.create();
11079
- }
11080
- else if (!(0, types_1.isInstantiableClass)(argType)) {
11081
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
11136
+ if (!arg.name) {
11137
+ let argType;
11138
+ if (arg.argumentCategory === 1 /* UnpackedList */) {
11139
+ getTypeOfExpression(arg.valueExpression);
11082
11140
  argType = types_1.UnknownType.create();
11083
11141
  }
11084
11142
  else {
11085
- if (types_1.ClassType.isPartiallyEvaluated(argType) ||
11086
- argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
11087
- // If the base class is partially evaluated, install a callback
11088
- // so we can fix up this class (e.g. compute the MRO) when the
11089
- // dependent class is completed.
11090
- registerDeferredClassCompletion(node, argType);
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();
11091
11158
  }
11092
- if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
11093
- if (!fileInfo.isStubFile &&
11094
- !types_1.ClassType.isTypingExtensionClass(argType) &&
11095
- fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_7) {
11096
- addError(localize_1.Localizer.Diagnostic.protocolIllegal(), arg.valueExpression);
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();
11097
11210
  }
11098
- classType.details.flags |= 8192 /* ProtocolClass */;
11099
11211
  }
11100
- if (types_1.ClassType.isBuiltIn(argType, 'property')) {
11101
- 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 */;
11102
11228
  }
11103
- // If the class directly derives from NamedTuple (in Python 3.6 or
11104
- // newer), it's considered a (read-only) dataclass.
11105
- if (fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
11106
- if (types_1.ClassType.isBuiltIn(argType, 'NamedTuple')) {
11107
- classType.details.flags |=
11108
- 4 /* DataClass */ |
11109
- 32 /* SkipSynthesizedDataClassEq */ |
11110
- 16777216 /* ReadOnlyInstanceVariables */;
11111
- }
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 */;
11112
11240
  }
11113
- // If the class directly derives from TypedDict or from a class that is
11114
- // a TypedDict, it is considered a TypedDict.
11115
- if (types_1.ClassType.isBuiltIn(argType, 'TypedDict') || types_1.ClassType.isTypedDictClass(argType)) {
11116
- classType.details.flags |= 128 /* TypedDictClass */;
11241
+ if (types_1.ClassType.isFinal(argType)) {
11242
+ const className = printObjectTypeForClass(argType);
11243
+ addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
11117
11244
  }
11118
- else if (types_1.ClassType.isTypedDictClass(classType) && !types_1.ClassType.isTypedDictClass(argType)) {
11119
- // Exempt Generic from this test. As of Python 3.11, generic TypedDict
11120
- // classes are supported.
11121
- if (!(0, types_1.isInstantiableClass)(argType) || !types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11122
- // TypedDict classes must derive only from other TypedDict classes.
11123
- addError(localize_1.Localizer.Diagnostic.typedDictBaseClass(), arg);
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
+ }
11124
11261
  }
11125
11262
  }
11126
- // Validate that the class isn't deriving from itself, creating a
11127
- // circular dependency.
11128
- if ((0, typeUtils_1.derivesFromClassRecursive)(argType, classType, /* ignoreUnknown */ true)) {
11129
- addError(localize_1.Localizer.Diagnostic.baseClassCircular(), arg);
11130
- argType = types_1.UnknownType.create();
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
+ }
11131
11277
  }
11132
11278
  }
11133
11279
  }
11134
- if ((0, types_1.isUnknown)(argType)) {
11135
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedBaseClass, diagnosticRules_1.DiagnosticRule.reportUntypedBaseClass, localize_1.Localizer.Diagnostic.baseClassUnknown(), arg);
11136
- }
11137
- // Check for a duplicate class.
11138
- if (classType.details.baseClasses.some((prevBaseClass) => {
11139
- return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
11140
- (0, types_1.isInstantiableClass)(argType) &&
11141
- types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
11142
- })) {
11143
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
11144
- }
11145
- classType.details.baseClasses.push(argType);
11146
- if ((0, types_1.isInstantiableClass)(argType)) {
11147
- if (types_1.ClassType.isEnumClass(argType)) {
11148
- classType.details.flags |= 1048576 /* EnumClass */;
11280
+ else if (arg.name.value === 'metaclass') {
11281
+ if (metaclassNode) {
11282
+ addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
11149
11283
  }
11150
- // Determine if the class is abstract. Protocol classes support abstract methods
11151
- // even though they don't derive from the ABCMeta class. We'll exclude built-in
11152
- // protocol classes because these are known not to contain any abstract methods
11153
- // and getAbstractMethods causes problems because of dependencies on some of these
11154
- // built-in protocol classes.
11155
- if (types_1.ClassType.supportsAbstractMethods(argType) ||
11156
- (types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
11157
- classType.details.flags |= 1024 /* SupportsAbstractMethods */;
11284
+ else {
11285
+ metaclassNode = arg.valueExpression;
11158
11286
  }
11159
- if (types_1.ClassType.isPropertyClass(argType)) {
11160
- classType.details.flags |= 2048 /* PropertyClass */;
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);
11161
11295
  }
11162
- if (types_1.ClassType.isFinal(argType)) {
11163
- const className = printObjectTypeForClass(argType);
11164
- addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
11296
+ else if (arg.name.value === 'total' && !constArgValue) {
11297
+ classType.details.flags |= 256 /* CanOmitDictValues */;
11298
+ }
11299
+ else if (arg.name.value === 'readonly' && constArgValue) {
11300
+ classType.details.flags |= 512 /* DictValuesReadOnly */;
11165
11301
  }
11166
11302
  }
11167
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11168
- if ((0, types_1.isInstantiableClass)(argType)) {
11169
- if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
11170
- // 'Generic' is implicitly added if type parameter syntax is used.
11171
- if (node.typeParameters) {
11172
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
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;
11173
11322
  }
11174
- else {
11175
- if (!genericTypeParameters) {
11176
- if (protocolTypeParameters) {
11177
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11178
- }
11179
- genericTypeParameters = [];
11180
- (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11181
- }
11323
+ else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11324
+ foundIllegalBaseClass = true;
11182
11325
  }
11183
11326
  }
11184
- else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
11185
- argType.typeArguments &&
11186
- argType.typeArguments.length > 0) {
11187
- if (!protocolTypeParameters) {
11188
- if (genericTypeParameters) {
11189
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
11190
- }
11191
- protocolTypeParameters = [];
11192
- (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
11193
- if (node.typeParameters && protocolTypeParameters.length > 0) {
11194
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
11195
- protocolTypeParameters = [];
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
+ });
11196
11419
  }
11197
11420
  }
11198
11421
  }
11199
11422
  }
11200
11423
  }
11201
- else if (arg.name.value === 'metaclass') {
11202
- if (metaclassNode) {
11203
- addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
11204
- }
11205
- else {
11206
- metaclassNode = arg.valueExpression;
11207
- }
11208
- }
11209
- else if (types_1.ClassType.isTypedDictClass(classType) &&
11210
- (arg.name.value === 'total' || arg.name.value === 'readonly')) {
11211
- // The "total" and "readonly" parameters apply only for TypedDict classes.
11212
- // PEP 589 specifies that the parameter must be either True or False.
11213
- const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
11214
- if (constArgValue === undefined) {
11215
- addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
11216
- }
11217
- else if (arg.name.value === 'total' && !constArgValue) {
11218
- classType.details.flags |= 256 /* CanOmitDictValues */;
11219
- }
11220
- else if (arg.name.value === 'readonly' && constArgValue) {
11221
- classType.details.flags |= 512 /* DictValuesReadOnly */;
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 */;
11222
11431
  }
11223
11432
  }
11224
- else {
11225
- // Collect arguments that will be passed to the `__init_subclass__`
11226
- // method described in PEP 487.
11227
- initSubclassArgs.push({
11228
- argumentCategory: 0 /* Simple */,
11229
- node: arg,
11230
- name: arg.name,
11231
- valueExpression: arg.valueExpression,
11232
- });
11233
- }
11234
- });
11235
- // Check for NamedTuple multiple inheritance.
11236
- if (classType.details.baseClasses.length > 1) {
11237
- let derivesFromNamedTuple = false;
11238
- let foundIllegalBaseClass = false;
11239
- classType.details.baseClasses.forEach((baseClass) => {
11240
- if ((0, types_1.isInstantiableClass)(baseClass)) {
11241
- if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
11242
- derivesFromNamedTuple = true;
11243
- }
11244
- else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11245
- foundIllegalBaseClass = true;
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);
11246
11439
  }
11247
- }
11248
- });
11249
- if (derivesFromNamedTuple && foundIllegalBaseClass) {
11250
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedTupleMultipleInheritance(), node.name);
11251
- }
11252
- }
11253
- // Make sure we don't have 'object' derive from itself. Infinite
11254
- // recursion will result.
11255
- if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
11256
- classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
11257
- // If there are no other (known) base classes, the class implicitly derives from object.
11258
- classType.details.baseClasses.push(getBuiltInType(node, 'object'));
11259
- }
11260
- // If genericTypeParameters or protocolTypeParameters are provided,
11261
- // make sure that typeParameters is a proper subset.
11262
- genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
11263
- if (genericTypeParameters && !node.typeParameters) {
11264
- verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
11265
- }
11266
- classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
11267
- // Determine if one or more type parameters is autovariance.
11268
- if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
11269
- classType.details.requiresVarianceInference = true;
11270
- }
11271
- // Make sure there's at most one variadic type parameter.
11272
- const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
11273
- if (variadics.length > 1) {
11274
- addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
11275
- names: variadics.map((v) => `"${v.details.name}"`).join(', '),
11276
- }), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
11277
- }
11278
- // Validate the default types for all type parameters.
11279
- classType.details.typeParameters.forEach((typeParam, index) => {
11280
- var _a;
11281
- let bestErrorNode = node.name;
11282
- if (node.typeParameters && index < node.typeParameters.parameters.length) {
11283
- const typeParamNode = node.typeParameters.parameters[index];
11284
- bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
11285
- }
11286
- validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
11287
- });
11288
- if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
11289
- addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
11290
- }
11291
- // The scope for this class becomes the "fields" for the corresponding type.
11292
- const innerScope = ScopeUtils.getScopeForNode(node.suite);
11293
- classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
11294
- ? new Map(innerScope.symbolTable)
11295
- : new Map();
11296
- // Determine whether the class should inherit __hash__. If a class defines
11297
- // __eq__ but doesn't define __hash__ then __hash__ is set to None.
11298
- if (classType.details.fields.has('__eq__') && !classType.details.fields.has('__hash__')) {
11299
- classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ | 128 /* ClassVar */ | 64 /* IgnoredForProtocolMatch */, types_1.NoneType.createInstance()));
11300
- }
11301
- // Determine whether the class's instance variables are constrained
11302
- // to those defined by __slots__. We need to do this prior to dataclass
11303
- // processing because dataclasses can implicitly add to the slots
11304
- // list.
11305
- const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
11306
- if (slotsNames) {
11307
- classType.details.localSlotsNames = slotsNames;
11308
- }
11309
- // Determine if the class should be a "pseudo-generic" class, characterized
11310
- // by having an __init__ method with parameters that lack type annotations.
11311
- // For such classes, we'll treat them as generic, with the type arguments provided
11312
- // by the callers of the constructor.
11313
- if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
11314
- const initMethod = classType.details.fields.get('__init__');
11315
- if (initMethod) {
11316
- const initDecls = initMethod.getTypedDeclarations();
11317
- if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
11318
- const initDeclNode = initDecls[0].node;
11319
- const initParams = initDeclNode.parameters;
11320
- if (initParams.length > 1 &&
11321
- !initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
11322
- const genericParams = initParams.filter((param, index) => index > 0 &&
11323
- param.name &&
11324
- param.category === 0 /* Simple */ &&
11325
- !param.defaultValue);
11326
- if (genericParams.length > 0) {
11327
- classType.details.flags |= 16384 /* PseudoGenericClass */;
11328
- // Create a type parameter for each simple, named parameter
11329
- // in the __init__ method.
11330
- classType.details.typeParameters = genericParams.map((param) => {
11331
- const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
11332
- typeVar.details.isSynthesized = true;
11333
- typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
11334
- typeVar.details.boundType = types_1.UnknownType.create();
11335
- return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
11336
- });
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 */;
11337
11447
  }
11338
11448
  }
11339
11449
  }
11340
11450
  }
11341
- }
11342
- // Determine if the class has a custom __class_getitem__ method. This applies
11343
- // only to classes that have no type parameters, since those with type parameters
11344
- // are assumed to follow normal subscripting semantics for generic classes.
11345
- if (classType.details.typeParameters.length === 0 && !types_1.ClassType.isBuiltIn(classType, 'type')) {
11346
- if (classType.details.baseClasses.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.hasCustomClassGetItem(baseClass)) ||
11347
- classType.details.fields.has('__class_getitem__')) {
11348
- classType.details.flags |= 262144 /* HasCustomClassGetItem */;
11349
- }
11350
- }
11351
- // Determine the effective metaclass.
11352
- if (metaclassNode) {
11353
- const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
11354
- if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
11355
- if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
11356
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
11357
- }
11358
- classType.details.declaredMetaclass = metaclassType;
11359
- if ((0, types_1.isInstantiableClass)(metaclassType)) {
11360
- if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
11361
- classType.details.flags |= 1048576 /* EnumClass */;
11362
- }
11363
- else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
11364
- classType.details.flags |= 1024 /* SupportsAbstractMethods */;
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;
11365
11466
  }
11366
11467
  }
11367
- }
11368
- }
11369
- const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
11370
- // Clear the "partially constructed" flag.
11371
- classType.details.flags &= ~131072 /* PartiallyEvaluated */;
11372
- // Now determine the decorated type of the class.
11373
- let decoratedType = classType;
11374
- let foundUnknown = false;
11375
- for (let i = node.decorators.length - 1; i >= 0; i--) {
11376
- const decorator = node.decorators[i];
11377
- const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
11378
- const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
11379
- if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
11380
- // Report this error only on the first unknown type.
11381
- if (!foundUnknown) {
11382
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
11383
- foundUnknown = true;
11468
+ else {
11469
+ // Apply the decorator only if the type is known.
11470
+ decoratedType = newDecoratedType;
11384
11471
  }
11385
11472
  }
11386
- else {
11387
- // Apply the decorator only if the type is known.
11388
- 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;
11389
11478
  }
11390
- }
11391
- // Determine whether this class derives from (or has a metaclass) that imbues
11392
- // it with dataclass-like behaviors. If so, we'll apply those here.
11393
- let dataClassBehaviors;
11394
- if ((0, types_1.isInstantiableClass)(effectiveMetaclass) && effectiveMetaclass.details.classDataClassTransform) {
11395
- dataClassBehaviors = effectiveMetaclass.details.classDataClassTransform;
11396
- }
11397
- else {
11398
- const baseClassDataTransform = classType.details.mro.find((mroClass) => {
11399
- return ((0, types_1.isClass)(mroClass) &&
11400
- mroClass.details.classDataClassTransform !== undefined &&
11401
- !types_1.ClassType.isSameGenericClass(mroClass, classType));
11402
- });
11403
- if (baseClassDataTransform) {
11404
- dataClassBehaviors = baseClassDataTransform.details.classDataClassTransform;
11405
- }
11406
- }
11407
- if (dataClassBehaviors) {
11408
- (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11409
- (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11410
- }
11411
- // Run any deferred class completions that depend on this class.
11412
- runDeferredClassCompletions(classType);
11413
- // If there are any outstanding deferred class completions registered that
11414
- // were not removed by the call to runDeferredClassCompletions, assume that
11415
- // the current class may depend on them and register for deferred completion.
11416
- registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
11417
- // Synthesize TypedDict methods.
11418
- if (types_1.ClassType.isTypedDictClass(classType)) {
11419
- (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
11420
- }
11421
- // Synthesize dataclass methods.
11422
- if (types_1.ClassType.isDataClass(classType)) {
11423
- const skipSynthesizedInit = types_1.ClassType.isSkipSynthesizedDataClassInit(classType);
11424
- let hasExistingInitMethod = skipSynthesizedInit;
11425
- // See if there's already a non-synthesized __init__ method.
11426
- // We shouldn't override it.
11427
- if (!skipSynthesizedInit) {
11428
- const initSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 2 /* SkipBaseClasses */);
11429
- if (initSymbol) {
11430
- hasExistingInitMethod = true;
11431
- }
11432
- }
11433
- let skipSynthesizeHash = false;
11434
- const hashSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__hash__', 2 /* SkipBaseClasses */);
11435
- if (hashSymbol) {
11436
- skipSynthesizeHash = true;
11437
- }
11438
- (0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
11439
- }
11440
- // Build a complete list of all slots names defined by the class hierarchy.
11441
- // This needs to be done after dataclass processing.
11442
- if (classType.details.localSlotsNames) {
11443
- let isLimitedToSlots = true;
11444
- const extendedSlotsNames = Array.from(classType.details.localSlotsNames);
11445
- classType.details.baseClasses.forEach((baseClass) => {
11446
- if ((0, types_1.isInstantiableClass)(baseClass)) {
11447
- if (!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
11448
- !types_1.ClassType.isBuiltIn(baseClass, 'type') &&
11449
- !types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
11450
- if (baseClass.details.inheritedSlotsNames === undefined) {
11451
- isLimitedToSlots = false;
11452
- }
11453
- else {
11454
- (0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
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
+ }
11455
11538
  }
11456
11539
  }
11540
+ else {
11541
+ isLimitedToSlots = false;
11542
+ }
11543
+ });
11544
+ if (isLimitedToSlots) {
11545
+ classType.details.inheritedSlotsNames = extendedSlotsNames;
11457
11546
  }
11458
- else {
11459
- isLimitedToSlots = false;
11460
- }
11461
- });
11462
- if (isLimitedToSlots) {
11463
- classType.details.inheritedSlotsNames = extendedSlotsNames;
11464
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;
11465
11561
  }
11466
- // Update the undecorated class type.
11467
- writeTypeCache(node.name, { type: classType }, 0 /* None */);
11468
- // Update the decorated class type.
11469
- writeTypeCache(node, { type: decoratedType }, 0 /* None */);
11470
- return { classType, decoratedType };
11471
11562
  }
11472
11563
  // Determines whether the type parameters has a default that refers to another
11473
11564
  // type parameter. If so, validates that it is in the list of "live" type
@@ -15720,6 +15811,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15720
15811
  const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
15721
15812
  let effectiveFlags;
15722
15813
  let errorSource;
15814
+ let includeDiagAddendum = true;
15723
15815
  if (variance === 3 /* Covariant */) {
15724
15816
  effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
15725
15817
  errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
@@ -15732,6 +15824,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15732
15824
  else {
15733
15825
  effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
15734
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;
15735
15830
  }
15736
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)) {
15737
15832
  // Don't report errors with type variables in "pseudo-random"
@@ -15744,6 +15839,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15744
15839
  name: types_1.TypeVarType.getReadableName(destTypeParam),
15745
15840
  ...printSrcDestTypes(srcTypeArg, destTypeArg),
15746
15841
  }));
15842
+ if (includeDiagAddendum) {
15843
+ childDiag.addAddendum(assignmentDiag);
15844
+ }
15747
15845
  }
15748
15846
  else {
15749
15847
  diag.addAddendum(assignmentDiag);
@@ -16965,7 +17063,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16965
17063
  }
16966
17064
  }
16967
17065
  }
16968
- else {
17066
+ else if (!srcParamDetails.paramSpec) {
16969
17067
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.functionTooManyParams().format({
16970
17068
  expected: srcPositionalCount,
16971
17069
  received: destPositionalCount,