@zzzen/pyright-internal 1.2.0-dev.20250316 → 1.2.0-dev.20250323

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 (90) hide show
  1. package/dist/analyzer/analyzerFileInfo.d.ts +1 -0
  2. package/dist/analyzer/analyzerFileInfo.js.map +1 -1
  3. package/dist/analyzer/binder.js +20 -12
  4. package/dist/analyzer/binder.js.map +1 -1
  5. package/dist/analyzer/checker.d.ts +3 -0
  6. package/dist/analyzer/checker.js +58 -9
  7. package/dist/analyzer/checker.js.map +1 -1
  8. package/dist/analyzer/codeFlowTypes.d.ts +2 -2
  9. package/dist/analyzer/codeFlowTypes.js +9 -0
  10. package/dist/analyzer/codeFlowTypes.js.map +1 -1
  11. package/dist/analyzer/constructorTransform.js +1 -1
  12. package/dist/analyzer/constructorTransform.js.map +1 -1
  13. package/dist/analyzer/constructors.js +7 -1
  14. package/dist/analyzer/constructors.js.map +1 -1
  15. package/dist/analyzer/importResolver.d.ts +2 -0
  16. package/dist/analyzer/importResolver.js +29 -6
  17. package/dist/analyzer/importResolver.js.map +1 -1
  18. package/dist/analyzer/importResult.d.ts +1 -0
  19. package/dist/analyzer/parameterUtils.d.ts +15 -0
  20. package/dist/analyzer/parameterUtils.js +59 -1
  21. package/dist/analyzer/parameterUtils.js.map +1 -1
  22. package/dist/analyzer/parseTreeUtils.d.ts +2 -0
  23. package/dist/analyzer/parseTreeUtils.js +19 -0
  24. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  25. package/dist/analyzer/program.js +17 -4
  26. package/dist/analyzer/program.js.map +1 -1
  27. package/dist/analyzer/programTypes.d.ts +2 -2
  28. package/dist/analyzer/programTypes.js.map +1 -1
  29. package/dist/analyzer/service.d.ts +1 -3
  30. package/dist/analyzer/service.js +1 -3
  31. package/dist/analyzer/service.js.map +1 -1
  32. package/dist/analyzer/sourceFile.d.ts +2 -1
  33. package/dist/analyzer/sourceFile.js +3 -1
  34. package/dist/analyzer/sourceFile.js.map +1 -1
  35. package/dist/analyzer/typeEvaluator.js +156 -200
  36. package/dist/analyzer/typeEvaluator.js.map +1 -1
  37. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
  38. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  39. package/dist/analyzer/typeUtils.js +8 -7
  40. package/dist/analyzer/typeUtils.js.map +1 -1
  41. package/dist/analyzer/typeWalker.js +1 -1
  42. package/dist/analyzer/typeWalker.js.map +1 -1
  43. package/dist/analyzer/types.d.ts +6 -5
  44. package/dist/analyzer/types.js +15 -23
  45. package/dist/analyzer/types.js.map +1 -1
  46. package/dist/common/cancellationUtils.d.ts +3 -0
  47. package/dist/common/cancellationUtils.js +8 -1
  48. package/dist/common/cancellationUtils.js.map +1 -1
  49. package/dist/common/languageServerInterface.d.ts +0 -2
  50. package/dist/common/languageServerInterface.js.map +1 -1
  51. package/dist/common/serviceKeys.d.ts +2 -0
  52. package/dist/common/serviceKeys.js +1 -0
  53. package/dist/common/serviceKeys.js.map +1 -1
  54. package/dist/common/serviceProviderExtensions.d.ts +2 -0
  55. package/dist/common/serviceProviderExtensions.js +9 -2
  56. package/dist/common/serviceProviderExtensions.js.map +1 -1
  57. package/dist/languageServerBase.js +2 -3
  58. package/dist/languageServerBase.js.map +1 -1
  59. package/dist/languageService/tooltipUtils.js +2 -2
  60. package/dist/languageService/tooltipUtils.js.map +1 -1
  61. package/dist/localization/package.nls.cs.json +1 -1
  62. package/dist/localization/package.nls.de.json +1 -1
  63. package/dist/localization/package.nls.es.json +1 -1
  64. package/dist/localization/package.nls.fr.json +1 -1
  65. package/dist/localization/package.nls.it.json +1 -1
  66. package/dist/localization/package.nls.ja.json +1 -1
  67. package/dist/localization/package.nls.ko.json +1 -1
  68. package/dist/localization/package.nls.pl.json +1 -1
  69. package/dist/localization/package.nls.pt-br.json +1 -1
  70. package/dist/localization/package.nls.ru.json +1 -1
  71. package/dist/localization/package.nls.tr.json +1 -1
  72. package/dist/localization/package.nls.zh-cn.json +1 -1
  73. package/dist/localization/package.nls.zh-tw.json +1 -1
  74. package/dist/readonlyAugmentedFileSystem.js +4 -0
  75. package/dist/readonlyAugmentedFileSystem.js.map +1 -1
  76. package/dist/server.js +1 -2
  77. package/dist/server.js.map +1 -1
  78. package/dist/tests/checker.test.js +11 -0
  79. package/dist/tests/checker.test.js.map +1 -1
  80. package/dist/tests/fourslash/import.pytyped.privateSymbols.fourslash.js +18 -0
  81. package/dist/tests/fourslash/import.pytyped.privateSymbols.fourslash.js.map +1 -1
  82. package/dist/tests/languageServer.test.js +2 -2
  83. package/dist/tests/sourceFile.test.js +5 -4
  84. package/dist/tests/sourceFile.test.js.map +1 -1
  85. package/dist/tests/typeEvaluator1.test.js +5 -1
  86. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  87. package/dist/tests/typeEvaluator4.test.js +1 -1
  88. package/dist/tests/typeEvaluator5.test.js +1 -1
  89. package/dist/tests/typeEvaluator6.test.js +1 -1
  90. package/package.json +1 -1
