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

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 (129) hide show
  1. package/dist/analyzer/checker.d.ts +1 -0
  2. package/dist/analyzer/checker.js +76 -77
  3. package/dist/analyzer/checker.js.map +1 -1
  4. package/dist/analyzer/codeFlowEngine.js +12 -33
  5. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  6. package/dist/analyzer/constraintSolver.js +30 -21
  7. package/dist/analyzer/constraintSolver.js.map +1 -1
  8. package/dist/analyzer/constructorTransform.js +3 -5
  9. package/dist/analyzer/constructorTransform.js.map +1 -1
  10. package/dist/analyzer/constructors.d.ts +6 -3
  11. package/dist/analyzer/constructors.js +53 -29
  12. package/dist/analyzer/constructors.js.map +1 -1
  13. package/dist/analyzer/dataClasses.js +10 -15
  14. package/dist/analyzer/dataClasses.js.map +1 -1
  15. package/dist/analyzer/declarationUtils.js +6 -3
  16. package/dist/analyzer/declarationUtils.js.map +1 -1
  17. package/dist/analyzer/decorators.js +1 -1
  18. package/dist/analyzer/decorators.js.map +1 -1
  19. package/dist/analyzer/docStringConversion.js +1 -1
  20. package/dist/analyzer/docStringConversion.js.map +1 -1
  21. package/dist/analyzer/docStringUtils.js +1 -1
  22. package/dist/analyzer/enums.js +1 -1
  23. package/dist/analyzer/enums.js.map +1 -1
  24. package/dist/analyzer/importResolver.d.ts +2 -1
  25. package/dist/analyzer/importResolver.js +23 -6
  26. package/dist/analyzer/importResolver.js.map +1 -1
  27. package/dist/analyzer/importStatementUtils.d.ts +1 -1
  28. package/dist/analyzer/importStatementUtils.js +33 -5
  29. package/dist/analyzer/importStatementUtils.js.map +1 -1
  30. package/dist/analyzer/operations.js +12 -6
  31. package/dist/analyzer/operations.js.map +1 -1
  32. package/dist/analyzer/packageTypeVerifier.js +9 -5
  33. package/dist/analyzer/packageTypeVerifier.js.map +1 -1
  34. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  35. package/dist/analyzer/parseTreeUtils.js +17 -2
  36. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  37. package/dist/analyzer/patternMatching.js +20 -15
  38. package/dist/analyzer/patternMatching.js.map +1 -1
  39. package/dist/analyzer/program.js +19 -12
  40. package/dist/analyzer/program.js.map +1 -1
  41. package/dist/analyzer/properties.js +20 -23
  42. package/dist/analyzer/properties.js.map +1 -1
  43. package/dist/analyzer/protocols.d.ts +1 -1
  44. package/dist/analyzer/protocols.js +14 -18
  45. package/dist/analyzer/protocols.js.map +1 -1
  46. package/dist/analyzer/service.js +1 -2
  47. package/dist/analyzer/service.js.map +1 -1
  48. package/dist/analyzer/sourceFile.js +33 -2
  49. package/dist/analyzer/sourceFile.js.map +1 -1
  50. package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -1
  51. package/dist/analyzer/sourceFileInfoUtils.js +9 -3
  52. package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
  53. package/dist/analyzer/sourceMapper.js +3 -0
  54. package/dist/analyzer/sourceMapper.js.map +1 -1
  55. package/dist/analyzer/typeEvaluator.d.ts +3 -1
  56. package/dist/analyzer/typeEvaluator.js +561 -574
  57. package/dist/analyzer/typeEvaluator.js.map +1 -1
  58. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -2
  59. package/dist/analyzer/typeGuards.js +26 -11
  60. package/dist/analyzer/typeGuards.js.map +1 -1
  61. package/dist/analyzer/typeUtils.js +43 -1
  62. package/dist/analyzer/typeUtils.js.map +1 -1
  63. package/dist/analyzer/typeVarContext.d.ts +1 -0
  64. package/dist/analyzer/typeVarContext.js +3 -0
  65. package/dist/analyzer/typeVarContext.js.map +1 -1
  66. package/dist/analyzer/types.d.ts +4 -2
  67. package/dist/analyzer/types.js +13 -5
  68. package/dist/analyzer/types.js.map +1 -1
  69. package/dist/common/configOptions.d.ts +2 -1
  70. package/dist/common/configOptions.js +18 -1
  71. package/dist/common/configOptions.js.map +1 -1
  72. package/dist/common/extensibility.d.ts +3 -0
  73. package/dist/common/serviceProviderExtensions.d.ts +2 -1
  74. package/dist/common/serviceProviderExtensions.js +1 -0
  75. package/dist/common/serviceProviderExtensions.js.map +1 -1
  76. package/dist/common/textEditTracker.js +2 -2
  77. package/dist/common/textEditTracker.js.map +1 -1
  78. package/dist/languageServerBase.d.ts +4 -4
  79. package/dist/languageServerBase.js +10 -7
  80. package/dist/languageServerBase.js.map +1 -1
  81. package/dist/languageService/completionProvider.d.ts +2 -1
  82. package/dist/languageService/completionProvider.js +9 -13
  83. package/dist/languageService/completionProvider.js.map +1 -1
  84. package/dist/localization/localize.d.ts +7 -3
  85. package/dist/localization/localize.js +5 -1
  86. package/dist/localization/localize.js.map +1 -1
  87. package/dist/localization/package.nls.cs.json +5 -2
  88. package/dist/localization/package.nls.de.json +5 -2
  89. package/dist/localization/package.nls.en-us.json +11 -7
  90. package/dist/localization/package.nls.es.json +5 -2
  91. package/dist/localization/package.nls.fr.json +5 -2
  92. package/dist/localization/package.nls.it.json +5 -2
  93. package/dist/localization/package.nls.ja.json +5 -2
  94. package/dist/localization/package.nls.ko.json +5 -2
  95. package/dist/localization/package.nls.pl.json +5 -2
  96. package/dist/localization/package.nls.pt-br.json +5 -2
  97. package/dist/localization/package.nls.qps-ploc.json +5 -2
  98. package/dist/localization/package.nls.ru.json +5 -2
  99. package/dist/localization/package.nls.tr.json +5 -2
  100. package/dist/localization/package.nls.zh-cn.json +5 -2
  101. package/dist/localization/package.nls.zh-tw.json +5 -2
  102. package/dist/pyright.js +17 -1
  103. package/dist/pyright.js.map +1 -1
  104. package/dist/server.js.map +1 -1
  105. package/dist/tests/config.test.js +7 -5
  106. package/dist/tests/config.test.js.map +1 -1
  107. package/dist/tests/diagnosticOverrides.test.js +4 -2
  108. package/dist/tests/diagnosticOverrides.test.js.map +1 -1
  109. package/dist/tests/docStringConversion.test.js +0 -22
  110. package/dist/tests/docStringConversion.test.js.map +1 -1
  111. package/dist/tests/fourslash/completions.params.fourslash.js +11 -0
  112. package/dist/tests/fourslash/completions.params.fourslash.js.map +1 -1
  113. package/dist/tests/fourslash/hover.docstring.split.fourslash.js +10 -0
  114. package/dist/tests/fourslash/hover.docstring.split.fourslash.js.map +1 -1
  115. package/dist/tests/fourslash/signature.dunderNew.fourslash.js +1 -1
  116. package/dist/tests/fourslash/signature.dunderNew.fourslash.js.map +1 -1
  117. package/dist/tests/harness/fourslash/testState.js +3 -3
  118. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  119. package/dist/tests/parseTreeUtils.test.js +15 -0
  120. package/dist/tests/parseTreeUtils.test.js.map +1 -1
  121. package/dist/tests/textEditUtil.test.js +25 -0
  122. package/dist/tests/textEditUtil.test.js.map +1 -1
  123. package/dist/tests/typeEvaluator1.test.js +8 -0
  124. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  125. package/dist/tests/typeEvaluator2.test.js +12 -0
  126. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  127. package/dist/tests/typeEvaluator3.test.js +3 -3
  128. package/dist/tests/typeEvaluator4.test.js +6 -6
  129. package/package.json +1 -1
@@ -617,7 +617,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
617
617
  break;
618
618
  }
