@zzzen/pyright-internal 1.2.0-dev.20231105 → 1.2.0-dev.20231112

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 (110) hide show
  1. package/dist/analyzer/checker.js +45 -58
  2. package/dist/analyzer/checker.js.map +1 -1
  3. package/dist/analyzer/codeFlowEngine.js +12 -33
  4. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  5. package/dist/analyzer/constraintSolver.js +20 -21
  6. package/dist/analyzer/constraintSolver.js.map +1 -1
  7. package/dist/analyzer/constructorTransform.js +3 -5
  8. package/dist/analyzer/constructorTransform.js.map +1 -1
  9. package/dist/analyzer/constructors.d.ts +6 -3
  10. package/dist/analyzer/constructors.js +43 -23
  11. package/dist/analyzer/constructors.js.map +1 -1
  12. package/dist/analyzer/dataClasses.js +10 -15
  13. package/dist/analyzer/dataClasses.js.map +1 -1
  14. package/dist/analyzer/declarationUtils.js +1 -1
  15. package/dist/analyzer/declarationUtils.js.map +1 -1
  16. package/dist/analyzer/decorators.js +1 -1
  17. package/dist/analyzer/decorators.js.map +1 -1
  18. package/dist/analyzer/enums.js +1 -1
  19. package/dist/analyzer/enums.js.map +1 -1
  20. package/dist/analyzer/importResolver.d.ts +2 -1
  21. package/dist/analyzer/importResolver.js +17 -5
  22. package/dist/analyzer/importResolver.js.map +1 -1
  23. package/dist/analyzer/importStatementUtils.d.ts +1 -1
  24. package/dist/analyzer/importStatementUtils.js +33 -5
  25. package/dist/analyzer/importStatementUtils.js.map +1 -1
  26. package/dist/analyzer/operations.js +12 -6
  27. package/dist/analyzer/operations.js.map +1 -1
  28. package/dist/analyzer/packageTypeVerifier.js +9 -5
  29. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  30. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  31. package/dist/analyzer/parseTreeUtils.js +17 -2
  32. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  33. package/dist/analyzer/patternMatching.js +1 -1
  34. package/dist/analyzer/patternMatching.js.map +1 -1
  35. package/dist/analyzer/program.js +17 -9
  36. package/dist/analyzer/program.js.map +1 -1
  37. package/dist/analyzer/properties.js +20 -23
  38. package/dist/analyzer/properties.js.map +1 -1
  39. package/dist/analyzer/protocols.d.ts +1 -1
  40. package/dist/analyzer/protocols.js +14 -18
  41. package/dist/analyzer/protocols.js.map +1 -1
  42. package/dist/analyzer/service.js +1 -2
  43. package/dist/analyzer/service.js.map +1 -1
  44. package/dist/analyzer/sourceFile.js +33 -2
  45. package/dist/analyzer/sourceFile.js.map +1 -1
  46. package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -1
  47. package/dist/analyzer/sourceFileInfoUtils.js +9 -3
  48. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  49. package/dist/analyzer/typeEvaluator.d.ts +3 -1
  50. package/dist/analyzer/typeEvaluator.js +551 -580
  51. package/dist/analyzer/typeEvaluator.js.map +1 -1
  52. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -2
  53. package/dist/analyzer/typeGuards.js +10 -9
  54. package/dist/analyzer/typeGuards.js.map +1 -1
  55. package/dist/analyzer/typeUtils.js +3 -1
  56. package/dist/analyzer/typeUtils.js.map +1 -1
  57. package/dist/analyzer/types.d.ts +3 -1
  58. package/dist/analyzer/types.js +1 -1
  59. package/dist/analyzer/types.js.map +1 -1
  60. package/dist/common/configOptions.d.ts +2 -1
  61. package/dist/common/configOptions.js +18 -1
  62. package/dist/common/configOptions.js.map +1 -1
  63. package/dist/common/extensibility.d.ts +3 -0
  64. package/dist/common/serviceProviderExtensions.d.ts +2 -1
  65. package/dist/common/serviceProviderExtensions.js +1 -0
  66. package/dist/common/serviceProviderExtensions.js.map +1 -1
  67. package/dist/common/textEditTracker.js +2 -2
  68. package/dist/common/textEditTracker.js.map +1 -1
  69. package/dist/languageServerBase.d.ts +1 -1
  70. package/dist/languageServerBase.js +4 -1
  71. package/dist/languageServerBase.js.map +1 -1
  72. package/dist/languageService/completionProvider.d.ts +2 -1
  73. package/dist/languageService/completionProvider.js +4 -2
  74. package/dist/languageService/completionProvider.js.map +1 -1
  75. package/dist/localization/localize.d.ts +4 -0
  76. package/dist/localization/localize.js +2 -0
  77. package/dist/localization/localize.js.map +1 -1
  78. package/dist/localization/package.nls.cs.json +3 -0
  79. package/dist/localization/package.nls.de.json +3 -0
  80. package/dist/localization/package.nls.en-us.json +3 -1
  81. package/dist/localization/package.nls.es.json +3 -0
  82. package/dist/localization/package.nls.fr.json +3 -0
  83. package/dist/localization/package.nls.it.json +3 -0
  84. package/dist/localization/package.nls.ja.json +3 -0
  85. package/dist/localization/package.nls.ko.json +3 -0
  86. package/dist/localization/package.nls.pl.json +3 -0
  87. package/dist/localization/package.nls.pt-br.json +3 -0
  88. package/dist/localization/package.nls.qps-ploc.json +3 -0
  89. package/dist/localization/package.nls.ru.json +3 -0
  90. package/dist/localization/package.nls.tr.json +3 -0
  91. package/dist/localization/package.nls.zh-cn.json +3 -0
  92. package/dist/localization/package.nls.zh-tw.json +3 -0
  93. package/dist/server.js.map +1 -1
  94. package/dist/tests/diagnosticOverrides.test.js +4 -2
  95. package/dist/tests/diagnosticOverrides.test.js.map +1 -1
  96. package/dist/tests/fourslash/signature.dunderNew.fourslash.js +1 -1
  97. package/dist/tests/fourslash/signature.dunderNew.fourslash.js.map +1 -1
  98. package/dist/tests/harness/fourslash/testState.js +3 -3
  99. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  100. package/dist/tests/parseTreeUtils.test.js +15 -0
  101. package/dist/tests/parseTreeUtils.test.js.map +1 -1
  102. package/dist/tests/textEditUtil.test.js +25 -0
  103. package/dist/tests/textEditUtil.test.js.map +1 -1
  104. package/dist/tests/typeEvaluator1.test.js +4 -0
  105. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  106. package/dist/tests/typeEvaluator2.test.js +4 -0
  107. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  108. package/dist/tests/typeEvaluator3.test.js +3 -3
  109. package/dist/tests/typeEvaluator4.test.js +5 -5
  110. package/package.json +1 -1
@@ -1297,9 +1297,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1297
1297
  // using the objectType parameter. Callers can specify these separately
1298
1298
  // to handle the case where we're fetching the object member from a
1299
1299
  // metaclass but binding to the class.
1300
- function getTypeOfObjectMember(errorNode, objectType, memberName, usage = { method: 'get' }, diag = undefined, flags = 0 /* Default */, selfType) {
1300
+ function getTypeOfBoundMember(errorNode, objectType, memberName, usage = { method: 'get' }, diag = undefined, flags = 0 /* Default */, selfType, recursionCount = 0) {
1301
1301
  if (types_1.ClassType.isPartiallyEvaluated(objectType)) {
1302
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: objectType.details.name }), errorNode);
1302
+ if (errorNode) {
1303
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: objectType.details.name }), errorNode);
1304
+ }
1303
1305
  return { type: types_1.UnknownType.create() };
1304
1306
  }
1305
1307
  // Determine the class that was used to instantiate the objectType.
@@ -1357,7 +1359,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1357
1359
  effectiveFlags &= ~16 /* SkipInstanceMembers */;
1358
1360
  }
1359
1361
  const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
1360
- memberInfo = getTypeOfClassMemberName(errorNode, types_1.ClassType.cloneAsInstance(metaclass), memberName, usage, metaclassDiag, effectiveFlags, objectTypeIsInstantiable ? objectType : types_1.ClassType.cloneAsInstantiable(objectType));
1362
+ memberInfo = getTypeOfClassMemberName(errorNode, types_1.ClassType.cloneAsInstance(metaclass), memberName, usage, metaclassDiag, effectiveFlags, objectTypeIsInstantiable ? objectType : types_1.ClassType.cloneAsInstantiable(objectType), recursionCount);
1361
1363
  // If there was a descriptor error (as opposed to an error where the members
1362
1364
  // was simply not found), use this diagnostic message.
1363
1365
  if (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isDescriptorError) {
@@ -1378,20 +1380,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1378
1380
  }
1379
1381
  return undefined;
1380
1382
  }