@@ -142,6 +142,10 @@ const maxCallSiteReturnTypeCacheSize = 8;
142
142
  // when inferring the type? We need to cut it off at some point
143
143
  // to avoid excessive computation.
144
144
  const maxEntriesToUseForInference = 64;
145
+ // How many times should attempt to infer a return type of a
146
+ // function before giving up and assuming that it won't converge
147
+ // due to recursion?
148
+ const maxReturnTypeInferenceAttempts = 8;
145
149
  // How many assignments to an unannotated variable should be used
146
150
  // when inferring its type? We need to cut it off at some point
147
151
  // to avoid excessive computation.
@@ -2355,7 +2359,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
2355
2359
  }
2356
2360
  else {
2357
2361
  // Constrain the resulting type to match the declared type.
2358
- destType = narrowTypeBasedOnAssignment(nameNode, declaredType, typeResult).type;
2362
+ destType = narrowTypeBasedOnAssignment(declaredType, typeResult).type;
2359
2363
  }
2360
2364
  }
2361
2365
  else {
@@ -2950,7 +2954,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
2950
2954
  // is a enum because the annotated type in an enum doesn't reflect
2951
2955
  // the type of the symbol.
2952
2956
  if (!(0, types_1.isClassInstance)(typeResult.type) || !types_1.ClassType.isEnumClass(typeResult.type)) {
2953
- typeResult = narrowTypeBasedOnAssignment(target, annotationType, typeResult);
2957
+ typeResult = narrowTypeBasedOnAssignment(annotationType, typeResult);
2954
2958
  }
2955
2959
  }
2956
2960
  }
@@ -3958,8 +3962,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
3958
3962
  if (isModuleGetAttrSupported) {
3959
3963
  const getAttrTypeResult = getEffectiveTypeOfSymbolForUsage(getAttrSymbol);
3960
3964
  if ((0, types_1.isFunction)(getAttrTypeResult.type)) {
3961
- type = getEffectiveReturnType(getAttrTypeResult.type);
3962
- if (getAttrTypeResult.isIncomplete) {
3965
+ const returnTypeResult = getEffectiveReturnTypeResult(getAttrTypeResult.type);
3966
+ type = returnTypeResult.type;
3967
+ if (getAttrTypeResult.isIncomplete || returnTypeResult.isIncomplete) {
3963
3968
  isIncomplete = true;
3964
3969
  }
3965
3970
  }
@@ -4310,7 +4315,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
4310
4315
  // descriptor-based accesses.
4311
4316
  narrowedTypeForSet = isDescriptorApplied
4312
4317
  ? usage.setType.type
4313
- : narrowTypeBasedOnAssignment(errorNode, type, usage.setType).type;
4318
+ : narrowTypeBasedOnAssignment(type, usage.setType).type;
4314
4319
  }
4315
4320
  // Verify that the assigned type is compatible.
4316
4321
  if (!assignType(type, usage.setType.type, diag?.createAddendum())) {
@@ -6399,7 +6404,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6399
6404
  // list will grow to include union expansions.
6400
6405
  function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
6401
6406
  const returnTypes = [];
6402
- const matchedOverloads = [];
6407
+ let matchedOverloads = [];
6403
6408
  let isTypeIncomplete = false;
6404
6409
  let overloadsUsedForCall = [];
6405
6410
  let isDefinitiveMatchFound = false;
@@ -6447,10 +6452,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6447
6452
  argResults: callResult.argResults ?? [],
6448
6453
  };
6449
6454
  matchedOverloads.push(matchedOverloadInfo);
6450
- if (callResult.anyOrUnknownArg) {
6455
+ if (callResult.anyOrUnknownArg || matchResults.unpackedArgOfUnknownLength) {
6451
6456
  possibleMatchResults.push(matchedOverloadInfo);
6452
- if ((0, typeUtils_1.isIncompleteUnknown)(callResult.anyOrUnknownArg)) {
6453
- possibleMatchInvolvesIncompleteUnknown = true;
6457
+ if (callResult.anyOrUnknownArg) {
6458
+ if ((0, typeUtils_1.isIncompleteUnknown)(callResult.anyOrUnknownArg)) {
6459
+ possibleMatchInvolvesIncompleteUnknown = true;
6460
+ }
6454
6461
  }
6455
6462
  }
6456
6463
  else {
@@ -6466,11 +6473,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6466
6473
  // Unknown, but include the "possible types" to allow for completion
6467
6474
  // suggestions.
6468
6475
  if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
6476
+ possibleMatchResults = filterOverloadMatchesForUnpackedArgs(possibleMatchResults);
6469
6477
  possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
6470
6478
  // Did the filtering produce a single result? If so, we're done.
6471
6479
  if (possibleMatchResults.length === 1) {
6472
6480
  overloadsUsedForCall = [possibleMatchResults[0].overload];
6473
6481
  returnTypes.push(possibleMatchResults[0].returnType);
6482
+ matchedOverloads = [possibleMatchResults[0]];
6474
6483
  }
6475
6484
  else {
6476
6485
  // Eliminate any return types that are subsumed by other return types.
@@ -6551,21 +6560,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6551
6560
  overloadsUsedForCall,
6552
6561
  };
6553
6562
  }
6554
- // This function determines whether multiple incompatible overloads match
6563
+ // Determines whether one or more overloads can be eliminated because they
6564
+ // rely on an unpacked argument of unknown length when there is at least
6565
+ // one overload that doesn't because it maps to an *args parameter.
6566
+ function filterOverloadMatchesForUnpackedArgs(matches) {
6567
+ if (matches.length < 2) {
6568
+ return matches;
6569
+ }
6570
+ // Is there at least one overload that relies on unpacked args for a match?
6571
+ const unpackedArgsOverloads = matches.filter((match) => match.matchResults.unpackedArgMapsToVariadic);
6572
+ if (unpackedArgsOverloads.length === matches.length || unpackedArgsOverloads.length === 0) {
6573
+ return matches;
6574
+ }
6575
+ return unpackedArgsOverloads;
6576
+ }
6577
+ // Determines whether multiple incompatible overloads match
6555
6578
  // due to an Any or Unknown argument type.
6556
6579
  function filterOverloadMatchesForAnyArgs(matches) {
6557
6580
  if (matches.length < 2) {
6558
6581
  return matches;
6559
6582
  }
6560
- // If the relevance of some matches differs, filter out the ones that
6561
- // are lower relevance. This favors *args parameters in cases where
6562
- // a *args argument is used.
6563
- if (matches[0].matchResults.relevance !== matches[matches.length - 1].matchResults.relevance) {
6564
- matches = matches.filter((m) => m.matchResults.relevance === matches[0].matchResults.relevance);
6565
- if (matches.length < 2) {
6566
- return matches;
6567
- }
6568
- }
6569
6583
  // If all of the return types match, select the first one.
6570
6584
  if ((0, typeUtils_1.areTypesSame)(matches.map((match) => match.returnType), { treatAnySameAsUnknown: true })) {
6571
6585
  return [matches[0]];
@@ -6599,7 +6613,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6599
6613
  }
6600
6614
  function getBestOverloadForArgs(errorNode, typeResult, argList) {
6601
6615
  let overloadIndex = 0;
6602
- let matches = [];
6616
+ const matches = [];
6603
6617
  const speculativeNode = getSpeculativeNodeForCall(errorNode);
6604
6618
  useSignatureTracker(errorNode, () => {
6605
6619
  // Create a list of potential overload matches based on arguments.
@@ -6613,7 +6627,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6613
6627
  });
6614
6628
  });
6615
6629
  });
6616
- matches = sortOverloadsByBestMatch(matches);
6617
6630
  let winningOverloadIndex;
6618
6631
  matches.forEach((match, matchIndex) => {
6619
6632
  if (winningOverloadIndex === undefined) {
@@ -6628,17 +6641,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6628
6641
  });
6629
6642
  return winningOverloadIndex === undefined ? undefined : matches[winningOverloadIndex].overload;
6630
6643
  }
6631
- // Sorts the list of overloads based first on "relevance" and second on order.
6632
- function sortOverloadsByBestMatch(matches) {
6633
- return matches.sort((a, b) => {
6634
- if (a.relevance !== b.relevance) {
6635
- return b.relevance - a.relevance;
6636
- }
6637
- return a.overloadIndex - b.overloadIndex;
6638
- });
6639
- }
6640
6644
  function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext) {
6641
- let filteredMatchResults = [];
6645
+ const filteredMatchResults = [];
6642
6646
  let contextFreeArgTypes;
6643
6647
  let isTypeIncomplete = !!typeResult.isIncomplete;
6644
6648
  const type = typeResult.type;
@@ -6661,7 +6665,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6661
6665
  overloadIndex++;
6662
6666
  });