619
619
  case 4 /* AssignmentExpression */: {
620
- typeResult = getTypeOfExpression(node.rightExpression);
620
+ typeResult = getTypeOfExpression(node.rightExpression, flags, inferenceContext);
621
621
  assignTypeToExpression(node.name, typeResult.type, !!typeResult.isIncomplete, node.rightExpression,
622
622
  /* ignoreEmptyContainers */ true);
623
623
  break;
@@ -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,25 @@ 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
+ if (recursionCount > types_1.maxTypeRecursionCount) {
1385
+ return undefined;
1386
+ }
1387
+ recursionCount++;
1388
+ const boundMethodResult = getTypeOfBoundMember(
1389
+ /* errorNode */ undefined, classType, memberName,
1390
+ /* usage */ undefined,
1391
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */, selfType, recursionCount);
1392
+ if (!boundMethodResult || boundMethodResult.typeErrors) {
1384
1393
  return undefined;
1385
1394
  }
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);
1395
+ if ((0, types_1.isFunction)(boundMethodResult.type) || (0, types_1.isOverloadedFunction)(boundMethodResult.type)) {
1396
+ return boundMethodResult.type;
1397
+ }
1398
+ if ((0, types_1.isClassInstance)(boundMethodResult.type)) {
1399
+ return getBoundMagicMethod(boundMethodResult.type, '__call__', selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType), recursionCount);
1393
1400
  }
1394
- if ((0, types_1.isAnyOrUnknown)(unboundMethodType)) {
1401
+ if ((0, types_1.isAnyOrUnknown)(boundMethodResult.type)) {
1395
1402
  const unknownFunction = types_1.FunctionType.createSynthesizedInstance('', 32768 /* SkipArgsKwargsCompatibilityCheck */);
1396
1403
  types_1.FunctionType.addDefaultParameters(unknownFunction);
1397
1404
  return unknownFunction;
@@ -1472,35 +1479,39 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1472
1479
  }
1473
1480
  case 6 /* Class */: {
1474
1481
  if (types_1.TypeBase.isInstantiable(subtype)) {
1475
- let methodType;
1482
+ let constructorType;
1476
1483
  // Try to get the `__init__` method first because it typically has more
1477
1484
  // 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);
1485
+ const initMethodResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, callNode, types_1.ClassType.cloneAsInstance(subtype),
1486
+ /* skipObjectBase */ false);
1487
+ if (initMethodResult && !initMethodResult.typeErrors && (0, types_1.isFunction)(initMethodResult.type)) {
1488
+ constructorType = initMethodResult.type;
1489
+ }
1490
+ const isObjectInit = constructorType &&
1491
+ (0, types_1.isFunction)(constructorType) &&
1492
+ constructorType.details.fullName === 'builtins.object.__init__';
1493
+ const isDefaultParams = constructorType &&
1494
+ (0, types_1.isFunction)(constructorType) &&
1495
+ types_1.FunctionType.hasDefaultParameters(constructorType);
1484
1496
  // If there was no `__init__` or the only `__init__` that was found was from
1485
1497
  // the `object` class or accepts only default parameters(* args, ** kwargs),
1486
1498
  // 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
- }
1499
+ if (!constructorType || isObjectInit || isDefaultParams) {
1500
+ const newMethodResult = (0, constructors_1.getBoundNewMethod)(evaluatorInterface, callNode, subtype,
1501
+ /* skipObjectBase */ false);
1502
+ if (newMethodResult &&
1503
+ !newMethodResult.typeErrors &&
1504
+ (0, types_1.isFunction)(newMethodResult.type) &&
1505
+ newMethodResult.type.details.fullName !== 'builtins.object.__new__') {
1506
+ constructorType = newMethodResult.type;
1496
1507
  }
1497
1508
  }
1498
- if (methodType) {
1499
- addFunctionToSignature(methodType);
1509
+ if (constructorType) {
1510
+ addFunctionToSignature(constructorType);
1500
1511
  }
1501
1512
  }
1502
1513
  else {
1503
- const methodType = getBoundMethod(subtype, '__call__');
1514
+ const methodType = getBoundMagicMethod(subtype, '__call__');
1504
1515
  if (methodType) {
1505
1516
  addFunctionToSignature(methodType);
1506
1517
  }
@@ -1635,20 +1646,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1635
1646
  case 24 /* Index */: {
1636
1647
  const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.baseExpression, 2 /* IndexBaseDefaults */).type);
1637
1648
  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
- }
1649
+ const setItemType = getBoundMagicMethod(baseType, '__setitem__');
1650
+ if (setItemType && (0, types_1.isFunction)(setItemType) && setItemType.details.parameters.length >= 2) {
1651
+ const paramType = types_1.FunctionType.getEffectiveParameterType(setItemType, 1);
1652
+ if (!(0, types_1.isAnyOrUnknown)(paramType)) {
1653
+ return paramType;
1652
1654
  }
1653
1655
  }
1654
1656
  else if (types_1.ClassType.isTypedDictClass(baseType)) {
@@ -1666,14 +1668,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1666
1668
  if (declaredType) {
1667
1669
  // If it's a descriptor, we need to get the setter type.
1668
1670
  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
- }
1671
+ const setter = getBoundMagicMethod(declaredType, '__set__');
1672
+ if (setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 2) {
1673
+ declaredType = setter.details.parameters[1].type;
1677
1674
  if ((0, types_1.isAnyOrUnknown)(declaredType)) {
1678
1675
  return undefined;
1679
1676
  }
@@ -1685,8 +1682,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1685
1682
  }
1686
1683
  if ((0, types_1.isFunction)(declaredType) || (0, types_1.isOverloadedFunction)(declaredType)) {
1687
1684
  if (bindFunction) {
1688
- declaredType = bindFunctionToClassOrObjectWithErrors(classOrObjectBase, declaredType,
1689
- /* memberAccessClass */ undefined, expression);
1685
+ declaredType = bindFunctionToClassOrObject(classOrObjectBase, declaredType);
1690
1686
  }
1691
1687
  }
1692
1688
  }
@@ -3323,7 +3319,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3323
3319
  }
3324
3320
  if (typeParametersForScope) {
3325
3321
  const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
3326
- if (match === null || match === void 0 ? void 0 : match.scopeId) {
3322
+ if ((match === null || match === void 0 ? void 0 : match.scopeId) !== undefined && match.scopeName !== undefined && match.scopeType !== undefined) {
3327
3323
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
3328
3324
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
3329
3325
  return {
@@ -3559,7 +3555,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3559
3555
  }, usage, 0 /* None */);
3560
3556
  }
3561
3557
  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,
3558
+ 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
3559
  /* memberAccessFlags */ undefined, baseTypeResult.bindToSelfType);
3564
3560
  if (typeResult) {
3565
3561
  type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
@@ -3651,7 +3647,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3651
3647
  return undefined;
3652
3648
  }
3653
3649
  if ((0, typeUtils_1.isNoneInstance)(subtype) && noneType && (0, types_1.isClassInstance)(noneType)) {
3654
- const typeResult = getTypeOfObjectMember(node.memberName, noneType, memberName, usage, diag);
3650
+ const typeResult = getTypeOfBoundMember(node.memberName, noneType, memberName, usage, diag);
3655
3651
  if (typeResult) {
3656
3652
  type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
3657
3653
  if (typeResult.isIncomplete) {
@@ -3732,8 +3728,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3732
3728
  }
3733
3729
  return { type, isIncomplete, isAsymmetricAccessor, isRequired, isNotRequired, memberAccessDeprecationInfo };
3734
3730
  }
3735
- function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType) {
3736
- var _a, _b, _c, _d;
3731
+ function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType, recursionCount = 0) {
3732
+ var _a, _b, _c;
3737
3733
  const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
3738
3734
  // Always look for a member with a declared type first.
3739
3735
  let memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, flags | 64 /* DeclaredTypesOnly */);
@@ -3746,8 +3742,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3746
3742
  // No attribute of that name was found. If this is a member access
3747
3743
  // through an object, see if there's an attribute access override
3748
3744
  // method ("__getattr__", etc.).