1381
- function getBoundMethod(classType, memberName, recursionCount = 0) {
1382
- const memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, 16 /* SkipInstanceMembers */);
1383
- if (!memberInfo) {
1383
+ function getBoundMagicMethod(classType, memberName, selfType, recursionCount = 0) {
1384
+ const boundMethodResult = getTypeOfBoundMember(
1385
+ /* errorNode */ undefined, classType, memberName,
1386
+ /* usage */ undefined,
1387
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */, selfType, recursionCount);
1388
+ if (!boundMethodResult || boundMethodResult.typeErrors) {
1384
1389
  return undefined;
1385
1390
  }
1386
- const unboundMethodType = getTypeOfMember(memberInfo);
1387
- if ((0, types_1.isFunction)(unboundMethodType) || (0, types_1.isOverloadedFunction)(unboundMethodType)) {
1388
- return bindFunctionToClassOrObject(types_1.ClassType.cloneAsInstance(classType), unboundMethodType,
1389
- /* memberClass */ undefined,
1390
- /* treatConstructorAsClassMember */ true,
1391
- /* selfType */ undefined,
1392
- /* diag */ undefined, recursionCount);
1391
+ if ((0, types_1.isFunction)(boundMethodResult.type) || (0, types_1.isOverloadedFunction)(boundMethodResult.type)) {
1392
+ return boundMethodResult.type;
1393
1393
  }
1394
- if ((0, types_1.isAnyOrUnknown)(unboundMethodType)) {
1394
+ if ((0, types_1.isAnyOrUnknown)(boundMethodResult.type)) {
1395
1395
  const unknownFunction = types_1.FunctionType.createSynthesizedInstance('', 32768 /* SkipArgsKwargsCompatibilityCheck */);
1396
1396
  types_1.FunctionType.addDefaultParameters(unknownFunction);
1397
1397
  return unknownFunction;
@@ -1472,35 +1472,39 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1472
1472
  }
1473
1473
  case 6 /* Class */: {
1474
1474
  if (types_1.TypeBase.isInstantiable(subtype)) {
1475
- let methodType;
1475
+ let constructorType;
1476
1476
  // Try to get the `__init__` method first because it typically has more
1477
1477
  // type information than `__new__`.
1478
- methodType = getBoundMethod(subtype, '__init__');
1479
- // Is this the __init__ method provided by the object class?
1480
- const isObjectInit = !!methodType &&
1481
- (0, types_1.isFunction)(methodType) &&
1482
- methodType.details.fullName === 'builtins.object.__init__';
1483
- const isDefaultParams = methodType && (0, types_1.isFunction)(methodType) && types_1.FunctionType.hasDefaultParameters(methodType);
1478
+ const initMethodResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, callNode, types_1.ClassType.cloneAsInstance(subtype),
1479
+ /* skipObjectBase */ false);
1480
+ if (initMethodResult && !initMethodResult.typeErrors && (0, types_1.isFunction)(initMethodResult.type)) {
1481
+ constructorType = initMethodResult.type;
1482
+ }
1483
+ const isObjectInit = constructorType &&
1484
+ (0, types_1.isFunction)(constructorType) &&
1485
+ constructorType.details.fullName === 'builtins.object.__init__';
1486
+ const isDefaultParams = constructorType &&
1487
+ (0, types_1.isFunction)(constructorType) &&
1488
+ types_1.FunctionType.hasDefaultParameters(constructorType);
1484
1489
  // If there was no `__init__` or the only `__init__` that was found was from
1485
1490
  // the `object` class or accepts only default parameters(* args, ** kwargs),
1486
1491
  // see if we can find a better signature from the `__new__` method.
1487
- if (!methodType || isObjectInit || isDefaultParams) {
1488
- const constructorType = getBoundMethod(subtype, '__new__');
1489
- if (constructorType) {
1490
- // Is this the __new__ method provided by the object class?
1491
- const isObjectNew = (0, types_1.isFunction)(constructorType) &&
1492
- constructorType.details.fullName === 'builtins.object.__new__';
1493
- if (!isObjectNew) {
1494
- methodType = constructorType;
1495
- }
1492
+ if (!constructorType || isObjectInit || isDefaultParams) {
1493
+ const newMethodResult = (0, constructors_1.getBoundNewMethod)(evaluatorInterface, callNode, subtype,
1494
+ /* skipObjectBase */ false);
1495
+ if (newMethodResult &&
1496
+ !newMethodResult.typeErrors &&
1497
+ (0, types_1.isFunction)(newMethodResult.type) &&
1498
+ newMethodResult.type.details.fullName !== 'builtins.object.__new__') {
1499
+ constructorType = newMethodResult.type;
1496
1500
  }
1497
1501
  }
1498
- if (methodType) {
1499
- addFunctionToSignature(methodType);
1502
+ if (constructorType) {
1503
+ addFunctionToSignature(constructorType);
1500
1504
  }
1501
1505
  }
1502
1506
  else {
1503
- const methodType = getBoundMethod(subtype, '__call__');
1507
+ const methodType = getBoundMagicMethod(subtype, '__call__');
1504
1508
  if (methodType) {
1505
1509
  addFunctionToSignature(methodType);
1506
1510
  }
@@ -1635,20 +1639,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1635
1639
  case 24 /* Index */: {
1636
1640
  const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.baseExpression, 2 /* IndexBaseDefaults */).type);
1637
1641
  if (baseType && (0, types_1.isClassInstance)(baseType)) {
1638
- const setItemMember = (0, typeUtils_1.lookUpClassMember)(baseType, '__setitem__');
1639
- if (setItemMember) {
1640
- const setItemType = getTypeOfMember(setItemMember);
1641
- if ((0, types_1.isFunction)(setItemType)) {
1642
- const boundFunction = bindFunctionToClassOrObjectWithErrors(baseType, setItemType, (0, types_1.isInstantiableClass)(setItemMember.classType) ? setItemMember.classType : undefined, expression,
1643
- /* treatConstructorAsClassMember */ false);
1644
- if (boundFunction && (0, types_1.isFunction)(boundFunction)) {
1645
- if (boundFunction.details.parameters.length >= 2) {
1646
- const paramType = types_1.FunctionType.getEffectiveParameterType(boundFunction, 1);
1647
- if (!(0, types_1.isAnyOrUnknown)(paramType)) {
1648
- return paramType;
1649
- }
1650
- }
1651
- }
1642
+ const setItemType = getBoundMagicMethod(baseType, '__setitem__');
1643
+ if (setItemType && (0, types_1.isFunction)(setItemType) && setItemType.details.parameters.length >= 2) {
1644
+ const paramType = types_1.FunctionType.getEffectiveParameterType(setItemType, 1);
1645
+ if (!(0, types_1.isAnyOrUnknown)(paramType)) {
1646
+ return paramType;
1652
1647
  }
1653
1648
  }
1654
1649
  else if (types_1.ClassType.isTypedDictClass(baseType)) {
@@ -1666,14 +1661,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1666
1661
  if (declaredType) {
1667
1662
  // If it's a descriptor, we need to get the setter type.
1668
1663
  if (useDescriptorSetterType && (0, types_1.isClassInstance)(declaredType)) {
1669
- const setterInfo = (0, typeUtils_1.lookUpClassMember)(declaredType, '__set__');
1670
- const setter = setterInfo ? getTypeOfMember(setterInfo) : undefined;
1671
- if (setterInfo && setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 3) {
1672
- declaredType = setter.details.parameters[2].type;
1673
- if ((0, types_1.isClass)(setterInfo.classType)) {
1674
- const typeVarMap = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(setterInfo.classType);
1675
- declaredType = (0, typeUtils_1.applySolvedTypeVars)(declaredType, typeVarMap);
1676
- }
1664
+ const setter = getBoundMagicMethod(declaredType, '__set__');
1665
+ if (setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 2) {
1666
+ declaredType = setter.details.parameters[1].type;
1677
1667
  if ((0, types_1.isAnyOrUnknown)(declaredType)) {
1678
1668
  return undefined;
1679
1669
  }
@@ -1685,8 +1675,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1685
1675
  }
1686
1676
  if ((0, types_1.isFunction)(declaredType) || (0, types_1.isOverloadedFunction)(declaredType)) {
1687
1677
  if (bindFunction) {
1688
- declaredType = bindFunctionToClassOrObjectWithErrors(classOrObjectBase, declaredType,
1689
- /* memberAccessClass */ undefined, expression);
1678
+ declaredType = bindFunctionToClassOrObject(classOrObjectBase, declaredType);
1690
1679
  }
1691
1680
  }
1692
1681
  }
@@ -3323,7 +3312,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3323
3312
  }
3324
3313
  if (typeParametersForScope) {
3325
3314
  const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
3326
- if (match === null || match === void 0 ? void 0 : match.scopeId) {
3315
+ if ((match === null || match === void 0 ? void 0 : match.scopeId) !== undefined && match.scopeName !== undefined && match.scopeType !== undefined) {
3327
3316
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
3328
3317
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
3329
3318
  return {
@@ -3559,7 +3548,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3559
3548
  }, usage, 0 /* None */);
3560
3549
  }
3561
3550
  case 6 /* Class */: {
3562
- const typeResult = (_a = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete)) !== null && _a !== void 0 ? _a : getTypeOfObjectMember(node.memberName, baseType, memberName, usage, diag,
3551
+ const typeResult = (_a = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete)) !== null && _a !== void 0 ? _a : getTypeOfBoundMember(node.memberName, baseType, memberName, usage, diag,
3563
3552
  /* memberAccessFlags */ undefined, baseTypeResult.bindToSelfType);
3564
3553
  if (typeResult) {
3565
3554
  type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
@@ -3651,7 +3640,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3651
3640
  return undefined;
3652
3641
  }
3653
3642
  if ((0, typeUtils_1.isNoneInstance)(subtype) && noneType && (0, types_1.isClassInstance)(noneType)) {
3654
- const typeResult = getTypeOfObjectMember(node.memberName, noneType, memberName, usage, diag);
3643
+ const typeResult = getTypeOfBoundMember(node.memberName, noneType, memberName, usage, diag);
3655
3644
  if (typeResult) {
3656
3645
  type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
3657
3646
  if (typeResult.isIncomplete) {
@@ -3732,8 +3721,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3732
3721
  }
3733
3722
  return { type, isIncomplete, isAsymmetricAccessor, isRequired, isNotRequired, memberAccessDeprecationInfo };
3734
3723
  }
3735
- function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType) {
3736
- var _a, _b, _c, _d;
3724
+ function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType, recursionCount = 0) {
3725
+ var _a, _b, _c;
3737
3726
  const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
3738
3727
  // Always look for a member with a declared type first.
3739
3728
  let memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, flags | 64 /* DeclaredTypesOnly */);
@@ -3746,8 +3735,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3746
3735
  // No attribute of that name was found. If this is a member access
3747
3736
  // through an object, see if there's an attribute access override
3748
3737
  // method ("__getattr__", etc.).
3749
- if ((flags & 512 /* SkipAttributeAccessOverride */) === 0) {
3750
- const generalAttrType = applyAttributeAccessOverride(classType, errorNode, usage, memberName, selfType);
3738
+ if ((flags & 512 /* SkipAttributeAccessOverride */) === 0 && errorNode) {
3739
+ const generalAttrType = applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType);
3751
3740
  if (generalAttrType) {
3752
3741
  return {
3753
3742
  symbol: undefined,
@@ -3756,7 +3745,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3756
3745
  isDescriptorError: false,
3757
3746
  isClassMember: false,
3758
3747
  isClassVar: false,
3759
- isAsymmetricAccessor: generalAttrType.isAsymmetricAccessor,
3748
+ isAsymmetricAccessor: !!generalAttrType.isAsymmetricAccessor,
3760
3749
  };
3761
3750
  }
3762
3751
  }
@@ -3770,7 +3759,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3770
3759
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsInitVar().format({ name: memberName }));
3771
3760
  return undefined;
3772
3761
  }
3773
- if (usage.method !== 'get') {
3762
+ if (usage.method !== 'get' && errorNode) {
3774
3763
  // If the usage indicates a 'set' or 'delete' and the access is within the
3775
3764
  // class definition itself, use only the declared type to avoid circular
3776
3765
  // type evaluation.
@@ -3805,23 +3794,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3805
3794
  }
3806
3795
  }
3807
3796
  if (!type) {
3808
- let selfClass = classType;
3809
- // Determine whether to replace Self variables with a specific
3810
- // class. Avoid doing this if there's a "selfType" specified
3811
- // because that case is used for super() calls where we want
3812
- // to leave the Self type generic (not specialized). We'll also
3813
- // skip this for __new__ methods because they are not bound
3814
- // to the class but rather assume the type of the cls argument.
3797
+ let selfClass;
3815
3798
  if (selfType) {
3816
- if ((0, types_1.isTypeVar)(selfType) && selfType.details.isSynthesizedSelf) {
3817
- selfClass = selfType;
3818
- }
3819
- else {
3820
- selfClass = undefined;
3821
- }
3799
+ selfClass = (0, typeUtils_1.convertToInstantiable)(selfType);
3822
3800
  }
3823
- else if (memberName === '__new__') {
3824
- selfClass = undefined;
3801
+ else {
3802
+ // Skip this for __new__ methods because they are not bound
3803
+ // to the class but rather assume the type of the cls argument.
3804
+ if (memberName !== '__new__') {
3805
+ selfClass = classType;
3806
+ }
3825
3807
  }
3826
3808
  const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3827
3809
  type = (_c = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
@@ -3839,7 +3821,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3839
3821
  }
3840
3822
  if (usage.method === 'get') {
3841
3823
  // Mark the member accessed if it's not coming from a parent class.
3842
- if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3824
+ if (errorNode &&
3825
+ (0, types_1.isInstantiableClass)(memberInfo.classType) &&
3843
3826
  types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
3844
3827
  setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
3845
3828
  }
@@ -3852,32 +3835,96 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3852
3835
  }
3853
3836
  }
3854
3837
  }
3855
- const descResult = applyDescriptorAccessMethod(type, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag);
3856
- let isDescriptorError = true;
3857
- if (descResult) {
3858
- isDescriptorError = false;
3859
- type = descResult.type;
3860
- if (usage.method === 'set' && usage.setType) {
3861
- // Verify that the assigned type is compatible.
3862
- if (!assignType(type, usage.setType.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum())) {
3863
- if (!usage.setType.isIncomplete) {
3864
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberAssignment().format({
3865
- type: printType(usage.setType.type),
3866
- name: memberName,
3867
- classType: printObjectTypeForClass(classType),
3868
- }));
3869
- }
3838
+ // If the member is a descriptor object, apply the descriptor protocol
3839
+ // now. If the member is an instance or class method, bind the method.
3840
+ let isDescriptorError = false;
3841
+ let isAsymmetricAccessor = false;
3842
+ let isDescriptorApplied = false;
3843
+ let memberAccessDeprecationInfo;
3844
+ type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
3845
+ const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
3846
+ const isClassMember = !memberInfo || memberInfo.isClassMember;
3847
+ let resultType;
3848
+ if ((0, types_1.isClass)(concreteSubtype) && isClassMember && errorNode) {
3849
+ const descResult = applyDescriptorAccessMethod(subtype, concreteSubtype, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag);
3850
+ if (descResult.isAsymmetricAccessor) {
3851
+ isAsymmetricAccessor = true;
3852
+ }
3853
+ if (descResult.memberAccessDeprecationInfo) {
3854
+ memberAccessDeprecationInfo = descResult.memberAccessDeprecationInfo;
3855
+ }
3856
+ if (descResult.typeErrors) {
3870
3857
  isDescriptorError = true;
3871
3858
  }
3872
- if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3873
- types_1.ClassType.isFrozenDataClass(memberInfo.classType) &&
3874
- isAccessedThroughObject) {
3875
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataClassFrozen().format({
3876
- name: printType(types_1.ClassType.cloneAsInstance(memberInfo.classType)),
3877
- }));
3859
+ if (descResult.isDescriptorApplied) {
3860
+ isDescriptorApplied = true;
3861
+ }
3862
+ resultType = descResult.type;
3863
+ }
3864
+ else if ((0, types_1.isFunction)(concreteSubtype) || (0, types_1.isOverloadedFunction)(concreteSubtype)) {
3865
+ const typeResult = bindMethodForMemberAccess(subtype, concreteSubtype, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount);
3866
+ resultType = typeResult.type;
3867
+ if (typeResult.typeErrors) {
3868
+ isDescriptorError = true;
3869
+ }
3870
+ }
3871
+ else {
3872
+ resultType = subtype;
3873
+ }
3874
+ // If this is a "set" operation, we have a bit more work to do.
3875
+ if (usage.method !== 'set') {
3876
+ return resultType;
3877
+ }
3878
+ // Check for an attempt to overwrite a ClassVar member from an instance.
3879
+ if (!isDescriptorApplied &&
3880
+ (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.isClassVar()) &&
3881
+ (flags & 128 /* DisallowClassVarWrites */) !== 0) {
3882
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
3883
+ isDescriptorError = true;
3884
+ }
3885
+ // Check for an attempt to overwrite a final member variable.
3886
+ const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
3887
+ if (finalVarTypeDecl &&
3888
+ errorNode &&
3889
+ !ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
3890
+ // If a Final instance variable is declared in the class body but is
3891
+ // being assigned within an __init__ method, it's allowed.
3892
+ const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
3893
+ if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
3894
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
3878
3895
  isDescriptorError = true;
3879
3896
  }
3880
3897
  }
3898
+ // Check for an attempt to overwrite an instance variable that is
3899
+ // read-only (e.g. in a named tuple).
3900
+ if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
3901
+ (0, types_1.isClass)(memberInfo.classType) &&
3902
+ types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
3903
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
3904
+ isDescriptorError = true;
3905
+ }
3906
+ return resultType;
3907
+ });
3908
+ if (!isDescriptorError && usage.method === 'set' && usage.setType) {
3909
+ // Verify that the assigned type is compatible.
3910
+ if (!assignType(type, usage.setType.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum())) {
3911
+ if (!usage.setType.isIncomplete) {
3912
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberAssignment().format({
3913
+ type: printType(usage.setType.type),
3914
+ name: memberName,
3915
+ classType: printObjectTypeForClass(classType),
3916
+ }));
3917
+ }
3918
+ isDescriptorError = true;
3919
+ }
3920
+ if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3921
+ types_1.ClassType.isFrozenDataClass(memberInfo.classType) &&
3922
+ isAccessedThroughObject) {
3923
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataClassFrozen().format({
3924
+ name: printType(types_1.ClassType.cloneAsInstance(memberInfo.classType)),
3925
+ }));
3926
+ isDescriptorError = true;
3927
+ }
3881
3928
  }
3882
3929
  return {
3883
3930
  symbol: memberInfo.symbol,
@@ -3887,329 +3934,208 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3887
3934
  isClassMember: !memberInfo.isInstanceMember,
3888
3935
  isClassVar: memberInfo.isClassVar,
3889
3936
  classType: memberInfo.classType,
3890
- isAsymmetricAccessor: (_d = descResult === null || descResult === void 0 ? void 0 : descResult.isAsymmetricAccessor) !== null && _d !== void 0 ? _d : false,
3891
- memberAccessDeprecationInfo: descResult === null || descResult === void 0 ? void 0 : descResult.memberAccessDeprecationInfo,
3937
+ isAsymmetricAccessor,
3938
+ memberAccessDeprecationInfo,
3892
3939
  };
3893
3940
  }
3894
3941
  // Applies descriptor access methods "__get__", "__set__", or "__delete__"
3895
- // if they apply. Also binds methods to the class/object through which it
3896
- // is accessed.
3897
- function applyDescriptorAccessMethod(type, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag) {
3898
- const treatConstructorAsClassMember = (flags & 256 /* TreatConstructorAsClassMethod */) !== 0;
3942
+ // if they apply.
3943
+ function applyDescriptorAccessMethod(memberType, concreteMemberType, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag) {
3944
+ var _a, _b, _c, _d;
3899
3945
  const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
3900
- let isTypeValid = true;
3946
+ let accessMethodName;
3947
+ if (usage.method === 'get') {
3948
+ accessMethodName = '__get__';
3949
+ }
3950
+ else if (usage.method === 'set') {
3951
+ accessMethodName = '__set__';
3952
+ }
3953
+ else {
3954
+ accessMethodName = '__delete__';
3955
+ }
3956
+ const methodTypeResult = getTypeOfBoundMember(errorNode, concreteMemberType, accessMethodName,
3957
+ /* usage */ undefined, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */);
3958
+ if (!methodTypeResult) {
3959
+ // Provide special error messages for properties.
3960
+ if (types_1.ClassType.isPropertyClass(concreteMemberType)) {
3961
+ if (usage.method !== 'get') {
3962
+ const message = usage.method === 'set'
3963
+ ? localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter()
3964
+ : localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter();
3965
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(message.format({ name: memberName }));
3966
+ return { type: types_1.AnyType.create(), typeErrors: true };
3967
+ }
3968
+ }
3969
+ return { type: memberType };
3970
+ }
3971
+ const methodClassType = methodTypeResult.classType;
3972
+ let methodType = methodTypeResult.type;
3973
+ if (methodTypeResult.typeErrors || !methodClassType) {
3974
+ return { type: types_1.UnknownType.create(), typeErrors: true };
3975
+ }
3976
+ if (!(0, types_1.isFunction)(methodType) && !(0, types_1.isOverloadedFunction)(methodType)) {
3977
+ if ((0, types_1.isAnyOrUnknown)(methodType)) {
3978
+ return { type: methodType };
3979
+ }
3980
+ // TODO - emit an error for this condition.
3981
+ return { type: memberType, typeErrors: true };
3982
+ }
3983
+ // Special-case logic for properties.
3984
+ if (types_1.ClassType.isPropertyClass(concreteMemberType) &&
3985
+ memberInfo &&
3986
+ (0, types_1.isInstantiableClass)(memberInfo.classType) &&
3987
+ methodType) {
3988
+ // If the property is being accessed from a protocol class (not an instance),
3989
+ // flag this as an error because a property within a protocol is meant to be
3990
+ // interpreted as a read-only attribute rather than a protocol, so accessing
3991
+ // it directly from the class has an ambiguous meaning.
3992
+ if ((flags & 16 /* SkipInstanceMembers */) !== 0 && types_1.ClassType.isProtocolClass(classType)) {
3993
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
3994
+ return { type: memberType, typeErrors: true };
3995
+ }
3996
+ // Infer return types before specializing. Otherwise a generic inferred
3997
+ // return type won't be properly specialized.
3998
+ inferReturnTypeIfNecessary(methodType);
3999
+ // This specialization is required specifically for properties, which should be
4000
+ // generic but are not defined that way. Because of this, we use type variables
4001
+ // in the synthesized methods (e.g. __get__) for the property class that are
4002
+ // defined in the class that declares the fget method.
4003
+ const specializedType = (0, typeUtils_1.partiallySpecializeType)(methodType, memberInfo.classType, selfType ? (0, typeUtils_1.convertToInstantiable)(selfType) : classType);
4004
+ if ((0, types_1.isFunction)(specializedType) || (0, types_1.isOverloadedFunction)(specializedType)) {
4005
+ methodType = specializedType;
4006
+ }
4007
+ }
4008
+ // Determine if we're calling __set__ on an asymmetric descriptor or property.
3901
4009
  let isAsymmetricAccessor = false;
3902
- let memberAccessDeprecationInfo;
3903
- type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
3904
- var _a, _b, _c;
3905
- const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
3906
- const isClassMember = !memberInfo || memberInfo.isClassMember;
3907
- if ((0, types_1.isClass)(concreteSubtype) && isClassMember) {
3908
- // If it's an object, use its class to lookup the descriptor. If it's a class,
3909
- // use its metaclass instead.
3910
- let lookupClass = concreteSubtype;
3911
- let isAccessedThroughMetaclass = false;
3912
- if (types_1.TypeBase.isInstantiable(concreteSubtype)) {
3913
- if (concreteSubtype.details.effectiveMetaclass &&
3914
- (0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass)) {
3915
- // When accessing a class member that is a class whose metaclass implements
3916
- // a descriptor protocol, only 'get' operations are allowed. If it's accessed
3917
- // through the object, all access methods are supported.
3918
- if (isAccessedThroughObject || usage.method === 'get') {
3919
- lookupClass = types_1.ClassType.cloneAsInstance(concreteSubtype.details.effectiveMetaclass);
3920
- isAccessedThroughMetaclass = true;
3921
- }
3922
- else {
3923
- lookupClass = undefined;
3924
- }
3925
- }
3926
- else {
3927
- lookupClass = undefined;
3928
- }
3929
- }
3930
- if (lookupClass) {
3931
- let accessMethodName;
3932
- if (usage.method === 'get') {
3933
- accessMethodName = '__get__';
3934
- }
3935
- else if (usage.method === 'set') {
3936
- accessMethodName = '__set__';
3937
- }
3938
- else {
3939
- accessMethodName = '__delete__';
3940
- }
3941
- const accessMethod = (0, typeUtils_1.lookUpClassMember)(lookupClass, accessMethodName, 16 /* SkipInstanceMembers */);
3942
- // Handle properties specially.
3943
- if (types_1.ClassType.isPropertyClass(lookupClass)) {
3944
- if (usage.method === 'set') {
3945
- if (!accessMethod) {
3946
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter().format({
3947
- name: memberName,
3948
- }));
3949
- isTypeValid = false;
3950
- return undefined;
3951
- }
3952
- }
3953
- else if (usage.method === 'del') {
3954
- if (!accessMethod) {
3955
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter().format({
3956
- name: memberName,
3957
- }));
3958
- isTypeValid = false;
3959
- return undefined;
3960
- }
3961
- }
3962
- }
3963
- if (accessMethod) {
3964
- let accessMethodType = getTypeOfMember(accessMethod);
3965
- const argList = [
3966
- {
3967
- // Provide "obj" argument.
3968
- argumentCategory: 0 /* Simple */,
3969
- typeResult: {
3970
- type: types_1.ClassType.isClassProperty(lookupClass)
3971
- ? classType
3972
- : isAccessedThroughObject
3973
- ? selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType)
3974
- : getNoneType(),
3975
- },
3976
- },
3977
- ];
3978
- if (usage.method === 'get') {
3979
- // Provide "owner" argument.
3980
- argList.push({
3981
- argumentCategory: 0 /* Simple */,
3982
- typeResult: {
3983
- type: isAccessedThroughObject
3984
- ? types_1.ClassType.cloneAsInstantiable(classType)
3985
- : classType,
3986
- },
3987
- });
3988
- }
3989
- else if (usage.method === 'set') {
3990
- // Provide "value" argument.
3991
- argList.push({
3992
- argumentCategory: 0 /* Simple */,
3993
- typeResult: {
3994
- type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
3995
- isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
3996
- },
3997
- });
3998
- }
3999
- if (types_1.ClassType.isPropertyClass(lookupClass) &&
4000
- memberInfo &&
4001
- (0, types_1.isInstantiableClass)(memberInfo.classType)) {
4002
- // This specialization is required specifically for properties, which should be
4003
- // generic but are not defined that way. Because of this, we use type variables
4004
- // in the synthesized methods (e.g. __get__) for the property class that are
4005
- // defined in the class that declares the fget method.
4006
- // Infer return types before specializing. Otherwise a generic inferred
4007
- // return type won't be properly specialized.
4008
- inferReturnTypeIfNecessary(accessMethodType);
4009
- accessMethodType = (0, typeUtils_1.partiallySpecializeType)(accessMethodType, memberInfo.classType);
4010
- // If the property is being accessed from a protocol class (not an instance),
4011
- // flag this as an error because a property within a protocol is meant to be
4012
- // interpreted as a read-only attribute rather than a protocol, so accessing
4013
- // it directly from the class has an ambiguous meaning.
4014
- if ((flags & 16 /* SkipInstanceMembers */) !== 0 &&
4015
- types_1.ClassType.isProtocolClass(classType)) {
4016
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
4017
- isTypeValid = false;
4018
- }
4019
- }
4020
- if (accessMethodType &&
4021
- ((0, types_1.isFunction)(accessMethodType) || (0, types_1.isOverloadedFunction)(accessMethodType))) {
4022
- const methodType = accessMethodType;
4023
- // Don't emit separate diagnostics for these method calls because
4024
- // they will be redundant.
4025
- const returnType = suppressDiagnostics(errorNode, () => {
4026
- var _a;
4027
- // Bind the accessor to the base object type.
4028
- let bindToClass;
4029
- // The "bind-to" class depends on whether the descriptor is defined
4030
- // on the metaclass or the class. We handle properties specially here
4031
- // because of the way we model the __get__ logic in the property class.
4032
- if (types_1.ClassType.isPropertyClass(concreteSubtype) && !isAccessedThroughMetaclass) {
4033
- if (memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType)) {
4034
- bindToClass = types_1.ClassType.cloneAsInstance(memberInfo.classType);
4035
- }
4036
- }
4037
- let boundMethodType = bindFunctionToClassOrObjectWithErrors(lookupClass, methodType, bindToClass, errorNode,
4038
- /* treatConstructorAsClassMember */ undefined, isAccessedThroughMetaclass ? concreteSubtype : undefined);
4039
- // The synthesized access method for the property may contain
4040
- // type variables associated with the "bindToClass", so we need
4041
- // to specialize those here.
4042
- if (boundMethodType &&
4043
- ((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
4044
- const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
4045
- if (bindToClass) {
4046
- const specializedBoundType = (0, typeUtils_1.partiallySpecializeType)(boundMethodType, bindToClass, classType);
4047
- if (specializedBoundType) {
4048
- if ((0, types_1.isFunction)(specializedBoundType) ||
4049
- (0, types_1.isOverloadedFunction)(specializedBoundType)) {
4050
- boundMethodType = specializedBoundType;
4051
- }
4052
- }
4053
- }
4054
- const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
4055
- /* skipUnknownArgCheck */ true);
4056
- if (callResult.overloadsUsedForCall &&
4057
- callResult.overloadsUsedForCall.length >= 1) {
4058
- const overloadUsed = callResult.overloadsUsedForCall[0];
4059
- if (overloadUsed.details.deprecatedMessage) {
4060
- memberAccessDeprecationInfo = {
4061
- deprecationMessage: overloadUsed.details.deprecatedMessage,
4062
- accessType: lookupClass && types_1.ClassType.isPropertyClass(lookupClass)
4063
- ? 'property'
4064
- : 'descriptor',
4065
- accessMethod: usage.method,
4066
- };
4067
- }
4068
- }
4069
- if (callResult.argumentErrors) {
4070
- if (usage.method === 'set') {
4071
- if (usage.setType &&
4072
- (0, types_1.isFunction)(boundMethodType) &&
4073
- boundMethodType.details.parameters.length >= 2 &&
4074
- !usage.setType.isIncomplete) {
4075
- const setterType = types_1.FunctionType.getEffectiveParameterType(boundMethodType, 1);
4076
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
4077
- destType: printType(setterType),
4078
- sourceType: printType(usage.setType.type),
4079
- }));
4080
- }
4081
- else if ((0, types_1.isOverloadedFunction)(boundMethodType)) {
4082
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
4083
- }
4084
- }
4085
- else {
4086
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessCallFailed().format({
4087
- name: accessMethodName,
4088
- className: printType((0, typeUtils_1.convertToInstance)(accessMethod.classType)),
4089
- }));
4090
- }
4091
- isTypeValid = false;
4092
- return types_1.AnyType.create();
4093
- }
4094
- // For set or delete, always return Any.
4095
- return usage.method === 'get'
4096
- ? (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create()
4097
- : types_1.AnyType.create();
4098
- }
4099
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessBindingFailed().format({
4100
- name: accessMethodName,
4101
- className: printType((0, typeUtils_1.convertToInstance)(accessMethod.classType)),
4102
- }));
4103
- isTypeValid = false;
4104
- return undefined;
4105
- });
4106
- // Determine if we're calling __set__ on an asymmetric descriptor or property.
4107
- if (usage.method === 'set' && (0, types_1.isClass)(accessMethod.classType)) {
4108
- if (isAsymmetricDescriptorClass(accessMethod.classType)) {
4109
- isAsymmetricAccessor = true;
4110
- }
4111
- }
4112
- if (returnType) {
4113
- return returnType;
4114
- }
4115
- }
4116
- }
4117
- }
4010
+ if (usage.method === 'set' && (0, types_1.isClass)(methodClassType)) {
4011
+ if (isAsymmetricDescriptorClass(methodClassType)) {
4012
+ isAsymmetricAccessor = true;
4118
4013
  }
4119
- else if ((0, types_1.isFunction)(concreteSubtype) || (0, types_1.isOverloadedFunction)(concreteSubtype)) {
4120
- // Check for an attempt to overwrite a final method.
4121
- if (usage.method === 'set') {
4122
- let isFinal = false;
4123
- if ((0, types_1.isFunction)(concreteSubtype)) {
4124
- isFinal = types_1.FunctionType.isFinal(concreteSubtype);
4125
- }
4126
- else {
4127
- const impl = types_1.OverloadedFunctionType.getImplementation(concreteSubtype);
4128
- if (impl) {
4129
- isFinal = types_1.FunctionType.isFinal(impl);
4130
- }
4131
- }
4132
- if (isFinal && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
4133
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4134
- name: memberName,
4135
- className: memberInfo.classType.details.name,
4136
- }));
4137
- isTypeValid = false;
4138
- return undefined;
4139
- }
4140
- }
4141
- // If this function is an instance member (e.g. a lambda that was
4142
- // assigned to an instance variable), don't perform any binding.
4143
- if (!isAccessedThroughObject || (memberInfo && !memberInfo.isInstanceMember)) {
4144
- return bindFunctionToClassOrObjectWithErrors(classType, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode, treatConstructorAsClassMember, selfType && (0, types_1.isClass)(selfType) ? types_1.ClassType.cloneIncludeSubclasses(selfType) : selfType);
4145
- }
4014
+ }
4015
+ if (!methodType) {
4016
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessBindingFailed().format({
4017
+ name: accessMethodName,
4018
+ className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
4019
+ }));
4020
+ return {
4021
+ type: types_1.UnknownType.create(),
4022
+ typeErrors: true,
4023
+ isDescriptorApplied: true,
4024
+ isAsymmetricAccessor,
4025
+ };
4026
+ }
4027
+ // Simulate a call to the access method.
4028
+ const argList = [];
4029
+ // Provide "obj" argument.
4030
+ argList.push({
4031
+ argumentCategory: 0 /* Simple */,
4032
+ typeResult: {
4033
+ type: types_1.ClassType.isClassProperty(concreteMemberType)
4034
+ ? classType
4035
+ : isAccessedThroughObject
4036
+ ? selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType)
4037
+ : getNoneType(),
4038
+ },
4039
+ });
4040
+ if (usage.method === 'get') {
4041
+ // Provide "owner" argument.
4042
+ argList.push({
4043
+ argumentCategory: 0 /* Simple */,
4044
+ typeResult: {
4045
+ type: isAccessedThroughObject ? types_1.ClassType.cloneAsInstantiable(classType) : classType,
4046
+ },
4047
+ });
4048
+ }
4049
+ else if (usage.method === 'set') {
4050
+ // Provide "value" argument.
4051
+ argList.push({
4052
+ argumentCategory: 0 /* Simple */,
4053
+ typeResult: {
4054
+ type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
4055
+ isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
4056
+ },
4057
+ });
4058
+ }
4059
+ // Suppress diagnostics for these method calls because they would be redundant.
4060
+ const callResult = suppressDiagnostics(errorNode, () => {
4061
+ return validateCallArguments(errorNode, argList, { type: methodType },
4062
+ /* typeVarContext */ undefined,
4063
+ /* skipUnknownArgCheck */ true);
4064
+ });
4065
+ // Collect deprecation information associated with the member access method.
4066
+ let deprecationInfo;
4067
+ if (callResult.overloadsUsedForCall && callResult.overloadsUsedForCall.length >= 1) {
4068
+ const overloadUsed = callResult.overloadsUsedForCall[0];
4069
+ if (overloadUsed.details.deprecatedMessage) {
4070
+ deprecationInfo = {
4071
+ deprecationMessage: overloadUsed.details.deprecatedMessage,
4072
+ accessType: types_1.ClassType.isPropertyClass(concreteMemberType) ? 'property' : 'descriptor',
4073
+ accessMethod: usage.method,
4074
+ };
4146
4075
  }
4147
- if (usage.method === 'set') {
4148
- if (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.isClassVar()) {
4149
- if (flags & 128 /* DisallowClassVarWrites */) {
4150
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
4151
- isTypeValid = false;
4152
- return undefined;
4153
- }
4154
- }
4155
- // Check for an attempt to overwrite a final member variable.
4156
- const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
4157
- if (finalVarTypeDecl && !ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
4158
- // If a Final instance variable is declared in the class body but is
4159
- // being assigned within an __init__ method, it's allowed.
4160
- const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
4161
- if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
4162
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
4163
- isTypeValid = false;
4164
- return undefined;
4165
- }
4166
- }
4167
- // Check for an attempt to overwrite an instance variable that is
4168
- // read-only (e.g. in a named tuple).
4169
- if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
4170
- (0, types_1.isClass)(memberInfo.classType) &&
4171
- types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
4172
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
4173
- isTypeValid = false;
4174
- return undefined;
4175
- }
4176
- let enforceTargetType = false;
4177
- if (memberInfo && memberInfo.symbol.hasTypedDeclarations()) {
4178
- // If the member has a declared type, we will enforce it.
4179
- enforceTargetType = true;
4180
- }
4181
- else {
4182
- // If the member has no declared type, we will enforce it
4183
- // if this assignment isn't within the enclosing class. If
4184
- // it is within the enclosing class, the assignment is used
4185
- // to infer the type of the member.
4186
- if (memberInfo && !memberInfo.symbol.getDeclarations().some((decl) => decl.node === errorNode)) {
4187
- enforceTargetType = true;
4188
- }
4189
- }
4190
- if (enforceTargetType) {
4191
- let effectiveType = subtype;
4192
- // If the code is patching a method (defined on the class)
4193
- // with an object-level function, strip the "self" parameter
4194
- // off the original type. This is sometimes done for test
4195
- // purposes to override standard behaviors of specific methods.
4196
- if (isAccessedThroughObject) {
4197
- if (!memberInfo.isInstanceMember && (0, types_1.isFunction)(concreteSubtype)) {
4198
- if (types_1.FunctionType.isClassMethod(concreteSubtype) ||
4199
- types_1.FunctionType.isInstanceMethod(concreteSubtype)) {
4200
- effectiveType = types_1.FunctionType.clone(concreteSubtype, /* stripFirstParam */ true);
4201
- }
4202
- }
4203
- }
4204
- return effectiveType;
4205
- }
4076
+ }
4077
+ if (!callResult.argumentErrors) {
4078
+ return {
4079
+ // For set or delete, always return Any.
4080
+ type: usage.method === 'get' ? (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create() : types_1.AnyType.create(),
4081
+ isDescriptorApplied: true,
4082
+ isAsymmetricAccessor,
4083
+ memberAccessDeprecationInfo: deprecationInfo,
4084
+ };
4085
+ }
4086
+ // Errors were detected when evaluating the access method call.
4087
+ if (usage.method === 'set') {
4088
+ if (usage.setType &&
4089
+ (0, types_1.isFunction)(methodType) &&
4090
+ methodType.details.parameters.length >= 2 &&
4091
+ !usage.setType.isIncomplete) {
4092
+ const setterType = types_1.FunctionType.getEffectiveParameterType(methodType, 1);
4093
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
4094
+ destType: printType(setterType),
4095
+ sourceType: printType(usage.setType.type),
4096
+ }));
4206
4097
  }