6663
6667
  });
6664
- filteredMatchResults = sortOverloadsByBestMatch(filteredMatchResults);
6665
6668
  // If there are no possible arg/param matches among the overloads,
6666
6669
  // emit an error that includes the argument types.
6667
6670
  if (filteredMatchResults.length === 0) {
@@ -6920,6 +6923,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6920
6923
  case 6 /* TypeCategory.Class */: {
6921
6924
  if ((0, typeUtils_1.isNoneInstance)(expandedCallType)) {
6922
6925
  addDiagnostic(diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.LocMessage.noneNotCallable(), errorNode);
6926
+ touchArgTypes();
6923
6927
  return { argumentErrors: true };
6924
6928
  }
6925
6929
  if (types_1.TypeBase.isInstantiable(expandedCallType)) {
@@ -6936,6 +6940,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6936
6940
  }
6937
6941
  case 7 /* TypeCategory.Module */: {
6938
6942
  addDiagnostic(diagnosticRules_1.DiagnosticRule.reportCallIssue, localize_1.LocMessage.moduleNotCallable(), errorNode);
6943
+ touchArgTypes();
6939
6944
  return { argumentErrors: true };
6940
6945
  }
6941
6946
  }
@@ -7398,25 +7403,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7398
7403
  const paramDetails = (0, parameterUtils_1.getParamListDetails)(overload, { disallowExtraKwargsForTd: true });
7399
7404
  const paramSpec = types_1.FunctionType.getParamSpecFromArgsKwargs(overload);
7400
7405
  let argIndex = 0;
7401
- let matchedUnpackedListOfUnknownLength = false;
7406
+ let unpackedArgOfUnknownLength = false;
7407
+ let unpackedArgMapsToVariadic = false;
7402
7408
  let reportedArgError = false;
7403
7409
  let isTypeIncomplete = !!typeResult.isIncomplete;
7404
7410
  let isTypeVarTupleFullyMatched = false;
7405
7411
  // Expand any unpacked tuples in the arg list.
7406
7412
  argList = expandArgList(argList);
7407
- // Build a map of parameters by name.
7408
- const paramMap = new Map();
7409
- paramDetails.params.forEach((paramInfo) => {
7410
- (0, debug_1.assert)(paramInfo !== undefined, 'paramInfo is undefined for param name map');
7411
- const param = paramInfo.param;
7412
- if (param.name && param.category === 0 /* ParamCategory.Simple */ && paramInfo.kind !== parameterUtils_1.ParamKind.Positional) {
7413
- let argsNeeded = paramMap.get(param.name)?.argsNeeded ?? 0;
7414
- if (param.category === 0 /* ParamCategory.Simple */ && !paramInfo.defaultType) {
7415
- argsNeeded += 1;
7416
- }
7417
- paramMap.set(param.name, { argsNeeded, argsReceived: 0 });
7418
- }
7419
- });
7413
+ // Construct an object that racks which parameters have been assigned arguments.
7414
+ const paramTracker = new parameterUtils_1.ParamAssignmentTracker(paramDetails.params);
7420
7415
  let positionalOnlyLimitIndex = paramDetails.positionOnlyParamCount;
7421
7416
  let positionParamLimitIndex = paramDetails.firstKeywordOnlyIndex ?? paramDetails.params.length;
7422
7417
  const varArgListParamIndex = paramDetails.argsIndex;
@@ -7535,6 +7530,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7535
7530
  argType.priv.tupleTypeArgs.length > 0) {
7536
7531
  tooManyPositionals = true;
7537
7532
  }