3749
- if ((flags & 512 /* SkipAttributeAccessOverride */) === 0) {
3750
- const generalAttrType = applyAttributeAccessOverride(classType, errorNode, usage, memberName, selfType);
3745
+ if ((flags & 512 /* SkipAttributeAccessOverride */) === 0 && errorNode) {
3746
+ const generalAttrType = applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType);
3751
3747
  if (generalAttrType) {
3752
3748
  return {
3753
3749
  symbol: undefined,
@@ -3756,7 +3752,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3756
3752
  isDescriptorError: false,
3757
3753
  isClassMember: false,
3758
3754
  isClassVar: false,
3759
- isAsymmetricAccessor: generalAttrType.isAsymmetricAccessor,
3755
+ isAsymmetricAccessor: !!generalAttrType.isAsymmetricAccessor,
3760
3756
  };
3761
3757
  }
3762
3758
  }
@@ -3770,7 +3766,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3770
3766
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsInitVar().format({ name: memberName }));
3771
3767
  return undefined;
3772
3768
  }
3773
- if (usage.method !== 'get') {
3769
+ if (usage.method !== 'get' && errorNode) {
3774
3770
  // If the usage indicates a 'set' or 'delete' and the access is within the
3775
3771
  // class definition itself, use only the declared type to avoid circular
3776
3772
  // type evaluation.
@@ -3805,23 +3801,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3805
3801
  }
3806
3802
  }
3807
3803
  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.
3804
+ let selfClass;
3815
3805
  if (selfType) {
3816
- if ((0, types_1.isTypeVar)(selfType) && selfType.details.isSynthesizedSelf) {
3817
- selfClass = selfType;
3818
- }
3819
- else {
3820
- selfClass = undefined;
3821
- }
3806
+ selfClass = (0, typeUtils_1.convertToInstantiable)(selfType);
3822
3807
  }
3823
- else if (memberName === '__new__') {
3824
- selfClass = undefined;
3808
+ else {
3809
+ // Skip this for __new__ methods because they are not bound
3810
+ // to the class but rather assume the type of the cls argument.
3811
+ if (memberName !== '__new__') {
3812
+ selfClass = classType;
3813
+ }
3825
3814
  }
3826
3815
  const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
3827
3816
  type = (_c = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
@@ -3839,7 +3828,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3839
3828
  }
3840
3829
  if (usage.method === 'get') {
3841
3830
  // Mark the member accessed if it's not coming from a parent class.
3842
- if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3831
+ if (errorNode &&
3832
+ (0, types_1.isInstantiableClass)(memberInfo.classType) &&
3843
3833
  types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
3844
3834
  setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
3845
3835
  }
@@ -3852,32 +3842,96 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3852
3842
  }
3853
3843
  }
3854
3844
  }
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
- }
3845
+ // If the member is a descriptor object, apply the descriptor protocol
3846
+ // now. If the member is an instance or class method, bind the method.
3847
+ let isDescriptorError = false;
3848
+ let isAsymmetricAccessor = false;
3849
+ let isDescriptorApplied = false;
3850
+ let memberAccessDeprecationInfo;
3851
+ type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
3852
+ const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
3853
+ const isClassMember = !memberInfo || memberInfo.isClassMember;
3854
+ let resultType;
3855
+ if ((0, types_1.isClass)(concreteSubtype) && isClassMember && errorNode) {
3856
+ const descResult = applyDescriptorAccessMethod(subtype, concreteSubtype, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag);
3857
+ if (descResult.isAsymmetricAccessor) {
3858
+ isAsymmetricAccessor = true;
3859
+ }
3860
+ if (descResult.memberAccessDeprecationInfo) {
3861
+ memberAccessDeprecationInfo = descResult.memberAccessDeprecationInfo;
3862
+ }
3863
+ if (descResult.typeErrors) {
3870
3864
  isDescriptorError = true;
3871
3865
  }
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
- }));
3866
+ if (descResult.isDescriptorApplied) {
3867
+ isDescriptorApplied = true;
3868
+ }
3869
+ resultType = descResult.type;
3870
+ }
3871
+ else if ((0, types_1.isFunction)(concreteSubtype) || (0, types_1.isOverloadedFunction)(concreteSubtype)) {
3872
+ const typeResult = bindMethodForMemberAccess(subtype, concreteSubtype, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount);
3873
+ resultType = typeResult.type;
3874
+ if (typeResult.typeErrors) {
3875
+ isDescriptorError = true;
3876
+ }
3877
+ }
3878
+ else {
3879
+ resultType = subtype;
3880
+ }
3881
+ // If this is a "set" operation, we have a bit more work to do.
3882
+ if (usage.method !== 'set') {
3883
+ return resultType;
3884
+ }
3885
+ // Check for an attempt to overwrite a ClassVar member from an instance.
3886
+ if (!isDescriptorApplied &&
3887
+ (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.isClassVar()) &&
3888
+ (flags & 128 /* DisallowClassVarWrites */) !== 0) {
3889
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
3890
+ isDescriptorError = true;
3891
+ }
3892
+ // Check for an attempt to overwrite a final member variable.
3893
+ const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
3894
+ if (finalVarTypeDecl &&
3895
+ errorNode &&
3896
+ !ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
3897
+ // If a Final instance variable is declared in the class body but is
3898
+ // being assigned within an __init__ method, it's allowed.
3899
+ const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
3900
+ if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
3901
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
3878
3902
  isDescriptorError = true;
3879
3903
  }
3880
3904
  }
3905
+ // Check for an attempt to overwrite an instance variable that is
3906
+ // read-only (e.g. in a named tuple).
3907
+ if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
3908
+ (0, types_1.isClass)(memberInfo.classType) &&
3909
+ types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
3910
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
3911
+ isDescriptorError = true;
3912
+ }
3913
+ return resultType;
3914
+ });
3915
+ if (!isDescriptorError && usage.method === 'set' && usage.setType) {
3916
+ // Verify that the assigned type is compatible.
3917
+ if (!assignType(type, usage.setType.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum())) {
3918
+ if (!usage.setType.isIncomplete) {
3919
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberAssignment().format({
3920
+ type: printType(usage.setType.type),
3921
+ name: memberName,
3922
+ classType: printObjectTypeForClass(classType),
3923
+ }));
3924
+ }
3925
+ isDescriptorError = true;
3926
+ }
3927
+ if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
3928
+ types_1.ClassType.isFrozenDataClass(memberInfo.classType) &&
3929
+ isAccessedThroughObject) {
3930
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataClassFrozen().format({
3931
+ name: printType(types_1.ClassType.cloneAsInstance(memberInfo.classType)),
3932
+ }));
3933
+ isDescriptorError = true;
3934
+ }
3881
3935
  }
3882
3936
  return {
3883
3937
  symbol: memberInfo.symbol,
@@ -3887,329 +3941,219 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3887
3941
  isClassMember: !memberInfo.isInstanceMember,
3888
3942
  isClassVar: memberInfo.isClassVar,
3889
3943
  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,
3944
+ isAsymmetricAccessor,
3945
+ memberAccessDeprecationInfo,
3892
3946
  };
3893
3947
  }
3894
3948
  // 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;