4207
- return subtype;
4208
- });
4209
- if (!isTypeValid) {
4210
- return undefined;
4098
+ else if ((0, types_1.isOverloadedFunction)(methodType)) {
4099
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
4100
+ }
4101
+ }
4102
+ else {
4103
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessCallFailed().format({
4104
+ name: accessMethodName,
4105
+ className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
4106
+ }));
4211
4107
  }
4212
- return { type, isAsymmetricAccessor, memberAccessDeprecationInfo };
4108
+ return {
4109
+ type: types_1.UnknownType.create(),
4110
+ typeErrors: true,
4111
+ isDescriptorApplied: true,
4112
+ isAsymmetricAccessor,
4113
+ memberAccessDeprecationInfo: deprecationInfo,
4114
+ };
4115
+ }
4116
+ function bindMethodForMemberAccess(type, concreteType, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount = 0) {
4117
+ // Check for an attempt to overwrite a final method.
4118
+ if (usage.method === 'set') {
4119
+ const impl = (0, types_1.isFunction)(concreteType)
4120
+ ? concreteType
4121
+ : types_1.OverloadedFunctionType.getImplementation(concreteType);
4122
+ if (impl && types_1.FunctionType.isFinal(impl) && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
4123
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4124
+ name: memberName,
4125
+ className: memberInfo.classType.details.name,
4126
+ }));
4127
+ return { type: types_1.UnknownType.create(), typeErrors: true };
4128
+ }
4129
+ }
4130
+ // If this function is an instance member (e.g. a lambda that was
4131
+ // assigned to an instance variable), don't perform any binding.
4132
+ if (types_1.TypeBase.isInstance(classType)) {
4133
+ if (!memberInfo || memberInfo.isInstanceMember) {
4134
+ return { type: type };
4135
+ }
4136
+ }
4137
+ const boundType = bindFunctionToClassOrObject(classType, concreteType, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, (flags & 256 /* TreatConstructorAsClassMethod */) !== 0, selfType && (0, types_1.isClass)(selfType) ? types_1.ClassType.cloneIncludeSubclasses(selfType) : selfType, diag, recursionCount);
4138
+ return { type: boundType !== null && boundType !== void 0 ? boundType : types_1.UnknownType.create(), typeErrors: !boundType };
4213
4139
  }