7533
+ else {
7534
+ unpackedArgOfUnknownLength = true;
7535
+ }
7538
7536
  }
7539
7537
  else {
7540
7538
  tooManyPositionals = true;
@@ -7627,8 +7625,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7627
7625
  if (!listElementType) {
7628
7626
  enforceIterable = true;
7629
7627
  }
7628
+ unpackedArgOfUnknownLength = true;
7630
7629
  if (paramInfo.param.category === 1 /* ParamCategory.ArgsList */) {
7631
- matchedUnpackedListOfUnknownLength = true;
7630
+ unpackedArgMapsToVariadic = true;
7632
7631
  }
7633
7632
  if (isParamVariadic && listElementType) {
7634
7633
  isArgCompatibleWithVariadic = true;
@@ -7672,10 +7671,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7672
7671
  }
7673
7672
  trySetActive(argList[argIndex], paramDetails.params[paramIndex].param);
7674
7673
  // Note that the parameter has received an argument.
7675
- if (paramName &&
7676
- paramDetails.params[paramIndex].param.category === 0 /* ParamCategory.Simple */ &&
7677
- paramMap.has(paramName)) {
7678
- paramMap.get(paramName).argsReceived++;
7674
+ if (paramName && paramDetails.params[paramIndex].param.category === 0 /* ParamCategory.Simple */) {
7675
+ paramTracker.markArgReceived(paramInfo);
7679
7676
  }
7680
7677
  if (advanceToNextArg || paramDetails.params[paramIndex].param.category === 1 /* ParamCategory.ArgsList */) {
7681
7678
  argIndex++;
@@ -7744,9 +7741,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7744
7741
  });
7745
7742
  trySetActive(argList[argIndex], paramInfo.param);
7746
7743
  // Note that the parameter has received an argument.
7747
- if (paramName && paramMap.has(paramName) && paramInfo.kind !== parameterUtils_1.ParamKind.Positional) {
7748
- paramMap.get(paramName).argsReceived++;
7749
- }
7744
+ paramTracker.markArgReceived(paramInfo);
7750
7745
  argIndex++;
7751
7746
  paramIndex++;
7752
7747
  }
@@ -7820,7 +7815,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7820
7815
  const tdEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface, argType);
7821
7816
  const diag = new diagnostic_1.DiagnosticAddendum();
7822
7817
  tdEntries.knownItems.forEach((entry, name) => {
7823
- const paramEntry = paramMap.get(name);
7818
+ const paramEntry = paramTracker.lookupName(name);
7824
7819
  if (paramEntry) {
7825
7820
  if (paramEntry.argsReceived > 0) {
7826
7821
  diag.addMessage(localize_1.LocMessage.paramAlreadyAssigned().format({ name }));
@@ -7857,10 +7852,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7857
7852
  paramName: name,
7858
7853
  });
7859
7854
  // Remember that this parameter has already received a value.
7860
- paramMap.set(name, {
7861
- argsNeeded: 1,
7862
- argsReceived: 1,
7863
- });
7855
+ paramTracker.addKeywordParam(name, paramDetails.params[paramDetails.kwargsIndex]);
7864
7856
  }
7865
7857
  else {
7866
7858
  // If the function doesn't have a **kwargs parameter, we need to emit an error.
@@ -7946,6 +7938,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7946
7938
  unpackedDictArgType = types_1.UnknownType.create();
7947
7939
  }
7948
7940
  }
7941
+ unpackedArgOfUnknownLength = true;
7949
7942
  if (paramDetails.kwargsIndex !== undefined && unpackedDictArgType) {
7950
7943
  const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
7951
7944
  validateArgTypeParams.push({
@@ -7957,6 +7950,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7957
7950
  errorNode: argList[argIndex].valueExpression || errorNode,
7958
7951
  paramName: paramDetails.params[paramDetails.kwargsIndex].param.name,
7959
7952
  });
7953
+ unpackedArgMapsToVariadic = true;
7960
7954
  }
7961
7955
  if (!isValidMappingType) {
7962
7956
  if (!canSkipDiagnosticForNode(errorNode) && !isTypeIncomplete) {
@@ -7977,7 +7971,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7977
7971
  const paramName = argList[argIndex].name;
7978
7972
  if (paramName) {
7979
7973
  const paramNameValue = paramName.d.value;
7980
- const paramEntry = paramMap.get(paramNameValue);
7974
+ const paramEntry = paramTracker.lookupName(paramNameValue);
7981
7975
  if (paramEntry) {
7982
7976
  if (paramEntry.argsReceived > 0) {
7983
7977
  if (!canSkipDiagnosticForNode(errorNode) && !isTypeIncomplete) {
@@ -8022,12 +8016,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8022
8016
  errorNode: argList[argIndex].valueExpression ?? errorNode,
8023
8017
  paramName: paramNameValue,
8024
8018
  });
8025
- // Remember that this parameter has already received a value.
8026
- paramMap.set(paramNameValue, {
8027
- argsNeeded: 1,
8028
- argsReceived: 1,
8029
- });
8030
8019
  (0, debug_1.assert)(paramDetails.params[paramDetails.kwargsIndex], 'paramDetails.kwargsIndex params entry is undefined');
8020
+ // Remember that this parameter has already received a value.
8021
+ paramTracker.addKeywordParam(paramNameValue, paramDetails.params[paramDetails.kwargsIndex]);
8031
8022
  }
8032
8023
  trySetActive(argList[argIndex], paramDetails.params[paramDetails.kwargsIndex].param);
8033
8024
  }
@@ -8088,8 +8079,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8088
8079
  if (paramIndex >= paramDetails.firstPositionOrKeywordIndex &&
8089
8080
  param.category === 0 /* ParamCategory.Simple */ &&
8090
8081
  param.name &&
8091
- paramMap.has(param.name) &&
8092
- paramMap.get(param.name).argsReceived === 0) {
8082
+ paramTracker.lookupDetails(paramInfo).argsReceived === 0) {
8093
8083
  const paramType = paramDetails.params[paramIndex].type;
8094
8084
  if (!unpackedDictKeyNames || unpackedDictKeyNames.includes(param.name)) {
8095
8085
  validateArgTypeParams.push({
@@ -8105,7 +8095,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8105
8095
  paramName: param.name,
8106
8096
  isParamNameSynthesized: types_1.FunctionParam.isNameSynthesized(param),
8107
8097
  });
8108
- paramMap.get(param.name).argsReceived = 1;
8098
+ paramTracker.markArgReceived(paramDetails.params[paramIndex]);
8109
8099
  }
8110
8100
  }
8111
8101
  });