3949
+ // if they apply.
3950
+ function applyDescriptorAccessMethod(memberType, concreteMemberType, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag) {
3951
+ var _a, _b, _c, _d;
3899
3952
  const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
3900
- let isTypeValid = true;
3953
+ let accessMethodName;
3954
+ if (usage.method === 'get') {
3955
+ accessMethodName = '__get__';
3956
+ }
3957
+ else if (usage.method === 'set') {
3958
+ accessMethodName = '__set__';
3959
+ }
3960
+ else {
3961
+ accessMethodName = '__delete__';
3962
+ }
3963
+ const methodTypeResult = getTypeOfBoundMember(errorNode, concreteMemberType, accessMethodName,
3964
+ /* usage */ undefined, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */);
3965
+ if (!methodTypeResult) {
3966
+ // Provide special error messages for properties.
3967
+ if (types_1.ClassType.isPropertyClass(concreteMemberType)) {
3968
+ if (usage.method !== 'get') {
3969
+ const message = usage.method === 'set'
3970
+ ? localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter()
3971
+ : localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter();
3972
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(message.format({ name: memberName }));
3973
+ return { type: types_1.AnyType.create(), typeErrors: true };
3974
+ }
3975
+ }
3976
+ return { type: memberType };
3977
+ }
3978
+ const methodClassType = methodTypeResult.classType;
3979
+ let methodType = methodTypeResult.type;
3980
+ if (methodTypeResult.typeErrors || !methodClassType) {
3981
+ return { type: types_1.UnknownType.create(), typeErrors: true };
3982
+ }
3983
+ if (!(0, types_1.isFunction)(methodType) && !(0, types_1.isOverloadedFunction)(methodType)) {
3984
+ if ((0, types_1.isAnyOrUnknown)(methodType)) {
3985
+ return { type: methodType };
3986
+ }
3987
+ // TODO - emit an error for this condition.
3988
+ return { type: memberType, typeErrors: true };
3989
+ }
3990
+ // Special-case logic for properties.
3991
+ if (types_1.ClassType.isPropertyClass(concreteMemberType) &&
3992
+ memberInfo &&
3993
+ (0, types_1.isInstantiableClass)(memberInfo.classType) &&
3994
+ methodType) {
3995
+ // If the property is being accessed from a protocol class (not an instance),
3996
+ // flag this as an error because a property within a protocol is meant to be
3997
+ // interpreted as a read-only attribute rather than a protocol, so accessing
3998
+ // it directly from the class has an ambiguous meaning.
3999
+ if ((flags & 16 /* SkipInstanceMembers */) !== 0 && types_1.ClassType.isProtocolClass(classType)) {
4000
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
4001
+ return { type: memberType, typeErrors: true };
4002
+ }
4003
+ // Infer return types before specializing. Otherwise a generic inferred
4004
+ // return type won't be properly specialized.
4005
+ inferReturnTypeIfNecessary(methodType);
4006
+ // This specialization is required specifically for properties, which should be
4007
+ // generic but are not defined that way. Because of this, we use type variables
4008
+ // in the synthesized methods (e.g. __get__) for the property class that are
4009
+ // defined in the class that declares the fget method.
4010
+ const specializedType = (0, typeUtils_1.partiallySpecializeType)(methodType, memberInfo.classType, selfType ? (0, typeUtils_1.convertToInstantiable)(selfType) : classType);
4011
+ if ((0, types_1.isFunction)(specializedType) || (0, types_1.isOverloadedFunction)(specializedType)) {
4012
+ methodType = specializedType;
4013
+ }
4014
+ }
4015
+ // Determine if we're calling __set__ on an asymmetric descriptor or property.
3901
4016
  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
- }
4017
+ if (usage.method === 'set' && (0, types_1.isClass)(methodClassType)) {
4018
+ if (isAsymmetricDescriptorClass(methodClassType)) {
4019
+ isAsymmetricAccessor = true;
4118
4020
  }
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
- }
4021
+ }
4022
+ if (!methodType) {
4023
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessBindingFailed().format({
4024
+ name: accessMethodName,
4025
+ className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
4026
+ }));
4027
+ return {
4028
+ type: types_1.UnknownType.create(),
4029
+ typeErrors: true,
4030
+ isDescriptorApplied: true,
4031
+ isAsymmetricAccessor,
4032
+ };
4033
+ }
4034
+ // Simulate a call to the access method.
4035
+ const argList = [];
4036
+ // Provide "obj" argument.
4037
+ let objArgType;
4038
+ if (types_1.ClassType.isClassProperty(concreteMemberType)) {
4039
+ // Handle "class properties" as a special case. We need to pass
4040
+ // the class rather than the object instance in this case.
4041
+ objArgType = classType;
4042
+ }
4043
+ else if (isAccessedThroughObject) {
4044
+ objArgType = selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType);
4045
+ }
4046
+ else {
4047
+ objArgType = getNoneType();
4048
+ }
4049
+ argList.push({
4050
+ argumentCategory: 0 /* Simple */,
4051
+ typeResult: { type: objArgType },
4052
+ });
4053
+ if (usage.method === 'get') {
4054
+ let classArgType;
4055
+ if (selfType) {
4056
+ classArgType = (0, typeUtils_1.convertToInstantiable)(selfType);
4146
4057
  }
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
- }
4058
+ else {
4059
+ classArgType = isAccessedThroughObject ? types_1.ClassType.cloneAsInstantiable(classType) : classType;
4206
4060
  }
4207
- return subtype;
4061
+ // Provide "owner" argument.
4062
+ argList.push({
4063
+ argumentCategory: 0 /* Simple */,
4064
+ typeResult: { type: classArgType },
4065
+ });
4066
+ }
4067
+ else if (usage.method === 'set') {
4068
+ // Provide "value" argument.
4069
+ argList.push({
4070
+ argumentCategory: 0 /* Simple */,
4071
+ typeResult: {
4072
+ type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
4073
+ isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
4074
+ },
4075
+ });
4076
+ }
4077
+ // Suppress diagnostics for these method calls because they would be redundant.
4078
+ const callResult = suppressDiagnostics(errorNode, () => {
4079
+ return validateCallArguments(errorNode, argList, { type: methodType },
4080
+ /* typeVarContext */ undefined,
4081
+ /* skipUnknownArgCheck */ true);
4208
4082
  });
4209
- if (!isTypeValid) {
4210
- return undefined;
4083
+ // Collect deprecation information associated with the member access method.
4084
+ let deprecationInfo;
4085
+ if (callResult.overloadsUsedForCall && callResult.overloadsUsedForCall.length >= 1) {
4086
+ const overloadUsed = callResult.overloadsUsedForCall[0];
4087
+ if (overloadUsed.details.deprecatedMessage) {
4088
+ deprecationInfo = {
4089
+ deprecationMessage: overloadUsed.details.deprecatedMessage,
4090
+ accessType: types_1.ClassType.isPropertyClass(concreteMemberType) ? 'property' : 'descriptor',
4091
+ accessMethod: usage.method,
4092
+ };
4093
+ }
4094
+ }
4095
+ if (!callResult.argumentErrors) {
4096
+ return {
4097
+ // For set or delete, always return Any.
4098
+ type: usage.method === 'get' ? (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create() : types_1.AnyType.create(),
4099
+ isDescriptorApplied: true,
4100
+ isAsymmetricAccessor,
4101
+ memberAccessDeprecationInfo: deprecationInfo,
4102
+ };
4211
4103
  }
4212
- return { type, isAsymmetricAccessor, memberAccessDeprecationInfo };
4104
+ // Errors were detected when evaluating the access method call.
4105
+ if (usage.method === 'set') {
4106
+ if (usage.setType &&
4107
+ (0, types_1.isFunction)(methodType) &&
4108
+ methodType.details.parameters.length >= 2 &&
4109
+ !usage.setType.isIncomplete) {
4110
+ const setterType = types_1.FunctionType.getEffectiveParameterType(methodType, 1);
4111
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
4112
+ destType: printType(setterType),
4113
+ sourceType: printType(usage.setType.type),
4114
+ }));
4115
+ }
4116
+ else if ((0, types_1.isOverloadedFunction)(methodType)) {
4117
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
4118
+ }
4119
+ }
4120
+ else {
4121
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessCallFailed().format({
4122
+ name: accessMethodName,
4123
+ className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
4124
+ }));
4125
+ }
4126
+ return {
4127
+ type: types_1.UnknownType.create(),
4128
+ typeErrors: true,
4129
+ isDescriptorApplied: true,
4130
+ isAsymmetricAccessor,
4131
+ memberAccessDeprecationInfo: deprecationInfo,
4132
+ };
4133
+ }
4134
+ function bindMethodForMemberAccess(type, concreteType, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount = 0) {
4135
+ // Check for an attempt to overwrite a final method.
4136
+ if (usage.method === 'set') {
4137
+ const impl = (0, types_1.isFunction)(concreteType)
4138
+ ? concreteType
4139
+ : types_1.OverloadedFunctionType.getImplementation(concreteType);
4140
+ if (impl && types_1.FunctionType.isFinal(impl) && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
4141
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
4142
+ name: memberName,
4143
+ className: memberInfo.classType.details.name,
4144
+ }));
4145
+ return { type: types_1.UnknownType.create(), typeErrors: true };
4146
+ }
4147
+ }
4148
+ // If this function is an instance member (e.g. a lambda that was
4149
+ // assigned to an instance variable), don't perform any binding.
4150
+ if (types_1.TypeBase.isInstance(classType)) {
4151
+ if (!memberInfo || memberInfo.isInstanceMember) {
4152
+ return { type: type };
4153
+ }
4154
+ }
4155
+ 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);
4156
+ return { type: boundType !== null && boundType !== void 0 ? boundType : types_1.UnknownType.create(), typeErrors: !boundType };
4213
4157
  }