4214
4140
  function isAsymmetricDescriptorClass(classType) {
4215
4141
  var _a;
@@ -4276,11 +4202,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4276
4202
  return isAsymmetric;
4277
4203
  }
4278
4204
  // Applies the __getattr__, __setattr__ or __delattr__ method if present.
4279
- function applyAttributeAccessOverride(classType, errorNode, usage, memberName, selfType) {
4205
+ // If it's not applicable, returns undefined.
4206
+ function applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType) {
4280
4207
  var _a, _b, _c, _d, _e;
4281
4208
  const getAttributeAccessMember = (name) => {
4282
4209
  var _a;
4283
- return (_a = getTypeOfObjectMember(errorNode, classType, name, { method: 'get' },
4210
+ return (_a = getTypeOfBoundMember(errorNode, classType, name,
4211
+ /* usage */ undefined,
4284
4212
  /* diag */ undefined, 16 /* SkipInstanceMembers */ |
4285
4213
  4 /* SkipObjectBaseClass */ |
4286
4214
  512 /* SkipAttributeAccessOverride */, selfType)) === null || _a === void 0 ? void 0 : _a.type;
@@ -4299,20 +4227,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4299
4227
  if (!accessMemberType) {
4300
4228
  return undefined;
4301
4229
  }
4302
- let nameLiteralType = types_1.AnyType.create();
4303
- if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
4304
- nameLiteralType = types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName);
4305
- }
4306
- const argList = [
4307
- {
4308
- // Provide "name" argument.
4309
- argumentCategory: 0 /* Simple */,
4310
- typeResult: { type: nameLiteralType },
4230
+ const argList = [];
4231
+ // Provide "name" argument.
4232
+ argList.push({
4233
+ argumentCategory: 0 /* Simple */,
4234
+ typeResult: {
4235
+ type: strClassType && (0, types_1.isInstantiableClass)(strClassType)
4236
+ ? types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName)
4237
+ : types_1.AnyType.create(),
4311
4238
  },
4312
- ];
4239
+ });
4313
4240
  if (usage.method === 'set') {
4241
+ // Provide "value" argument.
4314
4242
  argList.push({
4315
- // Provide "value" argument.
4316
4243
  argumentCategory: 0 /* Simple */,
4317
4244
  typeResult: {
4318
4245
  type: (_c = (_b = usage.setType) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create(),
@@ -4321,20 +4248,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4321
4248
  });
4322
4249
  }
4323
4250
  if (!(0, types_1.isFunction)(accessMemberType) && !(0, types_1.isOverloadedFunction)(accessMemberType)) {
4324
- // TODO - need to handle and report this error.
4251
+ if ((0, types_1.isAnyOrUnknown)(accessMemberType)) {
4252
+ return { type: accessMemberType };
4253
+ }
4254
+ // TODO - emit an error for this condition.
4325
4255
  return undefined;
4326
4256
  }
4327
4257
  const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(accessMemberType));
4328
4258
  const callResult = validateCallArguments(errorNode, argList, { type: accessMemberType }, typeVarContext,
4329
4259
  /* skipUnknownArgCheck */ true);
4330
- // TODO - need to handle and report errors when validating call to
4331
- // attribute access method.
4332
4260
  let isAsymmetricAccessor = false;
4333
4261
  if (usage.method === 'set') {
4334
4262
  isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType);
4335
4263
  }
4336
4264
  return {
4337
4265
  type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
4266
+ typeErrors: callResult.argumentErrors,
4338
4267
  isAsymmetricAccessor,
4339
4268
  };
4340
4269
  }
@@ -4545,10 +4474,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4545
4474
  typeParameters.forEach((param, index) => {
4546
4475
  if (param.details.isParamSpec && index < typeArgs.length) {
4547
4476
  const typeArgType = typeArgs[index].type;
4548
- if (typeArgs[index].typeList) {
4477
+ const typeList = typeArgs[index].typeList;
4478
+ if (typeList) {
4549
4479
  const functionType = types_1.FunctionType.createSynthesizedInstance('', 65536 /* ParamSpecValue */);
4550
4480
  types_1.TypeBase.setSpecialForm(functionType);
4551
- typeArgs[index].typeList.forEach((paramType, paramIndex) => {
4481
+ typeList.forEach((paramType, paramIndex) => {
4552
4482
  types_1.FunctionType.addParameter(functionType, {
4553
4483
  category: 0 /* Simple */,
4554
4484
  name: `__p${paramIndex}`,
@@ -4663,7 +4593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4663
4593
  }
4664
4594
  if ((0, types_1.isTypeVar)(baseTypeResult.type) && (0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4665
4595
  const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
4666
- const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeAliasIsPep695Syntax, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4596
+ const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, !!baseTypeResult.type.details.recursiveTypeAliasIsPep695Syntax, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4667
4597
  return { type };
4668
4598
  }
4669
4599
  let isIncomplete = baseTypeResult.isIncomplete;
@@ -4692,9 +4622,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4692
4622
  (0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass) &&
4693
4623
  !types_1.ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) &&
4694
4624
  (flags & 128 /* ExpectingInstantiableType */) === 0) {
4695
- const itemMethodType = getTypeOfObjectMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
4696
- /* usage */ undefined,
4697
- /* diag */ undefined, 512 /* SkipAttributeAccessOverride */);
4625
+ const itemMethodType = getBoundMagicMethod(concreteSubtype, getIndexAccessMagicMethodName(usage));
4698
4626
  if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
4699
4627
  // If the class doesn't derive from Generic, a type argument should not be allowed.
4700
4628
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
@@ -4920,7 +4848,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4920
4848
  }
4921
4849
  }
4922
4850
  function getTypeOfIndexedObjectOrClass(node, baseType, usage) {
4923
- var _a, _b, _c, _d, _e;
4851
+ var _a, _b, _c, _d;
4924
4852
  // Handle index operations for TypedDict classes specially.
4925
4853
  if ((0, types_1.isClassInstance)(baseType) && types_1.ClassType.isTypedDictClass(baseType)) {
4926
4854
  const typeFromTypedDict = (0, typedDicts_1.getTypeOfIndexedTypedDict)(evaluatorInterface, node, baseType, usage);
@@ -4929,9 +4857,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4929
4857
  }
4930
4858
  }
4931
4859
  const magicMethodName = getIndexAccessMagicMethodName(usage);
4932
- const itemMethodType = (_a = getTypeOfObjectMember(node, baseType, magicMethodName,
4933
- /* usage */ undefined,
4934
- /* diag */ undefined, 512 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
4860
+ const itemMethodType = getBoundMagicMethod(baseType, magicMethodName);
4935
4861
  if (!itemMethodType) {
4936
4862
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4937
4863
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.methodNotDefinedOnType().format({
@@ -5060,7 +4986,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5060
4986
  },
5061
4987
  ];
5062
4988
  if (usage.method === 'set') {
5063
- let setType = (_c = (_b = usage.setType) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : types_1.AnyType.create();
4989
+ let setType = (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.AnyType.create();
5064
4990
  // Expand constrained type variables.
5065
4991
  if ((0, types_1.isTypeVar)(setType) && setType.details.constraints.length > 0) {
5066
4992
  const conditionFilter = (0, types_1.isClassInstance)(baseType) ? baseType.condition : undefined;
@@ -5071,7 +4997,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5071
4997
  argumentCategory: 0 /* Simple */,
5072
4998
  typeResult: {
5073
4999
  type: setType,
5074
- isIncomplete: !!((_d = usage.setType) === null || _d === void 0 ? void 0 : _d.isIncomplete),
5000
+ isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
5075
5001
  },
5076
5002
  });
5077
5003
  }
@@ -5103,7 +5029,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5103
5029
  if ((0, types_1.isClassInstance)(positionalIndexType)) {
5104
5030
  const altArgList = [...argList];
5105
5031
  altArgList[0] = { ...altArgList[0] };
5106
- const indexMethod = getTypeOfObjectMember(node, positionalIndexType, '__index__');
5032
+ const indexMethod = getBoundMagicMethod(positionalIndexType, '__index__');
5107
5033
  if (indexMethod) {
5108
5034
  const intType = getBuiltInObject(node, 'int');
5109
5035
  if ((0, types_1.isClassInstance)(intType)) {
@@ -5121,7 +5047,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5121
5047
  }
5122
5048
  callResult = validateCallArguments(node, argList, { type: itemMethodType });
5123
5049
  return {
5124
- type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
5050
+ type: (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create(),
5125
5051
  isIncomplete: !!callResult.isTypeIncomplete,
5126
5052
  };
5127
5053
  }
@@ -5807,7 +5733,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5807
5733
  }
5808
5734
  }
5809
5735
  if (bindToType && implicitBindToType) {
5810
- bindToType = (0, typeUtils_1.addConditionToType)(bindToType, (0, typeUtils_1.getTypeCondition)(implicitBindToType));
5736
+ const typeCondition = (0, typeUtils_1.getTypeCondition)(implicitBindToType);
5737
+ if (typeCondition) {
5738
+ bindToType = (0, typeUtils_1.addConditionToType)(bindToType, typeCondition);
5739
+ }
5740
+ else if ((0, types_1.isClass)(implicitBindToType)) {
5741
+ bindToType = implicitBindToType;
5742
+ }
5811
5743
  }
5812
5744
  }
5813
5745
  // Determine whether super() should return an instance of the class or
@@ -5830,9 +5762,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5830
5762
  // Python docs indicate that super() isn't valid for
5831
5763
  // operations other than member accesses or attribute lookups.
5832
5764
  const parentNode = node.parent;
5833
- if (parentNode.nodeType === 35 /* MemberAccess */) {
5765
+ if ((parentNode === null || parentNode === void 0 ? void 0 : parentNode.nodeType) === 35 /* MemberAccess */) {
5834
5766
  const memberName = parentNode.memberName.value;
5835
- const effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5767
+ let effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5768
+ // If the bind-to type is a protocol, don't use the effective target class.
5769
+ // This pattern is used for mixins, where the mixin type is a protocol class
5770
+ // that is used to decorate the "self" or "cls" parameter.
5771
+ if (bindToType &&
5772
+ types_1.ClassType.isProtocolClass(bindToType) &&
5773
+ effectiveTargetClass &&
5774
+ !types_1.ClassType.isSameGenericClass(bindToType, effectiveTargetClass)) {
5775
+ effectiveTargetClass = undefined;
5776
+ }
5836
5777
  const lookupResults = bindToType
5837
5778
  ? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
5838
5779
  : undefined;
@@ -6563,7 +6504,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6563
6504
  const result = {
6564
6505
  returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
6565
6506
  };
6566
- const initTypeResult = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(expandedCallType), '__init__');
6507
+ const initTypeResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, errorNode, types_1.ClassType.cloneAsInstance(expandedCallType),
6508
+ /* skipObjectBase */ false);
6567
6509
  if (initTypeResult && (0, types_1.isOverloadedFunction)(initTypeResult.type)) {
6568
6510
  validateOverloadedFunctionArguments(errorNode, argList, { type: initTypeResult.type },
6569
6511
  /* typeVarContext */ undefined, skipUnknownArgCheck,
@@ -6664,18 +6606,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6664
6606
  return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
6665
6607
  }
6666
6608
  function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
6667
- var _a, _b;
6668
- const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6609
+ var _a;
6610
+ const callMethodResult = getTypeOfBoundMember(errorNode, expandedCallType, '__call__',
6669
6611
  /* usage */ undefined,
6670
- /* diag */ undefined, 512 /* SkipAttributeAccessOverride */ | 16 /* SkipInstanceMembers */)) === null || _a === void 0 ? void 0 : _a.type;
6671
- if (!memberType) {
6612
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */,
6613
+ /* selfType */ undefined, recursionCount);
6614
+ const callMethodType = callMethodResult === null || callMethodResult === void 0 ? void 0 : callMethodResult.type;
6615
+ if (!callMethodType) {
6672
6616
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6673
6617
  type: printType(expandedCallType),
6674
6618
  }), errorNode);
6675
6619
  return { returnType: types_1.UnknownType.create(), argumentErrors: true };
6676
6620
  }
6677
- const callResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6678
- let returnType = (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
6621
+ const callResult = validateCallArguments(errorNode, argList, { type: callMethodType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6622
+ let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
6679
6623
  if ((0, types_1.isTypeVar)(unexpandedCallType) &&
6680
6624
  types_1.TypeBase.isInstantiable(unexpandedCallType) &&
6681
6625
  (0, types_1.isClass)(expandedCallType) &&
@@ -6755,7 +6699,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6755
6699
  // validation is left to the caller.
6756
6700
  // This logic is based on PEP 3102: https://www.python.org/dev/peps/pep-3102/
6757
6701
  function matchFunctionArgumentsToParameters(errorNode, argList, typeResult, overloadIndex) {
6758
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
6702
+ var _a, _b, _c, _d, _e, _f, _g, _h;
6759
6703
  const paramDetails = (0, parameterUtils_1.getParameterListDetails)(typeResult.type);
6760
6704
  let argIndex = 0;
6761
6705
  let matchedUnpackedListOfUnknownLength = false;
@@ -6867,9 +6811,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6867
6811
  let paramIndex = 0;
6868
6812
  while (argIndex < positionalArgCount) {
6869
6813
  if (argIndex < positionalOnlyLimitIndex && argList[argIndex].name) {
6870
- const fileInfo = AnalyzerNodeInfo.getFileInfo(argList[argIndex].name);
6871
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.argPositional(), argList[argIndex].name);
6872
- reportedArgError = true;
6814
+ const nameNode = argList[argIndex].name;
6815
+ if (nameNode) {
6816
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(nameNode);
6817
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.argPositional(), nameNode);
6818
+ reportedArgError = true;
6819
+ }
6873
6820
  }
6874
6821
  const remainingArgCount = positionalArgCount - argIndex;
6875
6822
  const remainingParamCount = positionParamLimitIndex - paramIndex - 1;
@@ -6980,9 +6927,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6980
6927
  listElementType = undefined;
6981
6928
  }
6982
6929
  else {
6983
- listElementType =
6984
- (_e = (_d = getTypeOfIterator({ type: argType, isIncomplete: argTypeResult.isIncomplete },
6985
- /* isAsync */ false, argList[argIndex].valueExpression)) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : types_1.UnknownType.create();
6930
+ const valueExpr = argList[argIndex].valueExpression;
6931
+ const iteratorType = valueExpr
6932
+ ? (_d = getTypeOfIterator({ type: argType, isIncomplete: argTypeResult.isIncomplete },
6933
+ /* isAsync */ false, valueExpr)) === null || _d === void 0 ? void 0 : _d.type
6934
+ : undefined;
6935
+ listElementType = iteratorType !== null && iteratorType !== void 0 ? iteratorType : types_1.UnknownType.create();
6986
6936
  if (paramDetails.params[paramIndex].param.category !== 1 /* ArgsList */) {
6987
6937
  matchedUnpackedListOfUnknownLength = true;
6988
6938
  }
@@ -7014,7 +6964,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7014
6964
  paramType,
7015
6965
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7016
6966
  argument: funcArg,
7017
- errorNode: (_f = argList[argIndex].valueExpression) !== null && _f !== void 0 ? _f : errorNode,
6967
+ errorNode: (_e = argList[argIndex].valueExpression) !== null && _e !== void 0 ? _e : errorNode,
7018
6968
  paramName,
7019
6969
  isParamNameSynthesized: paramDetails.params[paramIndex].param.isNameSynthesized,
7020
6970
  mapsToVarArgList: isParamVariadic && remainingArgCount > remainingParamCount,
@@ -7317,7 +7267,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7317
7267
  paramType,
7318
7268
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7319
7269
  argument: argList[argIndex],
7320
- errorNode: (_g = argList[argIndex].valueExpression) !== null && _g !== void 0 ? _g : errorNode,
7270
+ errorNode: (_f = argList[argIndex].valueExpression) !== null && _f !== void 0 ? _f : errorNode,
7321
7271
  paramName: paramNameValue,
7322
7272
  });
7323
7273
  trySetActive(argList[argIndex], paramDetails.params[paramInfoIndex].param);
@@ -7333,7 +7283,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7333
7283
  paramType,
7334
7284
  requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7335
7285
  argument: argList[argIndex],
7336
- errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
7286
+ errorNode: (_g = argList[argIndex].valueExpression) !== null && _g !== void 0 ? _g : errorNode,
7337
7287
  paramName: paramNameValue,
7338
7288
  });
7339
7289
  // Remember that this parameter has already received a value.
@@ -7382,7 +7332,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7382
7332
  requiresTypeVarMatching: false,
7383
7333
  argument: argList[argIndex],
7384
7334
  argType: (0, types_1.isParamSpec)(argType) ? undefined : types_1.AnyType.create(),
7385
- errorNode: (_j = argList[argIndex].valueExpression) !== null && _j !== void 0 ? _j : errorNode,
7335
+ errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
7386
7336
  });
7387
7337
  }
7388
7338
  }
@@ -8901,13 +8851,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8901
8851
  let magicMethodSupported = true;
8902
8852
  // Create a helper lambda for object subtypes.
8903
8853
  const handleSubtype = (subtype) => {
8904
- var _a;
8905
8854
  let magicMethodType;
8906
8855
  const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
8907
8856
  if ((0, types_1.isClass)(concreteSubtype)) {
8908
- magicMethodType = (_a = getTypeOfObjectMember(errorNode, concreteSubtype, methodName,
8909
- /* usage */ undefined,
8910
- /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
8857
+ magicMethodType = getBoundMagicMethod(concreteSubtype, methodName, subtype);
8911
8858
  }
8912
8859
  if (magicMethodType) {
8913
8860
  const functionArgs = argList.map((arg) => {
@@ -8917,16 +8864,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8917
8864
  };
8918
8865
  });
8919
8866
  let callResult;
8920
- useSpeculativeMode(errorNode, () => {
8921
- callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8867
+ callResult = useSpeculativeMode(errorNode, () => {
8868
+ (0, debug_1.assert)(magicMethodType !== undefined);
8869
+ return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8922
8870
  /* typeVarContext */ undefined,
8923
8871
  /* skipUnknownArgCheck */ true, inferenceContext);
8924
8872
  });
8925
8873
  // If there were errors with the expected type, try
8926
8874
  // to evaluate without the expected type.
8927
8875
  if (callResult.argumentErrors && inferenceContext) {
8928
- useSpeculativeMode(errorNode, () => {
8929
- callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8876
+ callResult = useSpeculativeMode(errorNode, () => {
8877
+ (0, debug_1.assert)(magicMethodType !== undefined);
8878
+ return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8930
8879
  /* typeVarContext */ undefined,
8931
8880
  /* skipUnknownArgCheck */ true);
8932
8881
  });
@@ -9569,7 +9518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9569
9518
  expectedFunctionTypes.push(subtype);
9570
9519
  }
9571
9520
  if ((0, types_1.isClassInstance)(subtype)) {
9572
- const boundMethod = getBoundMethod(subtype, '__call__');
9521
+ const boundMethod = getBoundMagicMethod(subtype, '__call__');
9573
9522
  if (boundMethod && (0, types_1.isFunction)(boundMethod)) {
9574
9523
  expectedFunctionTypes.push(boundMethod);
9575
9524
  }
@@ -10452,6 +10401,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10452
10401
  let reportedUnpackedError = false;
10453
10402
  // Verify that we didn't receive any inappropriate types.
10454
10403
  typeArgs.forEach((typeArg, index) => {
10404
+ (0, debug_1.assert)(typeArgs !== undefined);
10455
10405
  if ((0, typeUtils_1.isEllipsisType)(typeArg.type)) {
10456
10406
  if (!isTupleTypeParam) {
10457
10407
  if (!allowParamSpec) {
@@ -10638,6 +10588,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10638
10588
  // with this type alias.
10639
10589
  typeParameters = [];
10640
10590
  (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10591
+ (0, debug_1.assert)(typeParameters !== undefined);
10641
10592
  (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10642
10593
  });
10643
10594
  // Don't include any synthesized type variables.
@@ -10654,6 +10605,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10654
10605
  // Validate the default types for all type parameters.
10655
10606
  typeParameters.forEach((typeParam, index) => {
10656
10607
  var _a;
10608
+ (0, debug_1.assert)(typeParameters !== undefined);
10657
10609
  let bestErrorNode = errorNode;
10658
10610
  if (typeParamNodes && index < typeParamNodes.length) {
10659
10611
  bestErrorNode = (_a = typeParamNodes[index].defaultExpression) !== null && _a !== void 0 ? _a : typeParamNodes[index].name;
@@ -10934,6 +10886,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10934
10886
  // If this is a type alias, record its name based on the assignment target.
10935
10887
  rightHandType = transformTypeForTypeAlias(rightHandType, typeAliasNameNode, node.rightExpression,
10936
10888
  /* isPep695Syntax */ false);
10889
+ (0, debug_1.assert)(typeAliasTypeVar !== undefined);
10937
10890
  if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, rightHandType)) {
10938
10891
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10939
10892
  name: typeAliasNameNode.value,
@@ -11650,6 +11603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11650
11603
  if (p.details.isVariadic) {
11651
11604
  return p;
11652
11605
  }
11606
+ (0, debug_1.assert)(objectType !== undefined);
11653
11607
  return i === paramIndex ? objectType : dummyTypeObject;
11654
11608
  });
11655
11609
  // Replace all type arguments with a dummy type except for the
@@ -11818,6 +11772,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11818
11772
  computeEffectiveMetaclass(type, errorNode);
11819
11773
  }
11820
11774
  function validateInitSubclassArgs(node, classType) {
11775
+ var _a, _b;
11821
11776
  // Collect arguments that will be passed to the `__init_subclass__`
11822
11777
  // method described in PEP 487 and validate it.
11823
11778
  const argList = [];
@@ -11831,72 +11786,91 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11831
11786
  });
11832
11787
  }
11833
11788
  });
11834
- const errorNode = argList.length > 0 ? argList[0].node.name : node.name;
11835
- const initSubclassMethodInfo = getTypeOfObjectMember(errorNode, classType, '__init_subclass__', { method: 'get' },
11836
- /* diag */ undefined, 32 /* SkipClassMembers */ |
11837
- 4 /* SkipObjectBaseClass */ |
11838
- 1 /* SkipOriginalClass */ |
11839
- 512 /* SkipAttributeAccessOverride */);
11840
- if (initSubclassMethodInfo) {
11841
- const initSubclassMethodType = initSubclassMethodInfo.type;
11842
- if (initSubclassMethodType) {
11843
- validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
11844
- /* typeVarContext */ undefined,
11845
- /* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(getNoneType()));
11846
- }
11847
- }
11848
- else if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
11789
+ const errorNode = argList.length > 0 ? (_b = (_a = argList[0].node) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : node.name : node.name;
11790
+ let newMethodMember;
11791
+ if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
11849
11792
  // See if the metaclass has a `__new__` method that accepts keyword parameters.
11850
- const newMethodMember = (0, typeUtils_1.lookUpClassMember)(classType.details.effectiveMetaclass, '__new__', 8 /* SkipTypeBaseClass */);
11851
- if (newMethodMember) {
11852
- const newMethodType = getTypeOfMember(newMethodMember);
11853
- if ((0, types_1.isFunction)(newMethodType)) {
11854
- const paramListDetails = (0, parameterUtils_1.getParameterListDetails)(newMethodType);
11855
- if (paramListDetails.firstKeywordOnlyIndex !== undefined) {
11856
- // Build a map of the keyword-only parameters.
11857
- const paramMap = new Map();
11858
- for (let i = paramListDetails.firstKeywordOnlyIndex; i < paramListDetails.params.length; i++) {
11859
- const paramInfo = paramListDetails.params[i];
11860
- if (paramInfo.param.category === 0 /* Simple */ && paramInfo.param.name) {
11861
- paramMap.set(paramInfo.param.name, i);
11862
- }
11793
+ newMethodMember = (0, typeUtils_1.lookUpClassMember)(classType.details.effectiveMetaclass, '__new__', 8 /* SkipTypeBaseClass */);
11794
+ }
11795
+ if (newMethodMember) {
11796
+ const newMethodType = getTypeOfMember(newMethodMember);
11797
+ if ((0, types_1.isFunction)(newMethodType)) {
11798
+ const paramListDetails = (0, parameterUtils_1.getParameterListDetails)(newMethodType);
11799
+ if (paramListDetails.firstKeywordOnlyIndex !== undefined) {
11800
+ // Build a map of the keyword-only parameters.
11801
+ const paramMap = new Map();
11802
+ for (let i = paramListDetails.firstKeywordOnlyIndex; i < paramListDetails.params.length; i++) {
11803
+ const paramInfo = paramListDetails.params[i];
11804
+ if (paramInfo.param.category === 0 /* Simple */ && paramInfo.param.name) {
11805
+ paramMap.set(paramInfo.param.name, i);
11863
11806
  }
11864
- argList.forEach((arg) => {
11865
- var _a, _b, _c;
11866
- const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
11867
- if (arg.argumentCategory === 0 /* Simple */ && arg.name) {
11868
- const paramIndex = (_a = paramMap.get(arg.name.value)) !== null && _a !== void 0 ? _a : paramListDetails.kwargsIndex;
11869
- if (paramIndex !== undefined) {
11870
- const paramInfo = paramListDetails.params[paramIndex];
11871
- const argParam = {
11872
- paramCategory: paramInfo.param.category,
11873
- paramType: types_1.FunctionType.getEffectiveParameterType(newMethodType, paramInfo.index),
11874
- requiresTypeVarMatching: false,
11875
- argument: arg,
11876
- errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
11877
- };
11878
- validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
11879
- paramMap.delete(arg.name.value);
11880
- }
11881
- else {
11882
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), (_c = arg.name) !== null && _c !== void 0 ? _c : errorNode);
11883
- }
11807
+ }
11808
+ argList.forEach((arg) => {
11809
+ var _a, _b, _c;
11810
+ const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
11811
+ if (arg.argumentCategory === 0 /* Simple */ && arg.name) {
11812
+ const paramIndex = (_a = paramMap.get(arg.name.value)) !== null && _a !== void 0 ? _a : paramListDetails.kwargsIndex;
11813
+ if (paramIndex !== undefined) {
11814
+ const paramInfo = paramListDetails.params[paramIndex];
11815
+ const argParam = {
11816
+ paramCategory: paramInfo.param.category,
11817
+ paramType: types_1.FunctionType.getEffectiveParameterType(newMethodType, paramInfo.index),
11818
+ requiresTypeVarMatching: false,
11819
+ argument: arg,
11820
+ errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
11821
+ };
11822
+ validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
11823
+ paramMap.delete(arg.name.value);
11884
11824
  }
11885
- });
11886
- // See if we have any remaining unmatched parameters without
11887
- // default values.
11888
- const unassignedParams = [];
11889
- paramMap.forEach((index, paramName) => {
11890
- const paramInfo = paramListDetails.params[index];
11891
- if (!paramInfo.param.hasDefault) {
11892
- unassignedParams.push(paramName);
11825
+ else {
11826
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), (_c = arg.name) !== null && _c !== void 0 ? _c : errorNode);
11893
11827
  }
11894
- });
11895
- if (unassignedParams.length > 0) {
11896
- const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
11897
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
11898
- ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
11899
- : localize_1.Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), errorNode);
11828
+ }
11829
+ });
11830
+ // See if we have any remaining unmatched parameters without
11831
+ // default values.
11832
+ const unassignedParams = [];
11833
+ paramMap.forEach((index, paramName) => {
11834
+ const paramInfo = paramListDetails.params[index];
11835
+ if (!paramInfo.param.hasDefault) {
11836
+ unassignedParams.push(paramName);
11837
+ }
11838
+ });
11839
+ if (unassignedParams.length > 0) {
11840
+ const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
11841
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
11842
+ ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
11843
+ : localize_1.Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), errorNode);
11844
+ }
11845
+ }
11846
+ }
11847
+ }
11848
+ else {
11849
+ // If there was no custom metaclass __new__ method, see if there is an __init_subclass__
11850
+ // method present somewhere in the class hierarchy.
11851
+ const initSubclassMethodInfo = getTypeOfBoundMember(errorNode, classType, '__init_subclass__',
11852
+ /* usage */ undefined,
11853
+ /* diag */ undefined, 32 /* SkipClassMembers */ |
11854
+ 1 /* SkipOriginalClass */ |
11855
+ 512 /* SkipAttributeAccessOverride */);
11856
+ if (initSubclassMethodInfo) {
11857
+ const initSubclassMethodType = initSubclassMethodInfo.type;
11858
+ if (initSubclassMethodType && initSubclassMethodInfo.classType) {
11859
+ const callResult = validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
11860
+ /* typeVarContext */ undefined,
11861
+ /* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(getNoneType()));
11862
+ if (callResult.argumentErrors) {
11863
+ const diag = addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.initSubclassCallFailed(), node.name);
11864
+ const initSubclassFunction = (0, types_1.isOverloadedFunction)(initSubclassMethodType)
11865
+ ? types_1.OverloadedFunctionType.getOverloads(initSubclassMethodType)[0]
11866
+ : initSubclassMethodType;
11867
+ const initSubclassDecl = (0, types_1.isFunction)(initSubclassFunction)
11868
+ ? initSubclassFunction.details.declaration
11869
+ : undefined;
11870
+ if (diag && initSubclassDecl) {
11871
+ diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.initSubclassLocation().format({
11872
+ name: printType((0, typeUtils_1.convertToInstance)(initSubclassMethodInfo.classType)),
11873
+ }), initSubclassDecl.path, initSubclassDecl.range);
11900
11874
  }
11901
11875
  }
11902
11876
  }
@@ -12060,7 +12034,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12060
12034
  // accumulate the list of type parameters upfront.
12061
12035
  const typeParametersSeen = [];
12062
12036
  if (node.typeParameters) {
12063
- functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
12037
+ functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters).map((typeParam) => (0, typeUtils_1.convertToInstance)(typeParam));
12064
12038
  }
12065
12039
  else {
12066
12040
  functionType.details.typeParameters = typeParametersSeen;
@@ -13945,6 +13919,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13945
13919
  else {
13946
13920
  // Avoid emitting this error for a partially-constructed class.
13947
13921
  if (!(0, types_1.isClassInstance)(typeArgType) || !types_1.ClassType.isPartiallyEvaluated(typeArgType)) {
13922
+ (0, debug_1.assert)(typeArgs !== undefined);
13948
13923
  const fileInfo = AnalyzerNodeInfo.getFileInfo(typeArgs[index].node);
13949
13924
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarAssignmentMismatch().format({
13950
13925
  type: printType(typeArgType),
@@ -13986,6 +13961,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13986
13961
  }
13987
13962
  // If there was no defined type provided, there should always
13988
13963
  // be a value expression from which we can retrieve the type.
13964
+ (0, debug_1.assert)(arg.valueExpression !== undefined);
13989
13965
  return getTypeOfExpressionExpectingType(arg.valueExpression, options);
13990
13966
  }
13991
13967
  function getTypeOfExpressionExpectingType(node, options) {
@@ -14371,8 +14347,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14371
14347
  });
14372
14348
  }
14373
14349
  else if ((0, types_1.isInstantiableClass)(baseType)) {
14374
- const initMethodType = (_b = getTypeOfObjectMember(argNode.parent.leftExpression, types_1.ClassType.cloneAsInstance(baseType), '__init__', { method: 'get' },
14375
- /* diag */ undefined, 4 /* SkipObjectBaseClass */)) === null || _b === void 0 ? void 0 : _b.type;
14350
+ const initMethodType = (_b = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, argNode.parent.leftExpression, types_1.ClassType.cloneAsInstance(baseType))) === null || _b === void 0 ? void 0 : _b.type;
14376
14351
  if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
14377
14352
  const paramDecl = getDeclarationFromFunctionNamedParameter(initMethodType, paramName);
14378
14353
  if (paramDecl) {
@@ -14754,6 +14729,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14754
14729
  // If the resolved declaration had no defined type, use the
14755
14730
  // inferred type for this node.
14756
14731
  if (resolvedDecl.type === 2 /* Parameter */) {
14732
+ (0, debug_1.assert)(resolvedDecl.node.name !== undefined);
14757
14733
  return (_b = evaluateTypeForSubnode(resolvedDecl.node.name, () => {
14758
14734
  evaluateTypeOfParameter(resolvedDecl.node);
14759
14735
  })) === null || _b === void 0 ? void 0 : _b.type;
@@ -14772,8 +14748,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14772
14748
  // See if this is an enum member. If so, we need to handle it as a special case.
14773
14749
  const enumMemberType = (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, resolvedDecl.node, () => {
14774
14750
  var _a, _b;
14775
- return ((_b = (_a = evaluateTypeForSubnode(resolvedDecl.inferredTypeSource, () => {
14776
- evaluateTypesForStatement(resolvedDecl.inferredTypeSource);
14751
+ (0, debug_1.assert)(resolvedDecl.inferredTypeSource !== undefined);
14752
+ const inferredTypeSource = resolvedDecl.inferredTypeSource;
14753
+ return ((_b = (_a = evaluateTypeForSubnode(inferredTypeSource, () => {
14754
+ evaluateTypesForStatement(inferredTypeSource);
14777
14755
  })) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create());
14778
14756
  });
14779
14757
  if (enumMemberType) {
@@ -15544,8 +15522,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15544
15522
  // derive from the source. We also need to use this path if we're
15545
15523
  // testing to see if the metaclass matches the protocol.
15546
15524
  if (types_1.ClassType.isProtocolClass(destType) && !isDerivedFrom) {
15547
- if (!(0, protocols_1.assignClassToProtocol)(evaluatorInterface, destType, srcType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags,
15548
- /* treatSourceAsInstantiable */ false, recursionCount)) {
15525
+ if (!(0, protocols_1.assignClassToProtocol)(evaluatorInterface, destType, types_1.ClassType.cloneAsInstance(srcType), diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
15549
15526
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.protocolIncompatible().format({
15550
15527
  sourceType: printType((0, typeUtils_1.convertToInstance)(srcType)),
15551
15528
  destType: printType((0, typeUtils_1.convertToInstance)(destType)),
@@ -15797,9 +15774,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15797
15774
  for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) {
15798
15775
  const ancestorType = inheritanceChain[ancestorIndex];
15799
15776
  // If we've hit an "unknown", all bets are off, and we need to assume
15800
- // that the type is assignable.
15777
+ // that the type is assignable. If the destType is marked "@final",
15778
+ // we should be able to assume that it's not assignable, but we can't do
15779
+ // this in the general case because it breaks assumptions with the
15780
+ // NotImplemented symbol exported by typeshed's builtins.pyi. Instead,
15781
+ // we'll special-case only None.
15801
15782
  if ((0, types_1.isUnknown)(ancestorType)) {
15802
- return true;
15783
+ return !(0, typeUtils_1.isNoneTypeClass)(destType);
15803
15784
  }
15804
15785
  // If this isn't the first time through the loop, specialize
15805
15786
  // for the next ancestor in the chain.
@@ -15852,24 +15833,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15852
15833
  const srcTypeArgs = curSrcType.typeArguments;
15853
15834
  for (let i = 0; i < destType.details.typeParameters.length; i++) {
15854
15835
  const typeArgType = i < srcTypeArgs.length ? srcTypeArgs[i] : types_1.UnknownType.create();
15855
- destTypeVarContext.setTypeVarType(destType.details.typeParameters[i],
15856
- /* narrowBound */ undefined,
15857
- /* narrowBoundNoLiterals */ undefined, typeArgType);
15836
+ const typeParam = destType.details.typeParameters[i];
15837
+ const variance = types_1.TypeVarType.getVariance(typeParam);
15838
+ (0, constraintSolver_1.updateTypeVarType)(evaluatorInterface, destTypeVarContext, typeParam, variance !== 4 /* Contravariant */ ? typeArgType : undefined, variance !== 3 /* Covariant */ ? typeArgType : undefined,
15839
+ /* forceRetainLiterals */ true);
15858
15840
  }
15859
15841
  }
15860
15842
  return true;
15861
15843
  }
15862
15844
  function getGetterTypeFromProperty(propertyClass, inferTypeIfNeeded) {
15863
- var _a;
15864
15845
  if (!types_1.ClassType.isPropertyClass(propertyClass)) {
15865
15846
  return undefined;
15866
15847
  }
15867
- const fgetSymbol = propertyClass.details.fields.get('fget');
15868
- if (fgetSymbol) {
15869
- const fgetType = (_a = getDeclaredTypeOfSymbol(fgetSymbol)) === null || _a === void 0 ? void 0 : _a.type;
15870
- if (fgetType && (0, types_1.isFunction)(fgetType)) {
15871
- return getFunctionEffectiveReturnType(fgetType, /* args */ undefined, inferTypeIfNeeded);
15872
- }
15848
+ if (propertyClass.fgetFunction) {
15849
+ return getFunctionEffectiveReturnType(propertyClass.fgetFunction, /* args */ undefined, inferTypeIfNeeded);
15873
15850
  }
15874
15851
  return undefined;
15875
15852
  }
@@ -16390,8 +16367,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16390
16367
  // If the destType is an instantiation of a Protocol,
16391
16368
  // see if the class type itself satisfies the protocol.
16392
16369
  if (types_1.ClassType.isProtocolClass(destType)) {
16393
- return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags,
16394
- /* treatSourceAsInstantiable */ true, recursionCount);
16370
+ return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16395
16371
  }
16396
16372
  // Determine if the metaclass can be assigned to the object.
16397
16373
  const metaclass = concreteSrcType.details.effectiveMetaclass;
@@ -16415,14 +16391,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16415
16391
  if ((0, types_1.isFunction)(destType)) {
16416
16392
  let concreteSrcType = makeTopLevelTypeVarsConcrete(srcType);
16417
16393
  if ((0, types_1.isClassInstance)(concreteSrcType)) {
16418
- const boundMethod = getBoundMethod(concreteSrcType, '__call__', recursionCount);
16394
+ const boundMethod = getBoundMagicMethod(concreteSrcType, '__call__',
16395
+ /* selfType */ undefined, recursionCount);
16419
16396
  if (boundMethod) {
16420
16397
  concreteSrcType = (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
16421
16398
  }
16422
16399
  }
16423
16400
  // If it's a class, use the constructor for type compatibility checking.
16424
16401
  if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
16425
- const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
16402
+ const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, (0, types_1.isTypeVar)(srcType) ? (0, typeUtils_1.convertToInstance)(srcType) : undefined, recursionCount);
16426
16403
  if (constructor) {
16427
16404
  concreteSrcType = constructor;
16428
16405
  }
@@ -16517,8 +16494,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16517
16494
  // Are we trying to assign None to a protocol?
16518
16495
  if ((0, typeUtils_1.isNoneInstance)(srcType) && (0, types_1.isClassInstance)(destType) && types_1.ClassType.isProtocolClass(destType)) {
16519
16496
  if (noneClassType && (0, types_1.isInstantiableClass)(noneClassType)) {
16520
- return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), noneClassType, diag, destTypeVarContext, srcTypeVarContext, flags,
16521
- /* treatSourceAsInstantiable */ false, recursionCount);
16497
+ return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), types_1.ClassType.cloneAsInstance(noneClassType), diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16522
16498
  }
16523
16499
  }
16524
16500
  if ((0, typeUtils_1.isNoneInstance)(destType)) {
@@ -16907,7 +16883,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16907
16883
  }
16908
16884
  }
16909
16885
  }
16910
- const boundMethod = getBoundMethod(objType, '__call__', recursionCount);
16886
+ const boundMethod = getBoundMagicMethod(objType, '__call__', /* selfType */ undefined, recursionCount);
16911
16887
  if (boundMethod) {
16912
16888
  return (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
16913
16889
  }
@@ -16993,7 +16969,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16993
16969
  if (srcDetails.params.length < destDetails.argsIndex) {
16994
16970
  return;
16995
16971
  }
16996
- let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly);
16972
+ let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => {
16973
+ (0, debug_1.assert)(destDetails.argsIndex !== undefined);
16974
+ return i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly;
16975
+ });
16997
16976
  if (srcLastToPackIndex < 0) {
16998
16977
  srcLastToPackIndex = srcDetails.params.length;
16999
16978
  }
@@ -17655,7 +17634,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17655
17634
  matchIndex = possibleMatchIndex;
17656
17635
  }
17657
17636
  if (matchIndex < 0) {
17658
- continue;
17637
+ break;
17659
17638
  }
17660
17639
  if (matchIndex < previousMatchIndex) {
17661
17640
  diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadOrder());
@@ -18109,14 +18088,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18109
18088
  });
18110
18089
  return methodList;
18111
18090
  }
18112
- function bindFunctionToClassOrObjectWithErrors(baseType, memberType, memberClass, errorNode, treatConstructorAsClassMember = false, selfType) {
18113
- const diag = errorNode ? new diagnostic_1.DiagnosticAddendum() : undefined;
18114
- const result = bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember, selfType, diag);
18115
- if (!result && errorNode && diag) {
18116
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, diag.getString(), errorNode);
18117
- }
18118
- return result;
18119
- }
18120
18091
  // If the memberType is an instance or class method, creates a new
18121
18092
  // version of the function that has the "self" or "cls" parameter bound
18122
18093
  // to it. If treatConstructorAsClassMember is true, the function is
@@ -18135,9 +18106,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18135
18106
  if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
18136
18107
  return functionType;
18137
18108
  }
18138
- const baseObj = (0, types_1.isInstantiableClass)(baseType)
18139
- ? types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType))
18140
- : baseType;
18109
+ const baseObj = (0, types_1.isClassInstance)(baseType)
18110
+ ? baseType
18111
+ : types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType));
18141
18112
  return partiallySpecializeFunctionForBoundClassOrObject(baseType, functionType, memberClass !== null && memberClass !== void 0 ? memberClass : types_1.ClassType.cloneAsInstantiable(baseObj), diag, recursionCount, selfType !== null && selfType !== void 0 ? selfType : baseObj,
18142
18113
  /* stripFirstParam */ (0, types_1.isClassInstance)(baseType));
18143
18114
  }
@@ -18444,8 +18415,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18444
18415
  getBestOverloadForArguments,
18445
18416
  getBuiltInType,
18446
18417
  getTypeOfMember,
18447
- getTypeOfObjectMember,
18448
- getBoundMethod,
18418
+ getTypeOfBoundMember,
18419
+ getBoundMagicMethod,
18449
18420
  getTypeOfMagicMethodCall,
18450
18421
  bindFunctionToClassOrObject,
18451
18422
  getCallSignatureInfo,