@@ -8115,10 +8105,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8115
8105
  // (i.e. an arg starting with a "**"), we will assume that all parameters
8116
8106
  // are matched.
8117
8107
  if (!unpackedDictArgType && !types_1.FunctionType.isDefaultParamCheckDisabled(overload)) {
8118
- const unassignedParams = Array.from(paramMap.keys()).filter((name) => {
8119
- const entry = paramMap.get(name);
8120
- return !entry || entry.argsReceived < entry.argsNeeded;
8121
- });
8108
+ const unassignedParams = paramTracker.getUnassignedParams();
8122
8109
  if (unassignedParams.length > 0) {
8123
8110
  if (!canSkipDiagnosticForNode(errorNode)) {
8124
8111
  const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
@@ -8138,8 +8125,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8138
8125
  paramDetails.params.forEach((paramInfo) => {
8139
8126
  const param = paramInfo.param;
8140
8127
  if (param.category === 0 /* ParamCategory.Simple */ && param.name) {
8141
- const entry = paramMap.get(param.name);
8142
- if (entry && entry.argsNeeded === 0 && entry.argsReceived === 0) {
8128
+ const entry = paramTracker.lookupDetails(paramInfo);
8129
+ if (entry.argsNeeded === 0 && entry.argsReceived === 0) {
8143
8130
  const defaultArgType = paramInfo.defaultType;
8144
8131
  if (defaultArgType &&
8145
8132
  !(0, typeUtils_1.isEllipsisType)(defaultArgType) &&
@@ -8230,13 +8217,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8230
8217
  }
8231
8218
  }
8232
8219
  }
8233
- let relevance = 0;
8234
- if (matchedUnpackedListOfUnknownLength) {
8235
- // Increase the relevance if we made assumptions about the length
8236
- // of an unpacked argument. This will favor overloads that
8237
- // associate this case with a *args parameter.
8238
- relevance++;
8239
- }
8240
8220
  // Special-case the builtin isinstance and issubclass functions.
8241
8221
  if (types_1.FunctionType.isBuiltIn(overload, ['isinstance', 'issubclass']) && validateArgTypeParams.length === 2) {
8242
8222
  validateArgTypeParams[1].isinstanceParam = true;
@@ -8250,7 +8230,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8250
8230
  paramSpecTarget,
8251
8231
  paramSpecArgList,
8252
8232
  activeParam,
8253
- relevance,
8233
+ unpackedArgOfUnknownLength,
8234
+ unpackedArgMapsToVariadic,
8254
8235
  argumentMatchScore: 0,
8255
8236
  };
8256
8237
  }
@@ -8505,9 +8486,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8505
8486
  }
8506
8487
  }
8507
8488
  // Calculate the return type.
8508
- let returnType = getEffectiveReturnType(type, {
8489
+ const returnTypeResult = getEffectiveReturnTypeResult(type, {
8509
8490
  callSiteInfo: { args: matchResults.argParams, errorNode },
8510
8491
  });
8492
+ let returnType = returnTypeResult.type;
8493
+ if (returnTypeResult.isIncomplete) {
8494
+ isTypeIncomplete = true;
8495
+ }
8511
8496
  if (condition.length > 0) {
8512
8497
  returnType = types_1.TypeBase.cloneForCondition(returnType, condition);
8513
8498
  }
@@ -8766,9 +8751,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8766
8751
  else {
8767
8752
  skippedBareTypeVarExpectedType = true;
8768
8753
  }
8769
- // If the expected type is Any, don't use an expected type. Instead,
8754
+ // If the expected type is unknown, don't use an expected type. Instead,
8770
8755
  // use default rules for evaluating the expression type.
8771
- if (expectedType && (0, types_1.isAnyOrUnknown)(expectedType)) {
8756
+ if (expectedType && (0, types_1.isUnknown)(expectedType)) {
8772
8757
  expectedType = undefined;
8773
8758
  }
8774
8759
  // Was the argument's type precomputed by the caller?
@@ -10423,7 +10408,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
10423
10408
  : undefined, () => {
10424
10409
  const returnTypeResult = getTypeOfExpression(node.d.expr,
10425
10410
  /* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType));
10426
- functionType.priv.inferredReturnType = {
10411
+ functionType.shared.inferredReturnType = {
10427
10412
  type: returnTypeResult.type,
10428
10413
  };
10429
10414
  if (returnTypeResult.isIncomplete) {
@@ -13569,7 +13554,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
13569
13554
  awaitableFunctionType.shared.declaredReturnType = createAwaitableReturnType(node, functionType.shared.declaredReturnType, types_1.FunctionType.isGenerator(functionType));
13570
13555
  }
13571
13556
  else {
13572
- awaitableFunctionType.priv.inferredReturnType = {
13557
+ awaitableFunctionType.shared.inferredReturnType = {
13573
13558
  type: createAwaitableReturnType(node, getInferredReturnType(functionType), types_1.FunctionType.isGenerator(functionType)),
13574
13559
  };
13575
13560
  }
@@ -16633,38 +16618,49 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16633
16618
  }
16634
16619
  }
16635
16620
  }
16621
+ function getEffectiveReturnType(type) {
16622
+ return getEffectiveReturnTypeResult(type).type;
16623
+ }
16624
+ function getInferredReturnType(type) {
16625
+ return getInferredReturnTypeResult(type).type;
16626
+ }
16636
16627
  // Returns the return type of the function. If the type is explicitly provided in
16637
16628
  // a type annotation, that type is returned. If not, an attempt is made to infer
16638
16629
  // the return type. If a list of args is provided, the inference logic may take
16639
16630
  // into account argument types to infer the return type.
16640
- function getEffectiveReturnType(type, options) {
16631
+ function getEffectiveReturnTypeResult(type, options) {
16641
16632
  const specializedReturnType = types_1.FunctionType.getEffectiveReturnType(type, /* includeInferred */ false);
16642
16633
  if (specializedReturnType && !(0, types_1.isUnknown)(specializedReturnType)) {
16643
- return specializedReturnType;
16634
+ return { type: specializedReturnType };
16644
16635
  }
16645
- return getInferredReturnType(type, options?.callSiteInfo);
16636
+ return getInferredReturnTypeResult(type, options?.callSiteInfo);
16646
16637
  }
16647
- function _getInferredReturnType(type, callSiteInfo) {
16638
+ function _getInferredReturnTypeResult(type, callSiteInfo) {
16648
16639
  let returnType;
16649
16640
  let isIncomplete = false;
16650
16641
  const analyzeUnannotatedFunctions = true;
16651
16642
  // Don't attempt to infer the return type for a stub file.
16652
16643
  if (types_1.FunctionType.isStubDefinition(type)) {
16653
- return types_1.UnknownType.create();
16644
+ return { type: types_1.UnknownType.create() };
16654
16645
  }
16655
16646
  // Don't infer the return type for a ParamSpec value.
16656
16647
  if (types_1.FunctionType.isParamSpecValue(type)) {
16657
- return types_1.UnknownType.create();
16648
+ return { type: types_1.UnknownType.create() };
16658
16649
  }
16659
16650
  // Don't infer the return type for an overloaded function (unless it's synthesized,
16660
16651
  // which is needed for proper operation of the __get__ method in properties).
16661
16652
  if (types_1.FunctionType.isOverloaded(type) && !types_1.FunctionType.isSynthesizedMethod(type)) {
16662
- return types_1.UnknownType.create();
16653
+ return { type: types_1.UnknownType.create() };
16663
16654
  }
16655
+ const evalCount = type.shared.inferredReturnType?.evaluationCount ?? 0;
16664
16656
  // If the return type has already been lazily evaluated,
16665
16657
  // don't bother computing it again.
16666
- if (type.priv.inferredReturnType && !type.priv.inferredReturnType.isIncomplete) {
16667
- returnType = type.priv.inferredReturnType.type;
16658
+ if (type.shared.inferredReturnType && !type.shared.inferredReturnType.isIncomplete) {
16659
+ returnType = type.shared.inferredReturnType.type;
16660
+ }
16661
+ else if (evalCount > maxReturnTypeInferenceAttempts) {
16662
+ // Detect a case where a return type won't converge because of recursion.
16663
+ returnType = types_1.UnknownType.create();
16668
16664
  }
16669
16665
  else {
16670
16666
  // Don't bother inferring the return type of __init__ because it's
@@ -16711,7 +16707,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16711
16707
  }
16712
16708
  returnType = (0, typeUtils_1.makeTypeVarsFree)(returnType, typeVarScopes);
16713
16709
  // Cache the type for next time.
16714
- type.priv.inferredReturnType = { type: returnType, isIncomplete };
16710
+ type.shared.inferredReturnType = { type: returnType, isIncomplete, evaluationCount: evalCount + 1 };
16715
16711
  }
16716
16712
  // If the type is partially unknown and the function has one or more unannotated
16717
16713
  // params, try to analyze the function with the provided argument types and
@@ -16748,7 +16744,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
16748
16744
  }
16749
16745
  }
16750
16746
  }
16751
- return returnType;
16747
+ return { type: returnType, isIncomplete };
16752
16748
  }
16753
16749
  function inferReturnTypeForCallSite(type, callSiteInfo) {
16754
16750
  const args = callSiteInfo.args;
@@ -18278,8 +18274,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
18278
18274
  }
18279
18275
  // Determines whether the two types are potentially comparable -- i.e.
18280
18276
  // their types overlap in such a way that it makes sense for them to
18281
- // be compared with an == or != operator.
18282
- function isTypeComparable(leftType, rightType) {
18277
+ // be compared with an == or != operator. The functional also supports
18278
+ // a special variant that can be used for the "is" and "is not" operator.
18279
+ // This variant can be less conservative in some cases.
18280
+ function isTypeComparable(leftType, rightType, assumeIsOperator = false) {
18283
18281
  if ((0, types_1.isAnyOrUnknown)(leftType) || (0, types_1.isAnyOrUnknown)(rightType)) {
18284
18282
  return true;
18285
18283
  }
@@ -18319,6 +18317,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
18319
18317
  if (assignType(genericLeftType, genericRightType) || assignType(genericRightType, genericLeftType)) {
18320
18318
  return true;
18321
18319
  }
18320
+ // Check for the "is None" or "is not None" case.
18321
+ if (assumeIsOperator && (0, typeUtils_1.isNoneInstance)(rightType)) {
18322
+ if ((0, typeUtils_1.isNoneInstance)(leftType)) {
18323
+ return true;
18324
+ }
18325
+ // The LHS could be a protocol or 'object', in which case None is
18326
+ // potentially comparable to it. In other cases, None is not comparable
18327
+ // because the types are disjoint.
18328
+ return assignType(leftType, rightType);
18329
+ }
18322
18330
  // Assume that if the types are disjoint and built-in classes that they
18323
18331
  // will never be comparable.
18324
18332
  if (types_1.ClassType.isBuiltIn(leftType) && types_1.ClassType.isBuiltIn(rightType) && types_1.TypeBase.isInstance(rightType)) {
@@ -19232,72 +19240,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
19232
19240
  }
19233
19241
  return canAssign;
19234
19242
  }
19235
- // If the declaredType contains type arguments that are "Any" and
19236
- // the corresponding type argument in the assignedType is not "Any",
19237
- // replace that type argument in the assigned type. This function assumes
19238
- // that the caller has already verified that the assignedType is assignable
19239
- // to the declaredType.
19240
- function replaceTypeArgsWithAny(node, declaredType, assignedType, recursionCount = 0) {
19241
- if (recursionCount > types_1.maxTypeRecursionCount) {
19242
- return undefined;
19243
- }
19244
- recursionCount++;
19245
- if (assignedType.shared.typeParams.length > 0 &&
19246
- assignedType.priv.typeArgs &&
19247
- assignedType.priv.typeArgs.length <= assignedType.shared.typeParams.length &&
19248
- !assignedType.priv.tupleTypeArgs) {
19249
- const constraints = new constraintTracker_1.ConstraintTracker();
19250
- (0, constraintSolver_1.addConstraintsForExpectedType)(evaluatorInterface, types_1.ClassType.specialize(assignedType, /* typeArgs */ undefined), declaredType, constraints, ParseTreeUtils.getTypeVarScopesForNode(node), node.start);
19251
- let replacedTypeArg = false;
19252
- const solution = (0, constraintSolver_1.solveConstraints)(evaluatorInterface, constraints).getMainSolutionSet();
19253
- const newTypeArgs = assignedType.priv.typeArgs.map((typeArg, index) => {
19254
- const typeParam = assignedType.shared.typeParams[index];
19255
- const expectedTypeArgType = solution.getType(typeParam);
19256
- if (expectedTypeArgType) {
19257
- if ((0, types_1.isAnyOrUnknown)(expectedTypeArgType) || (0, types_1.isAnyOrUnknown)(typeArg)) {
19258
- replacedTypeArg = true;
19259
- return expectedTypeArgType;
19260
- }
19261
- if ((0, types_1.isClassInstance)(expectedTypeArgType) && (0, types_1.isClassInstance)(typeArg)) {
19262
- // Recursively replace Any in the type argument.
19263
- const recursiveReplacement = replaceTypeArgsWithAny(node, expectedTypeArgType, typeArg, recursionCount);
19264
- if (recursiveReplacement) {
19265
- replacedTypeArg = true;
19266
- return recursiveReplacement;
19267
- }
19268
- }
19269
- else if ((0, typeUtils_1.containsAnyRecursive)(expectedTypeArgType)) {
19270
- // If the expected type arg contains an Any, we can replace it with
19271
- // a version that doesn't contain Any if the replacement doesn't violate
19272
- // the variance of the type parameter.
19273
- const variance = types_1.TypeVarType.getVariance(typeParam);
19274
- const isSubtype = assignType(expectedTypeArgType, typeArg);
19275
- const isSupertype = assignType(typeArg, expectedTypeArgType);
19276
- if ((variance === 4 /* Variance.Contravariant */ || isSubtype) &&
19277
- (variance === 3 /* Variance.Covariant */ || isSupertype)) {
19278
- replacedTypeArg = true;
19279
- return expectedTypeArgType;
19280
- }
19281
- }
19282
- }
19283
- return typeArg;
19284
- });
19285
- if (replacedTypeArg) {
19286
- return types_1.ClassType.specialize(assignedType, newTypeArgs);
19287
- }
19288
- }
19289
- // If the declared and assigned types are the same generic type but the assigned type
19290
- // contains one or more unknowns, use the declared type instead.
19291
- if (types_1.ClassType.isSameGenericClass(declaredType, assignedType)) {
19292
- if ((0, typeUtils_1.containsAnyRecursive)(assignedType) && !(0, typeUtils_1.containsAnyRecursive)(declaredType)) {
19293
- return declaredType;
19294
- }
19295
- }
19296
- return undefined;
19297
- }
19298
19243
  // When a value is assigned to a variable with a declared type,
19299
19244
  // we may be able to narrow the type based on the assignment.
19300
- function narrowTypeBasedOnAssignment(node, declaredType, assignedTypeResult) {
19245
+ function narrowTypeBasedOnAssignment(declaredType, assignedTypeResult) {
19301
19246
  // TODO: The rules for narrowing types on assignment are not defined in
19302
19247
  // the typing spec. Pyright's current logic is currently not even internally
19303
19248
  // consistent and probably not sound from a type theory perspective. It
@@ -19313,46 +19258,36 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
19313
19258
  }
19314
19259
  }
19315
19260
  const narrowedSubtype = (0, typeUtils_1.mapSubtypes)(declaredType, (declaredSubtype) => {
19316
- // We can't narrow "Any".
19317
- if ((0, types_1.isAnyOrUnknown)(declaredSubtype)) {
19318
- return declaredSubtype;
19261
+ if (!assignType(declaredSubtype, assignedSubtype)) {
19262
+ return undefined;
19319
19263
  }
19320
- if (assignType(declaredSubtype, assignedSubtype)) {
19321
- // If the assigned subtype is Any, stick with the declared type.
19322
- if ((0, types_1.isAny)(assignedSubtype)) {
19323
- return declaredSubtype;
19324
- }
19325
- if ((0, types_1.isClass)(declaredSubtype) &&
19326
- (0, types_1.isClass)(assignedSubtype) &&
19327
- types_1.TypeBase.isInstance(declaredSubtype) === types_1.TypeBase.isInstance(assignedSubtype)) {
19328
- const result = replaceTypeArgsWithAny(node, declaredSubtype, assignedSubtype);
19329
- if (result) {
19330
- assignedSubtype = result;
19331
- }
19264
+ // Retain unknowns for code flow analysis convergence and for
19265
+ // unknown type reporting in strict mode.
19266
+ if ((0, types_1.isUnknown)(assignedSubtype)) {
19267
+ return assignedSubtype;
19268
+ }
19269
+ // If the two types are bidirectionally assignable, they are
19270
+ // either equivalent (in which case it doesn't matter which
19271
+ // one we choose) or one or both include gradual types (Any, etc.),
19272
+ // in which case we'll want to stick with the declared subtype.
19273
+ if (assignType(assignedSubtype, declaredSubtype)) {
19274
+ // We need to be careful with TypedDict types that have
19275
+ // narrowed fields. In this case, we want to return the
19276
+ // assigned type.
19277
+ if ((0, types_1.isClass)(assignedSubtype) &&
19278
+ assignedSubtype.priv.typedDictNarrowedEntries &&
19279
+ (0, types_1.isTypeSame)(assignedSubtype, declaredSubtype, { ignoreTypedDictNarrowEntries: true })) {
19332
19280
  return assignedSubtype;
19333
19281
  }
19334
- if (!(0, types_1.isTypeVar)(declaredSubtype) &&
19335
- (0, types_1.isTypeVar)(assignedSubtype) &&
19336
- !types_1.TypeVarType.isBound(assignedSubtype)) {
19337
- // If the source is an unsolved TypeVar but the declared type is concrete,
19338
- // use the concrete type.
19339
- return declaredSubtype;
19340
- }
19341
- // If the declared type doesn't contain any `Any` but the assigned
19342
- // type does, stick with the declared type. We don't include unknowns
19343
- // in the assigned subtype check here so unknowns are preserved so
19344
- // reportUnknownVariableType assignment diagnostics are reported.
19345
- // TODO - this is an inconsistency because Any and Unknown should
19346
- // always be treated the same for purposes of type narrowing. This
19347
- // should be revisited once the narrowing-on-assignment behavior
19348
- // is properly specified in the typing spec.
19349
- if ((0, typeUtils_1.containsAnyRecursive)(assignedSubtype, /* includeUnknown */ false) &&
19350
- !(0, typeUtils_1.containsAnyRecursive)(declaredSubtype)) {
19351
- return declaredSubtype;
19282
+ // We also need to be careful with callback protocols.
19283
+ if ((0, types_1.isClassInstance)(declaredSubtype) && types_1.ClassType.isProtocolClass(declaredSubtype)) {
19284
+ if ((0, types_1.isFunction)(assignedSubtype) || (0, types_1.isOverloaded)(assignedSubtype)) {
19285
+ return assignedSubtype;
19286
+ }
19352
19287
  }
19353
- return assignedSubtype;
19288
+ return declaredSubtype;
19354
19289
  }
19355
- return undefined;
19290
+ return assignedSubtype;
19356
19291
  });
19357
19292
  // If we couldn't assign the assigned subtype any of the declared
19358
19293
  // subtypes, the types are incompatible. Return the unnarrowed form.
@@ -19895,6 +19830,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
19895
19830
  if (!baseType) {
19896
19831
  return types_1.FunctionType.clone(functionType, /* stripFirstParam */ true);
19897
19832
  }
19833
+ // If the first parameter was already stripped, it has already been
19834
+ // bound. Don't attempt to rebind.
19835
+ if (functionType.priv.strippedFirstParamType) {
19836
+ return functionType;
19837
+ }
19898
19838
  if (types_1.FunctionType.isInstanceMethod(functionType)) {
19899
19839
  // If the baseType is a metaclass, don't specialize the function.
19900
19840
  if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
@@ -19952,6 +19892,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
19952
19892
  }
19953
19893
  else {
19954
19894
  const subDiag = diag?.createAddendum();
19895
+ // Protect against the case where a callback protocol is being
19896
+ // bound to its own __call__ method but the first parameter
19897
+ // is annotated with its own callable type. This can lead to
19898
+ // infinite recursion.
19899
+ if ((0, types_1.isFunction)(memberTypeFirstParamType) || (0, types_1.isOverloaded)(memberTypeFirstParamType)) {
19900
+ if ((0, types_1.isClassInstance)(firstParamType) && types_1.ClassType.isProtocolClass(firstParamType)) {
19901
+ if (subDiag) {
19902
+ subDiag.addMessage(localize_1.LocMessage.bindTypeMismatch().format({
19903
+ type: printType(firstParamType),
19904
+ methodName: memberType.shared.name || '<anonymous>',
19905
+ paramName: memberTypeFirstParam.name || '__p0',
19906
+ }));
19907
+ }
19908
+ return undefined;
19909
+ }
19910
+ }
19955
19911
  if (!assignType(memberTypeFirstParamType, firstParamType, subDiag?.createAddendum(), constraints, 8192 /* AssignTypeFlags.AllowUnspecifiedTypeArgs */, recursionCount)) {
19956
19912
  if (memberTypeFirstParam.name &&
19957
19913
  !types_1.FunctionParam.isNameSynthesized(memberTypeFirstParam) &&
@@ -20230,7 +20186,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
20230
20186
  return codeFlowEngine.printControlFlowGraph(flowNode, reference, callName, logger);
20231
20187
  }
20232
20188
  // Track these apis internal usages when logging is on. otherwise, it should be noop.
20233
- const getInferredReturnType = wrapWithLogger(_getInferredReturnType);
20189
+ const getInferredReturnTypeResult = wrapWithLogger(_getInferredReturnTypeResult);
20234
20190
  const evaluatorInterface = {
20235
20191
  runWithCancellationToken,
20236
20192
  getType,