4214
4158
  function isAsymmetricDescriptorClass(classType) {
4215
4159
  var _a;
@@ -4276,11 +4220,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4276
4220
  return isAsymmetric;
4277
4221
  }
4278
4222
  // Applies the __getattr__, __setattr__ or __delattr__ method if present.
4279
- function applyAttributeAccessOverride(classType, errorNode, usage, memberName, selfType) {
4223
+ // If it's not applicable, returns undefined.
4224
+ function applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType) {
4280
4225
  var _a, _b, _c, _d, _e;
4281
4226
  const getAttributeAccessMember = (name) => {
4282
4227
  var _a;
4283
- return (_a = getTypeOfObjectMember(errorNode, classType, name, { method: 'get' },
4228
+ return (_a = getTypeOfBoundMember(errorNode, classType, name,
4229
+ /* usage */ undefined,
4284
4230
  /* diag */ undefined, 16 /* SkipInstanceMembers */ |
4285
4231
  4 /* SkipObjectBaseClass */ |
4286
4232
  512 /* SkipAttributeAccessOverride */, selfType)) === null || _a === void 0 ? void 0 : _a.type;
@@ -4299,20 +4245,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4299
4245
  if (!accessMemberType) {
4300
4246
  return undefined;
4301
4247
  }
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 },
4248
+ const argList = [];
4249
+ // Provide "name" argument.
4250
+ argList.push({
4251
+ argumentCategory: 0 /* Simple */,
4252
+ typeResult: {
4253
+ type: strClassType && (0, types_1.isInstantiableClass)(strClassType)
4254
+ ? types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName)
4255
+ : types_1.AnyType.create(),
4311
4256
  },
4312
- ];
4257
+ });
4313
4258
  if (usage.method === 'set') {
4259
+ // Provide "value" argument.
4314
4260
  argList.push({
4315
- // Provide "value" argument.
4316
4261
  argumentCategory: 0 /* Simple */,
4317
4262
  typeResult: {
4318
4263
  type: (_c = (_b = usage.setType) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create(),
@@ -4321,20 +4266,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4321
4266
  });
4322
4267
  }
4323
4268
  if (!(0, types_1.isFunction)(accessMemberType) && !(0, types_1.isOverloadedFunction)(accessMemberType)) {
4324
- // TODO - need to handle and report this error.
4269
+ if ((0, types_1.isAnyOrUnknown)(accessMemberType)) {
4270
+ return { type: accessMemberType };
4271
+ }
4272
+ // TODO - emit an error for this condition.
4325
4273
  return undefined;
4326
4274
  }
4327
4275
  const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(accessMemberType));
4328
4276
  const callResult = validateCallArguments(errorNode, argList, { type: accessMemberType }, typeVarContext,
4329
4277
  /* skipUnknownArgCheck */ true);
4330
- // TODO - need to handle and report errors when validating call to
4331
- // attribute access method.
4332
4278
  let isAsymmetricAccessor = false;
4333
4279
  if (usage.method === 'set') {
4334
4280
  isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType);
4335
4281
  }
4336
4282
  return {
4337
4283
  type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
4284
+ typeErrors: callResult.argumentErrors,
4338
4285
  isAsymmetricAccessor,
4339
4286
  };
4340
4287
  }
@@ -4545,10 +4492,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4545
4492
  typeParameters.forEach((param, index) => {
4546
4493
  if (param.details.isParamSpec && index < typeArgs.length) {
4547
4494
  const typeArgType = typeArgs[index].type;
4548
- if (typeArgs[index].typeList) {
4495
+ const typeList = typeArgs[index].typeList;
4496
+ if (typeList) {
4549
4497
  const functionType = types_1.FunctionType.createSynthesizedInstance('', 65536 /* ParamSpecValue */);
4550
4498
  types_1.TypeBase.setSpecialForm(functionType);
4551
- typeArgs[index].typeList.forEach((paramType, paramIndex) => {
4499
+ typeList.forEach((paramType, paramIndex) => {
4552
4500
  types_1.FunctionType.addParameter(functionType, {
4553
4501
  category: 0 /* Simple */,
4554
4502
  name: `__p${paramIndex}`,
@@ -4663,7 +4611,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4663
4611
  }
4664
4612
  if ((0, types_1.isTypeVar)(baseTypeResult.type) && (0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4665
4613
  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);
4614
+ 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
4615
  return { type };
4668
4616
  }
4669
4617
  let isIncomplete = baseTypeResult.isIncomplete;
@@ -4692,9 +4640,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4692
4640
  (0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass) &&
4693
4641
  !types_1.ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) &&
4694
4642
  (flags & 128 /* ExpectingInstantiableType */) === 0) {
4695
- const itemMethodType = getTypeOfObjectMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
4696
- /* usage */ undefined,
4697
- /* diag */ undefined, 512 /* SkipAttributeAccessOverride */);
4643
+ const itemMethodType = getBoundMagicMethod(concreteSubtype, getIndexAccessMagicMethodName(usage));
4698
4644
  if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
4699
4645
  // If the class doesn't derive from Generic, a type argument should not be allowed.
4700
4646
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
@@ -4920,7 +4866,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4920
4866
  }
4921
4867
  }
4922
4868
  function getTypeOfIndexedObjectOrClass(node, baseType, usage) {
4923
- var _a, _b, _c, _d, _e;
4869
+ var _a, _b, _c, _d;
4924
4870
  // Handle index operations for TypedDict classes specially.
4925
4871
  if ((0, types_1.isClassInstance)(baseType) && types_1.ClassType.isTypedDictClass(baseType)) {
4926
4872
  const typeFromTypedDict = (0, typedDicts_1.getTypeOfIndexedTypedDict)(evaluatorInterface, node, baseType, usage);
@@ -4929,9 +4875,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4929
4875
  }
4930
4876
  }
4931
4877
  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;
4878
+ const itemMethodType = getBoundMagicMethod(baseType, magicMethodName);
4935
4879
  if (!itemMethodType) {
4936
4880
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
4937
4881
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.methodNotDefinedOnType().format({
@@ -5060,7 +5004,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5060
5004
  },
5061
5005
  ];
5062
5006
  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();
5007
+ let setType = (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.AnyType.create();
5064
5008
  // Expand constrained type variables.
5065
5009
  if ((0, types_1.isTypeVar)(setType) && setType.details.constraints.length > 0) {
5066
5010
  const conditionFilter = (0, types_1.isClassInstance)(baseType) ? baseType.condition : undefined;
@@ -5071,7 +5015,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5071
5015
  argumentCategory: 0 /* Simple */,
5072
5016
  typeResult: {
5073
5017
  type: setType,
5074
- isIncomplete: !!((_d = usage.setType) === null || _d === void 0 ? void 0 : _d.isIncomplete),
5018
+ isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
5075
5019
  },
5076
5020
  });
5077
5021
  }
@@ -5103,7 +5047,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5103
5047
  if ((0, types_1.isClassInstance)(positionalIndexType)) {
5104
5048
  const altArgList = [...argList];
5105
5049
  altArgList[0] = { ...altArgList[0] };
5106
- const indexMethod = getTypeOfObjectMember(node, positionalIndexType, '__index__');
5050
+ const indexMethod = getBoundMagicMethod(positionalIndexType, '__index__');
5107
5051
  if (indexMethod) {
5108
5052
  const intType = getBuiltInObject(node, 'int');
5109
5053
  if ((0, types_1.isClassInstance)(intType)) {
@@ -5121,7 +5065,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5121
5065
  }
5122
5066
  callResult = validateCallArguments(node, argList, { type: itemMethodType });
5123
5067
  return {
5124
- type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
5068
+ type: (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create(),
5125
5069
  isIncomplete: !!callResult.isTypeIncomplete,
5126
5070
  };
5127
5071
  }
@@ -5807,7 +5751,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5807
5751
  }
5808
5752
  }
5809
5753
  if (bindToType && implicitBindToType) {
5810
- bindToType = (0, typeUtils_1.addConditionToType)(bindToType, (0, typeUtils_1.getTypeCondition)(implicitBindToType));
5754
+ const typeCondition = (0, typeUtils_1.getTypeCondition)(implicitBindToType);
5755
+ if (typeCondition) {
5756
+ bindToType = (0, typeUtils_1.addConditionToType)(bindToType, typeCondition);
5757
+ }
5758
+ else if ((0, types_1.isClass)(implicitBindToType)) {
5759
+ bindToType = implicitBindToType;
5760
+ }
5811
5761
  }
5812
5762
  }
5813
5763
  // Determine whether super() should return an instance of the class or
@@ -5830,9 +5780,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5830
5780
  // Python docs indicate that super() isn't valid for
5831
5781
  // operations other than member accesses or attribute lookups.
5832
5782
  const parentNode = node.parent;
5833
- if (parentNode.nodeType === 35 /* MemberAccess */) {
5783
+ if ((parentNode === null || parentNode === void 0 ? void 0 : parentNode.nodeType) === 35 /* MemberAccess */) {
5834
5784
  const memberName = parentNode.memberName.value;
5835
- const effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5785
+ let effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
5786
+ // If the bind-to type is a protocol, don't use the effective target class.
5787
+ // This pattern is used for mixins, where the mixin type is a protocol class
5788
+ // that is used to decorate the "self" or "cls" parameter.
5789
+ if (bindToType &&
5790
+ types_1.ClassType.isProtocolClass(bindToType) &&
5791
+ effectiveTargetClass &&
5792
+ !types_1.ClassType.isSameGenericClass(bindToType, effectiveTargetClass)) {
5793
+ effectiveTargetClass = undefined;
5794
+ }
5836
5795
  const lookupResults = bindToType
5837
5796
  ? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
5838
5797
  : undefined;
@@ -6563,7 +6522,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6563
6522
  const result = {
6564
6523
  returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
6565
6524
  };
6566
- const initTypeResult = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(expandedCallType), '__init__');
6525
+ const initTypeResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, errorNode, types_1.ClassType.cloneAsInstance(expandedCallType),
6526
+ /* skipObjectBase */ false);
6567
6527
  if (initTypeResult && (0, types_1.isOverloadedFunction)(initTypeResult.type)) {
6568
6528
  validateOverloadedFunctionArguments(errorNode, argList, { type: initTypeResult.type },
6569
6529
  /* typeVarContext */ undefined, skipUnknownArgCheck,
@@ -6664,18 +6624,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6664
6624
  return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
6665
6625
  }
6666
6626
  function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
6667
- var _a, _b;
6668
- const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6627
+ var _a;
6628
+ const callMethodResult = getTypeOfBoundMember(errorNode, expandedCallType, '__call__',
6669
6629
  /* usage */ undefined,
6670
- /* diag */ undefined, 512 /* SkipAttributeAccessOverride */ | 16 /* SkipInstanceMembers */)) === null || _a === void 0 ? void 0 : _a.type;
6671
- if (!memberType) {
6630
+ /* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */,
6631
+ /* selfType */ undefined, recursionCount);
6632
+ const callMethodType = callMethodResult === null || callMethodResult === void 0 ? void 0 : callMethodResult.type;
6633
+ if (!callMethodType) {
6672
6634
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6673
6635
  type: printType(expandedCallType),
6674
6636
  }), errorNode);
6675
6637
  return { returnType: types_1.UnknownType.create(), argumentErrors: true };
6676
6638
  }
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();
6639
+ const callResult = validateCallArguments(errorNode, argList, { type: callMethodType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6640
+ let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
6679
6641
  if ((0, types_1.isTypeVar)(unexpandedCallType) &&
6680
6642
  types_1.TypeBase.isInstantiable(unexpandedCallType) &&
6681
6643
  (0, types_1.isClass)(expandedCallType) &&
@@ -6867,9 +6829,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6867
6829
  let paramIndex = 0;
6868
6830
  while (argIndex < positionalArgCount) {
6869
6831
  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;
6832
+ const nameNode = argList[argIndex].name;
6833
+ if (nameNode) {
6834
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(nameNode);
6835
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.argPositional(), nameNode);
6836
+ reportedArgError = true;
6837
+ }
6873
6838
  }
6874
6839
  const remainingArgCount = positionalArgCount - argIndex;
6875
6840
  const remainingParamCount = positionParamLimitIndex - paramIndex - 1;
@@ -6982,7 +6947,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6982
6947
  else {
6983
6948
  listElementType =
6984
6949
  (_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();
6950
+ /* isAsync */ false, errorNode,
6951
+ /* emitNotIterableError */ false)) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : types_1.UnknownType.create();
6986
6952
  if (paramDetails.params[paramIndex].param.category !== 1 /* ArgsList */) {
6987
6953
  matchedUnpackedListOfUnknownLength = true;
6988
6954
  }
@@ -8901,13 +8867,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8901
8867
  let magicMethodSupported = true;
8902
8868
  // Create a helper lambda for object subtypes.
8903
8869
  const handleSubtype = (subtype) => {
8904
- var _a;
8905
8870
  let magicMethodType;
8906
8871
  const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
8907
8872
  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;
8873
+ magicMethodType = getBoundMagicMethod(concreteSubtype, methodName, subtype);
8911
8874
  }
8912
8875
  if (magicMethodType) {
8913
8876
  const functionArgs = argList.map((arg) => {
@@ -8917,16 +8880,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8917
8880
  };
8918
8881
  });
8919
8882
  let callResult;
8920
- useSpeculativeMode(errorNode, () => {
8921
- callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8883
+ callResult = useSpeculativeMode(errorNode, () => {
8884
+ (0, debug_1.assert)(magicMethodType !== undefined);
8885
+ return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8922
8886
  /* typeVarContext */ undefined,
8923
8887
  /* skipUnknownArgCheck */ true, inferenceContext);
8924
8888
  });
8925
8889
  // If there were errors with the expected type, try
8926
8890
  // to evaluate without the expected type.
8927
8891
  if (callResult.argumentErrors && inferenceContext) {
8928
- useSpeculativeMode(errorNode, () => {
8929
- callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8892
+ callResult = useSpeculativeMode(errorNode, () => {
8893
+ (0, debug_1.assert)(magicMethodType !== undefined);
8894
+ return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
8930
8895
  /* typeVarContext */ undefined,
8931
8896
  /* skipUnknownArgCheck */ true);
8932
8897
  });
@@ -9569,7 +9534,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9569
9534
  expectedFunctionTypes.push(subtype);
9570
9535
  }
9571
9536
  if ((0, types_1.isClassInstance)(subtype)) {
9572
- const boundMethod = getBoundMethod(subtype, '__call__');
9537
+ const boundMethod = getBoundMagicMethod(subtype, '__call__');
9573
9538
  if (boundMethod && (0, types_1.isFunction)(boundMethod)) {
9574
9539
  expectedFunctionTypes.push(boundMethod);
9575
9540
  }
@@ -10452,6 +10417,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10452
10417
  let reportedUnpackedError = false;
10453
10418
  // Verify that we didn't receive any inappropriate types.
10454
10419
  typeArgs.forEach((typeArg, index) => {
10420
+ (0, debug_1.assert)(typeArgs !== undefined);
10455
10421
  if ((0, typeUtils_1.isEllipsisType)(typeArg.type)) {
10456
10422
  if (!isTupleTypeParam) {
10457
10423
  if (!allowParamSpec) {
@@ -10638,6 +10604,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10638
10604
  // with this type alias.
10639
10605
  typeParameters = [];
10640
10606
  (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10607
+ (0, debug_1.assert)(typeParameters !== undefined);
10641
10608
  (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10642
10609
  });
10643
10610
  // Don't include any synthesized type variables.
@@ -10654,6 +10621,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10654
10621
  // Validate the default types for all type parameters.
10655
10622
  typeParameters.forEach((typeParam, index) => {
10656
10623
  var _a;
10624
+ (0, debug_1.assert)(typeParameters !== undefined);
10657
10625
  let bestErrorNode = errorNode;
10658
10626
  if (typeParamNodes && index < typeParamNodes.length) {
10659
10627
  bestErrorNode = (_a = typeParamNodes[index].defaultExpression) !== null && _a !== void 0 ? _a : typeParamNodes[index].name;
@@ -10934,6 +10902,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10934
10902
  // If this is a type alias, record its name based on the assignment target.
10935
10903
  rightHandType = transformTypeForTypeAlias(rightHandType, typeAliasNameNode, node.rightExpression,
10936
10904
  /* isPep695Syntax */ false);
10905
+ (0, debug_1.assert)(typeAliasTypeVar !== undefined);
10937
10906
  if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, rightHandType)) {
10938
10907
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10939
10908
  name: typeAliasNameNode.value,
@@ -11650,6 +11619,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11650
11619
  if (p.details.isVariadic) {
11651
11620
  return p;
11652
11621
  }
11622
+ (0, debug_1.assert)(objectType !== undefined);
11653
11623
  return i === paramIndex ? objectType : dummyTypeObject;
11654
11624
  });
11655
11625
  // Replace all type arguments with a dummy type except for the
@@ -11818,6 +11788,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11818
11788
  computeEffectiveMetaclass(type, errorNode);
11819
11789
  }
11820
11790
  function validateInitSubclassArgs(node, classType) {
11791
+ var _a, _b;
11821
11792
  // Collect arguments that will be passed to the `__init_subclass__`
11822
11793
  // method described in PEP 487 and validate it.
11823
11794
  const argList = [];
@@ -11831,72 +11802,91 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11831
11802
  });
11832
11803
  }
11833
11804
  });
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)) {
11805
+ 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;
11806
+ let newMethodMember;
11807
+ if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
11849
11808
  // 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
- }
11809
+ newMethodMember = (0, typeUtils_1.lookUpClassMember)(classType.details.effectiveMetaclass, '__new__', 8 /* SkipTypeBaseClass */);
11810
+ }
11811
+ if (newMethodMember) {
11812
+ const newMethodType = getTypeOfMember(newMethodMember);
11813
+ if ((0, types_1.isFunction)(newMethodType)) {
11814
+ const paramListDetails = (0, parameterUtils_1.getParameterListDetails)(newMethodType);
11815
+ if (paramListDetails.firstKeywordOnlyIndex !== undefined) {
11816
+ // Build a map of the keyword-only parameters.
11817
+ const paramMap = new Map();
11818
+ for (let i = paramListDetails.firstKeywordOnlyIndex; i < paramListDetails.params.length; i++) {
11819
+ const paramInfo = paramListDetails.params[i];
11820
+ if (paramInfo.param.category === 0 /* Simple */ && paramInfo.param.name) {
11821
+ paramMap.set(paramInfo.param.name, i);
11863
11822
  }
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
- }
11823
+ }
11824
+ argList.forEach((arg) => {
11825
+ var _a, _b, _c;
11826
+ const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
11827
+ if (arg.argumentCategory === 0 /* Simple */ && arg.name) {
11828
+ const paramIndex = (_a = paramMap.get(arg.name.value)) !== null && _a !== void 0 ? _a : paramListDetails.kwargsIndex;
11829
+ if (paramIndex !== undefined) {
11830
+ const paramInfo = paramListDetails.params[paramIndex];
11831
+ const argParam = {
11832
+ paramCategory: paramInfo.param.category,
11833
+ paramType: types_1.FunctionType.getEffectiveParameterType(newMethodType, paramInfo.index),
11834
+ requiresTypeVarMatching: false,
11835
+ argument: arg,
11836
+ errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
11837
+ };
11838
+ validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
11839
+ paramMap.delete(arg.name.value);
11884
11840
  }
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);
11841
+ else {
11842
+ 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
11843
  }
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);
11844
+ }
11845
+ });
11846
+ // See if we have any remaining unmatched parameters without
11847
+ // default values.
11848
+ const unassignedParams = [];
11849
+ paramMap.forEach((index, paramName) => {
11850
+ const paramInfo = paramListDetails.params[index];
11851
+ if (!paramInfo.param.hasDefault) {
11852
+ unassignedParams.push(paramName);
11853
+ }
11854
+ });
11855
+ if (unassignedParams.length > 0) {
11856
+ const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
11857
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
11858
+ ? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
11859
+ : localize_1.Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), errorNode);
11860
+ }
11861
+ }
11862
+ }
11863
+ }
11864
+ else {
11865
+ // If there was no custom metaclass __new__ method, see if there is an __init_subclass__
11866
+ // method present somewhere in the class hierarchy.
11867
+ const initSubclassMethodInfo = getTypeOfBoundMember(errorNode, classType, '__init_subclass__',
11868
+ /* usage */ undefined,
11869
+ /* diag */ undefined, 32 /* SkipClassMembers */ |
11870
+ 1 /* SkipOriginalClass */ |
11871
+ 512 /* SkipAttributeAccessOverride */);
11872
+ if (initSubclassMethodInfo) {
11873
+ const initSubclassMethodType = initSubclassMethodInfo.type;
11874
+ if (initSubclassMethodType && initSubclassMethodInfo.classType) {
11875
+ const callResult = validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
11876
+ /* typeVarContext */ undefined,
11877
+ /* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(getNoneType()));
11878
+ if (callResult.argumentErrors) {
11879
+ const diag = addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.initSubclassCallFailed(), node.name);
11880
+ const initSubclassFunction = (0, types_1.isOverloadedFunction)(initSubclassMethodType)
11881
+ ? types_1.OverloadedFunctionType.getOverloads(initSubclassMethodType)[0]
11882
+ : initSubclassMethodType;
11883
+ const initSubclassDecl = (0, types_1.isFunction)(initSubclassFunction)
11884
+ ? initSubclassFunction.details.declaration
11885
+ : undefined;
11886
+ if (diag && initSubclassDecl) {
11887
+ diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.initSubclassLocation().format({
11888
+ name: printType((0, typeUtils_1.convertToInstance)(initSubclassMethodInfo.classType)),
11889
+ }), initSubclassDecl.path, initSubclassDecl.range);
11900
11890
  }
11901
11891
  }
11902
11892
  }
@@ -12060,7 +12050,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12060
12050
  // accumulate the list of type parameters upfront.
12061
12051
  const typeParametersSeen = [];
12062
12052
  if (node.typeParameters) {
12063
- functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
12053
+ functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters).map((typeParam) => (0, typeUtils_1.convertToInstance)(typeParam));
12064
12054
  }
12065
12055
  else {
12066
12056
  functionType.details.typeParameters = typeParametersSeen;
@@ -13945,6 +13935,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13945
13935
  else {
13946
13936
  // Avoid emitting this error for a partially-constructed class.
13947
13937
  if (!(0, types_1.isClassInstance)(typeArgType) || !types_1.ClassType.isPartiallyEvaluated(typeArgType)) {
13938
+ (0, debug_1.assert)(typeArgs !== undefined);
13948
13939
  const fileInfo = AnalyzerNodeInfo.getFileInfo(typeArgs[index].node);
13949
13940
  addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarAssignmentMismatch().format({
13950
13941
  type: printType(typeArgType),
@@ -13986,6 +13977,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13986
13977
  }
13987
13978
  // If there was no defined type provided, there should always
13988
13979
  // be a value expression from which we can retrieve the type.
13980
+ (0, debug_1.assert)(arg.valueExpression !== undefined);
13989
13981
  return getTypeOfExpressionExpectingType(arg.valueExpression, options);
13990
13982
  }
13991
13983
  function getTypeOfExpressionExpectingType(node, options) {
@@ -14371,8 +14363,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14371
14363
  });
14372
14364
  }
14373
14365
  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;
14366
+ 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
14367
  if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
14377
14368
  const paramDecl = getDeclarationFromFunctionNamedParameter(initMethodType, paramName);
14378
14369
  if (paramDecl) {
@@ -14754,6 +14745,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14754
14745
  // If the resolved declaration had no defined type, use the
14755
14746
  // inferred type for this node.
14756
14747
  if (resolvedDecl.type === 2 /* Parameter */) {
14748
+ (0, debug_1.assert)(resolvedDecl.node.name !== undefined);
14757
14749
  return (_b = evaluateTypeForSubnode(resolvedDecl.node.name, () => {
14758
14750
  evaluateTypeOfParameter(resolvedDecl.node);
14759
14751
  })) === null || _b === void 0 ? void 0 : _b.type;
@@ -14772,8 +14764,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14772
14764
  // See if this is an enum member. If so, we need to handle it as a special case.
14773
14765
  const enumMemberType = (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, resolvedDecl.node, () => {
14774
14766
  var _a, _b;
14775
- return ((_b = (_a = evaluateTypeForSubnode(resolvedDecl.inferredTypeSource, () => {
14776
- evaluateTypesForStatement(resolvedDecl.inferredTypeSource);
14767
+ (0, debug_1.assert)(resolvedDecl.inferredTypeSource !== undefined);
14768
+ const inferredTypeSource = resolvedDecl.inferredTypeSource;
14769
+ return ((_b = (_a = evaluateTypeForSubnode(inferredTypeSource, () => {
14770
+ evaluateTypesForStatement(inferredTypeSource);
14777
14771
  })) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create());
14778
14772
  });
14779
14773
  if (enumMemberType) {
@@ -15221,7 +15215,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15221
15215
  // the return type. If a list of args is provided, the inference logic may take
15222
15216
  // into account argument types to infer the return type.
15223
15217
  function getFunctionEffectiveReturnType(type, args, inferTypeIfNeeded = true) {
15224
- const specializedReturnType = types_1.FunctionType.getSpecializedReturnType(type);
15218
+ const specializedReturnType = types_1.FunctionType.getSpecializedReturnType(type, /* includeInferred */ false);
15225
15219
  if (specializedReturnType) {
15226
15220
  return adjustCallableReturnType(specializedReturnType, /* trackedSignatures */ undefined);
15227
15221
  }
@@ -15544,8 +15538,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15544
15538
  // derive from the source. We also need to use this path if we're
15545
15539
  // testing to see if the metaclass matches the protocol.
15546
15540
  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)) {
15541
+ 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
15542
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.protocolIncompatible().format({
15550
15543
  sourceType: printType((0, typeUtils_1.convertToInstance)(srcType)),
15551
15544
  destType: printType((0, typeUtils_1.convertToInstance)(destType)),
@@ -15797,9 +15790,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15797
15790
  for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) {
15798
15791
  const ancestorType = inheritanceChain[ancestorIndex];
15799
15792
  // If we've hit an "unknown", all bets are off, and we need to assume
15800
- // that the type is assignable.
15793
+ // that the type is assignable. If the destType is marked "@final",
15794
+ // we should be able to assume that it's not assignable, but we can't do
15795
+ // this in the general case because it breaks assumptions with the
15796
+ // NotImplemented symbol exported by typeshed's builtins.pyi. Instead,
15797
+ // we'll special-case only None.
15801
15798
  if ((0, types_1.isUnknown)(ancestorType)) {
15802
- return true;
15799
+ return !(0, typeUtils_1.isNoneTypeClass)(destType);
15803
15800
  }
15804
15801
  // If this isn't the first time through the loop, specialize
15805
15802
  // for the next ancestor in the chain.
@@ -15852,24 +15849,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15852
15849
  const srcTypeArgs = curSrcType.typeArguments;
15853
15850
  for (let i = 0; i < destType.details.typeParameters.length; i++) {
15854
15851
  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);
15852
+ const typeParam = destType.details.typeParameters[i];
15853
+ const variance = types_1.TypeVarType.getVariance(typeParam);
15854
+ (0, constraintSolver_1.updateTypeVarType)(evaluatorInterface, destTypeVarContext, typeParam, variance !== 4 /* Contravariant */ ? typeArgType : undefined, variance !== 3 /* Covariant */ ? typeArgType : undefined,
15855
+ /* forceRetainLiterals */ true);
15858
15856
  }
15859
15857
  }
15860
15858
  return true;
15861
15859
  }
15862
15860
  function getGetterTypeFromProperty(propertyClass, inferTypeIfNeeded) {
15863
- var _a;
15864
15861
  if (!types_1.ClassType.isPropertyClass(propertyClass)) {
15865
15862
  return undefined;
15866
15863
  }
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
- }
15864
+ if (propertyClass.fgetFunction) {
15865
+ return getFunctionEffectiveReturnType(propertyClass.fgetFunction, /* args */ undefined, inferTypeIfNeeded);
15873
15866
  }
15874
15867
  return undefined;
15875
15868
  }
@@ -16390,8 +16383,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16390
16383
  // If the destType is an instantiation of a Protocol,
16391
16384
  // see if the class type itself satisfies the protocol.
16392
16385
  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);
16386
+ return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16395
16387
  }
16396
16388
  // Determine if the metaclass can be assigned to the object.
16397
16389
  const metaclass = concreteSrcType.details.effectiveMetaclass;
@@ -16415,14 +16407,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16415
16407
  if ((0, types_1.isFunction)(destType)) {
16416
16408
  let concreteSrcType = makeTopLevelTypeVarsConcrete(srcType);
16417
16409
  if ((0, types_1.isClassInstance)(concreteSrcType)) {
16418
- const boundMethod = getBoundMethod(concreteSrcType, '__call__', recursionCount);
16410
+ const boundMethod = getBoundMagicMethod(concreteSrcType, '__call__',
16411
+ /* selfType */ undefined, recursionCount);
16419
16412
  if (boundMethod) {
16420
16413
  concreteSrcType = (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
16421
16414
  }
16422
16415
  }
16423
16416
  // If it's a class, use the constructor for type compatibility checking.
16424
16417
  if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
16425
- const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
16418
+ const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, (0, types_1.isTypeVar)(srcType) ? (0, typeUtils_1.convertToInstance)(srcType) : undefined, recursionCount);
16426
16419
  if (constructor) {
16427
16420
  concreteSrcType = constructor;
16428
16421
  }
@@ -16517,8 +16510,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16517
16510
  // Are we trying to assign None to a protocol?
16518
16511
  if ((0, typeUtils_1.isNoneInstance)(srcType) && (0, types_1.isClassInstance)(destType) && types_1.ClassType.isProtocolClass(destType)) {
16519
16512
  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);
16513
+ return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), types_1.ClassType.cloneAsInstance(noneClassType), diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
16522
16514
  }
16523
16515
  }
16524
16516
  if ((0, typeUtils_1.isNoneInstance)(destType)) {
@@ -16907,7 +16899,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16907
16899
  }
16908
16900
  }
16909
16901
  }
16910
- const boundMethod = getBoundMethod(objType, '__call__', recursionCount);
16902
+ const boundMethod = getBoundMagicMethod(objType, '__call__', /* selfType */ undefined, recursionCount);
16911
16903
  if (boundMethod) {
16912
16904
  return (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
16913
16905
  }
@@ -16993,7 +16985,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16993
16985
  if (srcDetails.params.length < destDetails.argsIndex) {
16994
16986
  return;
16995
16987
  }
16996
- let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly);
16988
+ let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => {
16989
+ (0, debug_1.assert)(destDetails.argsIndex !== undefined);
16990
+ return i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly;
16991
+ });
16997
16992
  if (srcLastToPackIndex < 0) {
16998
16993
  srcLastToPackIndex = srcDetails.params.length;
16999
16994
  }
@@ -17655,7 +17650,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17655
17650
  matchIndex = possibleMatchIndex;
17656
17651
  }
17657
17652
  if (matchIndex < 0) {
17658
- continue;
17653
+ break;
17659
17654
  }
17660
17655
  if (matchIndex < previousMatchIndex) {
17661
17656
  diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadOrder());
@@ -18109,14 +18104,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18109
18104
  });
18110
18105
  return methodList;
18111
18106
  }
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
18107
  // If the memberType is an instance or class method, creates a new
18121
18108
  // version of the function that has the "self" or "cls" parameter bound
18122
18109
  // to it. If treatConstructorAsClassMember is true, the function is
@@ -18135,9 +18122,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18135
18122
  if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
18136
18123
  return functionType;
18137
18124
  }
18138
- const baseObj = (0, types_1.isInstantiableClass)(baseType)
18139
- ? types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType))
18140
- : baseType;
18125
+ const baseObj = (0, types_1.isClassInstance)(baseType)
18126
+ ? baseType
18127
+ : types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType));
18141
18128
  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
18129
  /* stripFirstParam */ (0, types_1.isClassInstance)(baseType));
18143
18130
  }
@@ -18444,8 +18431,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
18444
18431
  getBestOverloadForArguments,
18445
18432
  getBuiltInType,
18446
18433
  getTypeOfMember,
18447
- getTypeOfObjectMember,
18448
- getBoundMethod,
18434
+ getTypeOfBoundMember,
18435
+ getBoundMagicMethod,
18449
18436
  getTypeOfMagicMethodCall,
18450
18437
  bindFunctionToClassOrObject,
18451
18438
  getCallSignatureInfo,