@zzzen/pyright-internal 1.2.0-dev.20261011 → 1.2.0-dev.20261101

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 (144) hide show
  1. package/dist/analyzer/binder.js +28 -9
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.js +8 -3
  4. package/dist/analyzer/checker.js.map +1 -1
  5. package/dist/analyzer/codeFlowEngine.js +76 -30
  6. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  7. package/dist/analyzer/dataClasses.js +14 -5
  8. package/dist/analyzer/dataClasses.js.map +1 -1
  9. package/dist/analyzer/decorators.d.ts +1 -1
  10. package/dist/analyzer/decorators.js +22 -2
  11. package/dist/analyzer/decorators.js.map +1 -1
  12. package/dist/analyzer/namedTuples.d.ts +2 -1
  13. package/dist/analyzer/namedTuples.js +63 -35
  14. package/dist/analyzer/namedTuples.js.map +1 -1
  15. package/dist/analyzer/operations.js +45 -1
  16. package/dist/analyzer/operations.js.map +1 -1
  17. package/dist/analyzer/overloadResultAdmission.js +115 -3
  18. package/dist/analyzer/overloadResultAdmission.js.map +1 -1
  19. package/dist/analyzer/overloadResultController.js +36 -10
  20. package/dist/analyzer/overloadResultController.js.map +1 -1
  21. package/dist/analyzer/overloadResultSelector.js +32 -12
  22. package/dist/analyzer/overloadResultSelector.js.map +1 -1
  23. package/dist/analyzer/parseTreeUtils.d.ts +3 -0
  24. package/dist/analyzer/parseTreeUtils.js +56 -0
  25. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  26. package/dist/analyzer/patternMatching.js +67 -27
  27. package/dist/analyzer/patternMatching.js.map +1 -1
  28. package/dist/analyzer/program.d.ts +3 -0
  29. package/dist/analyzer/program.js +34 -9
  30. package/dist/analyzer/program.js.map +1 -1
  31. package/dist/analyzer/sentinel.js +7 -1
  32. package/dist/analyzer/sentinel.js.map +1 -1
  33. package/dist/analyzer/service.js +6 -2
  34. package/dist/analyzer/service.js.map +1 -1
  35. package/dist/analyzer/sourceEnumerator.d.ts +3 -1
  36. package/dist/analyzer/sourceEnumerator.js +30 -11
  37. package/dist/analyzer/sourceEnumerator.js.map +1 -1
  38. package/dist/analyzer/sourceFile.js +13 -6
  39. package/dist/analyzer/sourceFile.js.map +1 -1
  40. package/dist/analyzer/sourceMapper.d.ts +1 -0
  41. package/dist/analyzer/sourceMapper.js +10 -4
  42. package/dist/analyzer/sourceMapper.js.map +1 -1
  43. package/dist/analyzer/tupleComparison.d.ts +6 -0
  44. package/dist/analyzer/tupleComparison.js +731 -0
  45. package/dist/analyzer/tupleComparison.js.map +1 -0
  46. package/dist/analyzer/tuples.js +52 -10
  47. package/dist/analyzer/tuples.js.map +1 -1
  48. package/dist/analyzer/typeEvaluator.js +508 -63
  49. package/dist/analyzer/typeEvaluator.js.map +1 -1
  50. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
  51. package/dist/analyzer/typeEvaluatorTypes.js +2 -3
  52. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  53. package/dist/analyzer/typeGuards.d.ts +6 -1
  54. package/dist/analyzer/typeGuards.js +373 -72
  55. package/dist/analyzer/typeGuards.js.map +1 -1
  56. package/dist/analyzer/typeStubRenderer.d.ts +6 -1
  57. package/dist/analyzer/typeStubRenderer.js +19 -12
  58. package/dist/analyzer/typeStubRenderer.js.map +1 -1
  59. package/dist/analyzer/typeUtils.js +3 -0
  60. package/dist/analyzer/typeUtils.js.map +1 -1
  61. package/dist/analyzer/typedDicts.d.ts +2 -1
  62. package/dist/analyzer/typedDicts.js +49 -10
  63. package/dist/analyzer/typedDicts.js.map +1 -1
  64. package/dist/analyzer/types.d.ts +14 -0
  65. package/dist/analyzer/types.js +215 -10
  66. package/dist/analyzer/types.js.map +1 -1
  67. package/dist/common/configOptions.d.ts +1 -0
  68. package/dist/common/configOptions.js +9 -0
  69. package/dist/common/configOptions.js.map +1 -1
  70. package/dist/common/processUtils.d.ts +6 -0
  71. package/dist/common/processUtils.js +56 -1
  72. package/dist/common/processUtils.js.map +1 -1
  73. package/dist/common/textEditTracker.js +1 -1
  74. package/dist/common/textEditTracker.js.map +1 -1
  75. package/dist/common/windowsProcessTree.d.ts +2 -0
  76. package/dist/common/windowsProcessTree.js +23 -0
  77. package/dist/common/windowsProcessTree.js.map +1 -1
  78. package/dist/common/windowsProcessTree.json +273 -34
  79. package/dist/languageServerBase.d.ts +3 -0
  80. package/dist/languageServerBase.js +44 -12
  81. package/dist/languageServerBase.js.map +1 -1
  82. package/dist/languageService/callHierarchyProvider.js +6 -6
  83. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  84. package/dist/languageService/referencesProvider.js +3 -3
  85. package/dist/languageService/referencesProvider.js.map +1 -1
  86. package/dist/languageService/renameProvider.js +1 -1
  87. package/dist/languageService/renameProvider.js.map +1 -1
  88. package/dist/languageService/symbolIndexer.js +2 -2
  89. package/dist/languageService/symbolIndexer.js.map +1 -1
  90. package/dist/localization/localize.d.ts +2 -0
  91. package/dist/localization/localize.js +2 -0
  92. package/dist/localization/localize.js.map +1 -1
  93. package/dist/localization/package.nls.en-us.json +8 -0
  94. package/dist/parser/parseTreeTokenReuse.d.ts +34 -0
  95. package/dist/parser/parseTreeTokenReuse.js +897 -0
  96. package/dist/parser/parseTreeTokenReuse.js.map +1 -0
  97. package/dist/parser/tokenizer.d.ts +10 -1
  98. package/dist/parser/tokenizer.js +184 -130
  99. package/dist/parser/tokenizer.js.map +1 -1
  100. package/dist/tests/checker.test.js +58 -0
  101. package/dist/tests/checker.test.js.map +1 -1
  102. package/dist/tests/config.test.js +126 -0
  103. package/dist/tests/config.test.js.map +1 -1
  104. package/dist/tests/fourSlashParser.test.js +35 -0
  105. package/dist/tests/fourSlashParser.test.js.map +1 -1
  106. package/dist/tests/fourslash/hover.typedDict.get.fourslash.js +11 -0
  107. package/dist/tests/fourslash/hover.typedDict.get.fourslash.js.map +1 -1
  108. package/dist/tests/harness/fourslash/fourSlashParser.js +14 -4
  109. package/dist/tests/harness/fourslash/fourSlashParser.js.map +1 -1
  110. package/dist/tests/languageServer.test.js +15 -0
  111. package/dist/tests/languageServer.test.js.map +1 -1
  112. package/dist/tests/lsp/languageServer.js +6 -6
  113. package/dist/tests/lsp/languageServer.js.map +1 -1
  114. package/dist/tests/mypyPrimerAnalysis.test.js +133 -0
  115. package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
  116. package/dist/tests/overloadResultController.test.js +379 -1
  117. package/dist/tests/overloadResultController.test.js.map +1 -1
  118. package/dist/tests/signatureHelp.test.js +34 -0
  119. package/dist/tests/signatureHelp.test.js.map +1 -1
  120. package/dist/tests/sourceEnumeratorSymlink.test.js +98 -13
  121. package/dist/tests/sourceEnumeratorSymlink.test.js.map +1 -1
  122. package/dist/tests/sourceMapperUtils.test.js +143 -0
  123. package/dist/tests/sourceMapperUtils.test.js.map +1 -1
  124. package/dist/tests/typeEvaluator1.test.js +22 -3
  125. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  126. package/dist/tests/typeEvaluator2.test.js +54 -1
  127. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  128. package/dist/tests/typeEvaluator4.test.js +10 -3
  129. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  130. package/dist/tests/typeEvaluator5.test.js +1 -1
  131. package/dist/tests/typeEvaluator6.test.js +55 -0
  132. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  133. package/dist/tests/typeEvaluator7.test.js +30 -0
  134. package/dist/tests/typeEvaluator7.test.js.map +1 -1
  135. package/dist/tests/typeEvaluator8.test.js +1293 -2
  136. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  137. package/dist/tests/types.test.js +55 -0
  138. package/dist/tests/types.test.js.map +1 -1
  139. package/dist/typeServer/programWrapper.js +8 -2
  140. package/dist/typeServer/programWrapper.js.map +1 -1
  141. package/dist/typeServer/server.d.ts +12 -2
  142. package/dist/typeServer/server.js +97 -0
  143. package/dist/typeServer/server.js.map +1 -1
  144. package/package.json +3 -3
@@ -80,6 +80,7 @@ const namedTuples_1 = require("./namedTuples");
80
80
  const operations_1 = require("./operations");
81
81
  const parameterUtils_1 = require("./parameterUtils");
82
82
  const ParseTreeUtils = __importStar(require("./parseTreeUtils"));
83
+ const parseTreeWalker_1 = require("./parseTreeWalker");
83
84
  const patternMatching_1 = require("./patternMatching");
84
85
  const properties_1 = require("./properties");
85
86
  const protocols_1 = require("./protocols");
@@ -203,6 +204,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
203
204
  let functionRecursionMap = new Map();
204
205
  let codeFlowAnalyzerCache = new Map();
205
206
  let typeCache = new Map();
207
+ let contextualLambdaTypeCache;
206
208
  let typeFormTypeCache = new Map();
207
209
  let effectiveTypeCache = new Map();
208
210
  let exceptionTargetSymbolCache = new Map();
@@ -399,6 +401,55 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
399
401
  function setTypeResultForNode(node, typeResult, flags = 0 /* EvalFlags.None */) {
400
402
  writeTypeCache(node, typeResult, flags);
401
403
  }
404
+ function captureContextualLambdaTypes(node, typeResult) {
405
+ const cache = contextualLambdaTypeCache;
406
+ if (!cache || !cache.lambdaNodes.some((root) => ParseTreeUtils.isNodeContainedWithin(node, root))) {
407
+ return;
408
+ }
409
+ captureLambdaTypeCacheEntries(node, cache, typeResult);
410
+ }
411
+ function captureLambdaTypeCacheEntries(node, cache, typeResult) {
412
+ checkForCancellation();
413
+ const entry = typeResult ? { typeResult, flags: 0 /* EvalFlags.None */, incompleteGenCount } : readTypeCacheEntry(node);
414
+ if (entry && !entry.typeResult.isIncomplete) {
415
+ captureLambdaTypeCacheEntry(node, cache, entry);
416
+ }
417
+ if (typeResult) {
418
+ return;
419
+ }
420
+ for (const child of (0, parseTreeWalker_1.getChildNodes)(node)) {
421
+ // Nested lambdas capture their own contextual types before any
422
+ // non-contextual fallback can replace them.
423
+ if (child && child.nodeType !== 33 /* ParseNodeType.Lambda */) {
424
+ captureLambdaTypeCacheEntries(child, cache);
425
+ }
426
+ }
427
+ }
428
+ function captureLambdaTypeCacheEntry(node, cache, entry) {
429
+ const nodeEntries = cache.entries.get(node) ?? new Map();
430
+ // Generic inference can revisit a lambda within the same callable branch.
431
+ nodeEntries.set(cache.branchIndex, entry);
432
+ cache.entries.set(node, nodeEntries);
433
+ }
434
+ function combineContextualLambdaTypes(cache) {
435
+ for (const [node, branchEntries] of cache.entries) {
436
+ checkForCancellation();
437
+ const nodeEntries = Array.from(branchEntries.values());
438
+ const lastEntry = nodeEntries[nodeEntries.length - 1];
439
+ writeTypeCache(node, {
440
+ ...lastEntry.typeResult,
441
+ type: (0, types_1.combineTypes)(nodeEntries.map((entry) => entry.typeResult.type)),
442
+ typeErrors: nodeEntries.some((entry) => entry.typeResult.typeErrors),
443
+ }, readTypeCacheEntry(node)?.flags ?? lastEntry.flags);
444
+ const parentCache = contextualLambdaTypeCache;
445
+ const combinedEntry = readTypeCacheEntry(node);
446
+ if (parentCache &&
447
+ combinedEntry &&
448
+ parentCache.lambdaNodes.some((root) => ParseTreeUtils.isNodeContainedWithin(node, root))) {
449
+ captureLambdaTypeCacheEntry(node, parentCache, combinedEntry);
450
+ }
451
+ }
452
+ }
402
453
  function getMaxCodeComplexity() {
403
454
  return maxCodeComplexity;
404
455
  }
@@ -688,6 +739,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
688
739
  }
689
740
  }
690
741
  function getTypeOfExpression(node, flags = 0 /* EvalFlags.None */, inferenceContext) {
742
+ const result = getTypeOfExpressionWithCache(node, flags, inferenceContext);
743
+ if ((flags & 268435456 /* EvalFlags.StripTupleLiterals */) !== 0 && result.type.props?.inferredTupleLiteral) {
744
+ return { ...result, type: (0, types_1.getInferredTupleLiteralBase)(result.type) };
745
+ }
746
+ return result;
747
+ }
748
+ function getTypeOfExpressionWithCache(node, flags = 0 /* EvalFlags.None */, inferenceContext) {
691
749
  if (evaluatorOptions.experimentalOverloadResult?.needsActivationBoundary()) {
692
750
  return runWithOverloadActivation(() => getTypeOfExpression(node, flags, inferenceContext));
693
751
  }
@@ -1119,6 +1177,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
1119
1177
  return getTypeOfStringListAsType(node, flags);
1120
1178
  }
1121
1179
  const isBytesNode = (node) => (node.d.token.flags & 32 /* StringTokenFlags.Bytes */) !== 0;
1180
+ const isTemplateNode = (node) => (node.d.token.flags & 128 /* StringTokenFlags.Template */) !== 0;
1181
+ // Check for mixing of t-string literals with str, bytes, or f-string
1182
+ // literals. CPython reports this as a SyntaxError (PEP 750).
1183
+ const firstTemplateIndex = node.d.strings.findIndex(isTemplateNode);
1184
+ const firstNonTemplateIndex = node.d.strings.findIndex((str) => !isTemplateNode(str));
1185
+ if (firstTemplateIndex >= 0 && firstNonTemplateIndex >= 0) {
1186
+ addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.mixingTemplateAndStr(), node.d.strings[Math.max(firstTemplateIndex, firstNonTemplateIndex)]);
1187
+ return { type: types_1.UnknownType.create() };
1188
+ }
1122
1189
  // Check for mixing of bytes and str, which is not allowed.
1123
1190
  const firstStrIndex = node.d.strings.findIndex((str) => !isBytesNode(str));
1124
1191
  const firstBytesIndex = node.d.strings.findIndex((str) => isBytesNode(str));
@@ -1339,7 +1406,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
1339
1406
  }
1340
1407
  return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
1341
1408
  if ((0, types_1.isClass)(subtype)) {
1342
- if (subtype.priv.literalValue !== undefined) {
1409
+ // A sentinel literal represents a stable singleton, so stripping
1410
+ // it cannot produce a wider instance type.
1411
+ if (subtype.priv.literalValue !== undefined && !(0, typeUtils_1.isSentinelLiteral)(subtype)) {
1343
1412
  subtype = types_1.ClassType.cloneWithLiteral(subtype, /* value */ undefined);
1344
1413
  }
1345
1414
  if (types_1.ClassType.isBuiltIn(subtype, 'LiteralString')) {
@@ -2741,6 +2810,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
2741
2810
  const declarations = symbolWithScope.symbol.getDeclarations();
2742
2811
  let declaredType = getDeclaredTypeOfSymbol(symbolWithScope.symbol)?.type;
2743
2812
  const fileInfo = nodeInfo.getFileInfo(nameNode);
2813
+ // Class-scope aliases need the canonical method type for binding and override checks.
2814
+ if (declaredType === undefined && symbolWithScope.scope.type === 3 /* ScopeType.Class */) {
2815
+ const methodType = getMethodFromDescriptor(typeResult.type);
2816
+ if (methodType) {
2817
+ typeResult = { ...typeResult, type: methodType };
2818
+ }
2819
+ }
2744
2820
  // If this is a class scope and there is no type declared for this class variable,
2745
2821
  // see if a parent class has a type declared.
2746
2822
  if (declaredType === undefined && symbolWithScope.scope.type === 3 /* ScopeType.Class */) {
@@ -3237,8 +3313,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
3237
3313
  }
3238
3314
  // This code path can often produce many duplicate subtypes. We can
3239
3315
  // reduce the cost of the combineTypes call below by filtering out these
3240
- // duplicates proactively.
3316
+ // duplicates proactively. Equal retained tuple literals can carry
3317
+ // different inference fallbacks, which combineTypes must reconcile.
3241
3318
  if (newSubtypes.length === 0 ||
3319
+ transformedType.props?.inferredTupleLiteral ||
3320
+ newSubtypes[newSubtypes.length - 1].props?.inferredTupleLiteral ||
3242
3321
  !(0, types_1.isTypeSame)(transformedType, newSubtypes[newSubtypes.length - 1])) {
3243
3322
  newSubtypes.push(transformedType);
3244
3323
  }
@@ -3679,8 +3758,101 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
3679
3758
  }
3680
3759
  }
3681
3760
  }
3761
+ // Bare names expose descriptors without changing the canonical types of method declarations.
3762
+ if ((flags & 256 /* EvalFlags.TypeExpression */) === 0) {
3763
+ type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
3764
+ if (!(0, types_1.isFunctionOrOverloaded)(subtype)) {
3765
+ return subtype;
3766
+ }
3767
+ const signature = (0, types_1.isFunction)(subtype) ? subtype : types_1.OverloadedType.getOverloads(subtype)[0];
3768
+ if (!signature ||
3769
+ signature.priv.boundToType ||
3770
+ (!types_1.FunctionType.isClassMethod(signature) && !types_1.FunctionType.isStaticMethod(signature))) {
3771
+ return subtype;
3772
+ }
3773
+ const implementation = (0, types_1.isOverloaded)(subtype) ? types_1.OverloadedType.getImplementation(subtype) : undefined;
3774
+ const declaration = implementation && (0, types_1.isFunction)(implementation)
3775
+ ? implementation.shared.declaration
3776
+ : signature.shared.declaration;
3777
+ for (const decorator of declaration?.node.d.decorators ?? []) {
3778
+ const decoratedType = readTypeCache(decorator, /* flags */ undefined);
3779
+ if (decoratedType &&
3780
+ (0, types_1.isClassInstance)(decoratedType) &&
3781
+ types_1.ClassType.isBuiltIn(decoratedType, ['classmethod', 'staticmethod'])) {
3782
+ return createMethodDescriptor(decoratedType, subtype, decorator);
3783
+ }
3784
+ // Only look through outer decorators that preserve the original
3785
+ // callable, rather than a replacement with a similar signature.
3786
+ if (!decoratedType ||
3787
+ !(0, types_1.isFunction)(decoratedType) ||
3788
+ decoratedType.shared.declaration !== declaration ||
3789
+ types_1.FunctionType.isClassMethod(decoratedType) !== types_1.FunctionType.isClassMethod(signature) ||
3790
+ types_1.FunctionType.isStaticMethod(decoratedType) !== types_1.FunctionType.isStaticMethod(signature)) {
3791
+ break;
3792
+ }
3793
+ }
3794
+ return subtype;
3795
+ });
3796
+ }
3682
3797
  return { type, isIncomplete };
3683
3798
  }
3799
+ function createMethodDescriptor(descriptor, methodType, decorator) {
3800
+ const signature = (0, types_1.isFunction)(methodType) ? methodType : types_1.OverloadedType.getOverloads(methodType)[0];
3801
+ const fileInfo = nodeInfo.getFileInfo(decorator);
3802
+ const descriptorClass = types_1.ClassType.createInstantiable(descriptor.shared.name, `${signature.shared.fullName}.__descriptor__`, fileInfo.moduleName, fileInfo.fileUri, 1 /* ClassTypeFlags.BuiltIn */, ParseTreeUtils.getTypeSourceId(decorator),
3803
+ /* declaredMetaclass */ undefined, descriptor.shared.effectiveMetaclass ?? types_1.UnknownType.create());
3804
+ descriptorClass.shared.baseClasses.push(types_1.ClassType.cloneAsInstantiable(descriptor));
3805
+ (0, typeUtils_1.computeMroLinearization)(descriptorClass);
3806
+ // ParamSpec and return-type arguments cannot represent correlated overloads.
3807
+ // Retain the callable itself rather than reconstructing it from those arguments.
3808
+ const functionType = (0, typeUtils_1.mapSignatures)(methodType, (overload) => types_1.FunctionType.cloneWithNewFlags(overload, overload.shared.flags & ~(2 /* FunctionTypeFlags.ClassMethod */ | 4 /* FunctionTypeFlags.StaticMethod */)));
3809
+ const getter = types_1.FunctionType.createSynthesizedInstance('__func__');
3810
+ types_1.FunctionType.addParam(getter, types_1.FunctionParam.create(0 /* ParamCategory.Simple */, types_1.AnyType.create(), types_1.FunctionParamFlags.TypeDeclared, 'self'));
3811
+ getter.shared.declaredReturnType = functionType;
3812
+ getter.shared.declaration = signature.shared.declaration;
3813
+ const propertyType = getBuiltInType(decorator, 'property');
3814
+ (0, debug_1.assert)((0, types_1.isInstantiableClass)(propertyType));
3815
+ const functionProperty = (0, properties_1.createProperty)(evaluatorInterface, decorator, propertyType, getter, nodeInfo);
3816
+ const fields = types_1.ClassType.getSymbolTable(descriptorClass);
3817
+ fields.set('__func__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, functionProperty));
3818
+ fields.set('__wrapped__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, functionProperty));
3819
+ if (types_1.ClassType.isBuiltIn(descriptor, 'staticmethod')) {
3820
+ fields.set('__call__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, methodType));
3821
+ }
3822
+ const getMethod = getBoundMagicMethod(descriptor, '__get__');
3823
+ if (getMethod && (0, types_1.isFunctionOrOverloaded)(getMethod)) {
3824
+ const boundFunction = types_1.ClassType.isBuiltIn(descriptor, 'classmethod')
3825
+ ? (0, typeUtils_1.mapSignatures)(methodType, (overload) => types_1.FunctionType.clone(overload, /* stripFirstParam */ true))
3826
+ : functionType;
3827
+ const descriptorGet = (0, typeUtils_1.mapSignatures)(getMethod, (overload) => {
3828
+ const specializedGet = types_1.FunctionType.clone(overload);
3829
+ specializedGet.shared.declaredReturnType = boundFunction;
3830
+ if (specializedGet.priv.specializedTypes) {
3831
+ specializedGet.priv.specializedTypes.returnType = boundFunction;
3832
+ }
3833
+ return specializedGet;
3834
+ });
3835
+ (0, debug_1.assert)(descriptorGet);
3836
+ fields.set('__get__', symbol_1.Symbol.createWithType(4 /* SymbolFlags.ClassMember */, descriptorGet));
3837
+ }
3838
+ return types_1.ClassType.cloneAsInstance(descriptorClass);
3839
+ }
3840
+ function getMethodFromDescriptor(type) {
3841
+ if (!(0, types_1.isClassInstance)(type) || !types_1.ClassType.isBuiltIn(type, ['classmethod', 'staticmethod'])) {
3842
+ return undefined;
3843
+ }
3844
+ const functionProperty = type.shared.fields.get('__func__')?.getSynthesizedType()?.type;
3845
+ const functionType = functionProperty && (0, types_1.isClassInstance)(functionProperty)
3846
+ ? getGetterTypeFromProperty(functionProperty)
3847
+ : undefined;
3848
+ if (!functionType || !(0, types_1.isFunctionOrOverloaded)(functionType)) {
3849
+ return undefined;
3850
+ }
3851
+ return (0, typeUtils_1.mapSignatures)(functionType, (signature) => types_1.FunctionType.cloneWithNewFlags(signature, signature.shared.flags |
3852
+ (types_1.ClassType.isBuiltIn(type, 'classmethod')
3853
+ ? 2 /* FunctionTypeFlags.ClassMethod */
3854
+ : 4 /* FunctionTypeFlags.StaticMethod */)));
3855
+ }
3684
3856
  const typeFormSpecialFormDiagnosticFactories = [
3685
3857
  ['Final', () => localize_1.LocMessage.finalContext()],
3686
3858
  ['Optional', () => localize_1.LocMessage.optionalExtraArgs()],
@@ -6061,19 +6233,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6061
6233
  }
6062
6234
  }
6063
6235
  const magicMethodName = getIndexAccessMagicMethodName(usage);
6064
- const itemMethodType = getBoundMagicMethod(baseType, magicMethodName, selfType, node.d.leftExpr);
6065
- if (!itemMethodType) {
6066
- addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIndexIssue, localize_1.LocMessage.methodNotDefinedOnType().format({
6067
- name: magicMethodName,
6068
- type: printType(baseType),
6069
- }), node.d.leftExpr);
6070
- return { type: types_1.UnknownType.create() };
6071
- }
6236
+ // A full member lookup specializes tuple arguments even if a constant
6237
+ // index can select its answer directly.
6238
+ const nativeItemSymbol = usage.method === 'get' && !selfType && (0, types_1.isClassInstance)(baseType) && types_1.ClassType.isBuiltIn(baseType, 'tuple')
6239
+ ? types_1.ClassType.getSymbolTable(baseType).get(magicMethodName)
6240
+ : undefined;
6241
+ const nativeItemType = nativeItemSymbol?.isClassMember()
6242
+ ? getEffectiveTypeOfSymbol(nativeItemSymbol)
6243
+ : undefined;
6244
+ const nativeItemMethods = nativeItemType && (0, types_1.isFunctionOrOverloaded)(nativeItemType)
6245
+ ? (0, types_1.isOverloaded)(nativeItemType)
6246
+ ? types_1.OverloadedType.getOverloads(nativeItemType)
6247
+ : [nativeItemType]
6248
+ : [];
6249
+ const canDeferBinding = nativeItemMethods.length > 0 &&
6250
+ nativeItemMethods.every((method) => types_1.FunctionType.isInstanceMethod(method) &&
6251
+ method.shared.parameters.length > 0 &&
6252
+ !types_1.FunctionParam.isTypeDeclared(method.shared.parameters[0]));
6253
+ let itemMethodType = canDeferBinding
6254
+ ? undefined
6255
+ : getBoundMagicMethod(baseType, magicMethodName, selfType, node.d.leftExpr);
6072
6256
  // Handle the special case where the object is a tuple and
6073
6257
  // the index is a constant number (integer) or a slice with integer
6074
6258
  // start and end values. In these cases, we can determine
6075
6259
  // the exact type by indexing into the tuple type array.
6076
- if (node.d.items.length === 1 &&
6260
+ if ((canDeferBinding || itemMethodType) &&
6261
+ node.d.items.length === 1 &&
6077
6262
  !node.d.trailingComma &&
6078
6263
  !node.d.items[0].d.name &&
6079
6264
  node.d.items[0].d.argCategory === 0 /* ArgCategory.Simple */ &&
@@ -6100,16 +6285,47 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6100
6285
  }
6101
6286
  }
6102
6287
  }
6103
- else if ((0, types_1.isClassInstance)(valueType) && types_1.ClassType.isBuiltIn(valueType, 'slice')) {
6288
+ else if (usage.method === 'get' &&
6289
+ index0Expr.nodeType === 46 /* ParseNodeType.Slice */ &&
6290
+ (0, types_1.isClassInstance)(valueType) &&
6291
+ types_1.ClassType.isBuiltIn(valueType, 'slice')) {
6104
6292
  const tupleType = (0, typeUtils_1.getSpecializedTupleType)(baseType);
6105
- if (tupleType && index0Expr.nodeType === 46 /* ParseNodeType.Slice */) {
6106
- const slicedTupleType = (0, tuples_1.getSlicedTupleType)(evaluatorInterface, tupleType, index0Expr);
6107
- if (slicedTupleType) {
6108
- return { type: slicedTupleType };
6293
+ if (tupleType) {
6294
+ // Skip this if a subclass overrides the tuple's __getitem__ method.
6295
+ const getItemMember = (0, typeUtils_1.lookUpObjectMember)(baseType, '__getitem__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
6296
+ const isTupleGetItem = !getItemMember ||
6297
+ ((0, types_1.isInstantiableClass)(getItemMember.classType) &&
6298
+ types_1.ClassType.isBuiltIn(getItemMember.classType, 'tuple'));
6299
+ if (isTupleGetItem) {
6300
+ const slicedTupleType = (0, tuples_1.getSlicedTupleType)(evaluatorInterface, tupleType, index0Expr);
6301
+ if (slicedTupleType) {
6302
+ return { type: slicedTupleType };
6303
+ }
6109
6304
  }
6110
6305
  }
6111
6306
  }
6112
6307
  }
6308
+ if (canDeferBinding) {
6309
+ const inferredBase = (0, types_1.getInferredTupleLiteralBase)(baseType);
6310
+ const tupleArgs = baseType.priv.tupleTypeArgs;
6311
+ if (inferredBase !== baseType &&
6312
+ (0, types_1.isClassInstance)(inferredBase) &&
6313
+ types_1.ClassType.isBuiltIn(inferredBase, 'tuple') &&
6314
+ tupleArgs &&
6315
+ tupleArgs.length > 1 &&
6316
+ tupleArgs.some((arg) => (0, types_1.isUnion)(arg.type) || ((0, types_1.isClassInstance)(arg.type) && types_1.ClassType.isBuiltIn(arg.type, 'tuple')))) {
6317
+ // Avoid structural union work for optional literals before native method binding.
6318
+ baseType = inferredBase;
6319
+ }
6320
+ itemMethodType = getBoundMagicMethod(baseType, magicMethodName, selfType, node.d.leftExpr);
6321
+ }
6322
+ if (!itemMethodType) {
6323
+ addDiagnostic(diagnosticRules_1.DiagnosticRule.reportIndexIssue, localize_1.LocMessage.methodNotDefinedOnType().format({
6324
+ name: magicMethodName,
6325
+ type: printType(baseType),
6326
+ }), node.d.leftExpr);
6327
+ return { type: types_1.UnknownType.create() };
6328
+ }
6113
6329
  const positionalArgs = node.d.items.filter((item) => item.d.argCategory === 0 /* ArgCategory.Simple */);
6114
6330
  const unpackedListArgs = node.d.items.filter((item) => item.d.argCategory === 1 /* ArgCategory.UnpackedList */);
6115
6331
  let positionalIndexType;
@@ -6973,14 +7189,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6973
7189
  else {
6974
7190
  if (enclosingClassType) {
6975
7191
  targetClassType = enclosingClassType ?? types_1.UnknownType.create();
7192
+ const functionInfo = enclosingFunction
7193
+ ? (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, enclosingFunction,
7194
+ /* isInClass */ true, nodeInfo)
7195
+ : undefined;
6976
7196
  // Zero-argument forms of super are not allowed within static methods.
6977
7197
  // This results in a runtime exception.
6978
- if (enclosingFunction) {
6979
- const functionInfo = (0, decorators_1.getFunctionInfoFromDecorators)(evaluatorInterface, enclosingFunction,
6980
- /* isInClass */ true, nodeInfo);
6981
- if ((functionInfo?.flags & 4 /* FunctionTypeFlags.StaticMethod */) !== 0) {
6982
- addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.superCallZeroArgFormStaticMethod(), node.d.leftExpr);
6983
- }
7198
+ if (functionInfo !== undefined && (functionInfo.flags & 4 /* FunctionTypeFlags.StaticMethod */) !== 0) {
7199
+ addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.superCallZeroArgFormStaticMethod(), node.d.leftExpr);
7200
+ }
7201
+ else if (!ParseTreeUtils.isZeroArgSuperCallAllowed(node, nodeInfo.getFileInfo(node).executionEnvironment.pythonVersion, nodeInfo)) {
7202
+ // The evaluation scope cannot supply a first positional
7203
+ // argument for the zero-argument form.
7204
+ addDiagnostic(diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.LocMessage.superCallZeroArgForm(), node.d.leftExpr);
6984
7205
  }
6985
7206
  }
6986
7207
  else {
@@ -7218,7 +7439,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7218
7439
  // there will be only one argument list in expandedArgTypes, and all entries
7219
7440
  // (one for each argument) will be undefined. On subsequent calls, this
7220
7441
  // list will grow to include union expansions.
7221
- function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
7442
+ function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext, skipFinalValidation = false) {
7222
7443
  const returnTypes = [];
7223
7444
  const specializedInitSelfTypes = [];
7224
7445
  let matchedOverloads = [];
@@ -7261,17 +7482,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7261
7482
  if (!callResult.argumentErrors && callResult.returnType) {
7262
7483
  if (evaluatorOptions.experimentalOverloadResult &&
7263
7484
  !callResult.isTypeIncomplete &&
7264
- !overload.priv.boundToType &&
7265
- !overload.shared.methodClass &&
7266
- !overload.shared.declaration?.isMethod &&
7267
7485
  errorNode.nodeType === 9 /* ParseNodeType.Call */ &&
7268
- errorNode.d.leftExpr.nodeType === 38 /* ParseNodeType.Name */ &&
7269
- errorNode.parent?.nodeType === 3 /* ParseNodeType.Assignment */ &&
7270
- errorNode.parent.d.rightExpr === errorNode &&
7486
+ (0, overloadResultSelector_1.isAutomaticOverloadSeedSyntax)(errorNode) &&
7271
7487
  expandedArgTypes.length === 1 &&
7272
- !hasArgTypeOverride &&
7273
- callResult.argResults) {
7274
- evaluatorOptions.experimentalOverloadResult.considerActivation(errorNode, callResult.argResults);
7488
+ !hasArgTypeOverride) {
7489
+ const receiver = overload.priv.boundToType;
7490
+ evaluatorOptions.experimentalOverloadResult.considerActivation(errorNode, receiver && (0, types_1.isClassInstance)(receiver)
7491
+ ? [{ argType: receiver }, ...(callResult.argResults ?? [])]
7492
+ : callResult.argResults ?? []);
7275
7493
  }
7276
7494
  overloadsUsedForCall.push(overload);
7277
7495
  matchedOverload = overload;
@@ -7390,6 +7608,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7390
7608
  if (constraints && isDefinitiveMatchFound) {
7391
7609
  constraints.copyFromClone(matchedOverloads[matchedOverloads.length - 1].constraints);
7392
7610
  }
7611
+ // A speculative refinement does not need to populate the type cache;
7612
+ // the original call has already performed the normal final validation.
7613
+ if (skipFinalValidation) {
7614
+ return {
7615
+ argumentErrors: false,
7616
+ returnType: (0, types_1.combineTypes)(returnTypes),
7617
+ isTypeIncomplete,
7618
+ overloadsUsedForCall,
7619
+ };
7620
+ }
7393
7621
  // And run through the first expanded argument list one more time to
7394
7622
  // populate the type cache, without applying a different branch's constraints.
7395
7623
  const finalConstraints = expandedArgTypes.length > 1
@@ -7518,10 +7746,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7518
7746
  name: arg.d.name,
7519
7747
  }));
7520
7748
  const sources = node.d.args.map((arg) => getTypeOfExpression(arg.d.valueExpr));
7521
- if (sources.some((s) => s.isIncomplete || s.typeErrors || (0, types_1.isAny)(s.type) || !(0, overloadResultSelector_1.isFixedOverloadArgumentShape)(s.type, budget))) {
7749
+ const receiver = node.d.leftExpr.nodeType === 35 /* ParseNodeType.MemberAccess */
7750
+ ? getTypeOfExpression(node.d.leftExpr.d.leftExpr)
7751
+ : undefined;
7752
+ if ([...sources, ...(receiver ? [receiver] : [])].some((s) => s.isIncomplete || s.typeErrors || (0, types_1.isAny)(s.type) || !(0, overloadResultSelector_1.isFixedOverloadArgumentShape)(s.type, budget))) {
7522
7753
  return decline('unsupported-argument-shape');
7523
7754
  }
7524
- if (!sources.some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
7755
+ if (![...sources, ...(receiver ? [receiver] : [])].some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
7525
7756
  return decline('no-invariant-any');
7526
7757
  }
7527
7758
  const returns = [];
@@ -7531,10 +7762,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7531
7762
  const declaration = overload.shared.declaration;
7532
7763
  const declaredReturnType = overload.shared.declaredReturnType;
7533
7764
  const returnType = types_1.FunctionType.getEffectiveReturnType(overload);
7765
+ const receiverParam = overload.priv.strippedFirstParamType;
7766
+ const supportedBinding = receiver
7767
+ ? declaration?.isMethod &&
7768
+ types_1.FunctionType.isInstanceMethod(overload) &&
7769
+ overload.priv.boundToType &&
7770
+ (0, types_1.isClassInstance)(overload.priv.boundToType) &&
7771
+ receiverParam &&
7772
+ (0, types_1.isClassInstance)(receiverParam) &&
7773
+ (0, types_1.isClassInstance)(receiver.type) &&
7774
+ types_1.ClassType.isSameGenericClass(receiver.type, receiverParam) &&
7775
+ overload.shared.methodClass &&
7776
+ types_1.ClassType.isSameGenericClass(receiver.type, types_1.ClassType.cloneAsInstance(overload.shared.methodClass)) &&
7777
+ (0, overloadResultSelector_1.isFixedOverloadArgumentShape)(receiverParam, budget)
7778
+ : !declaration?.isMethod && !overload.shared.methodClass && !overload.priv.boundToType;
7534
7779
  if (!declaration ||
7535
- declaration.isMethod ||
7536
- overload.shared.methodClass ||
7537
- overload.priv.boundToType ||
7780
+ !supportedBinding ||
7538
7781
  overload.shared.typeParams.length ||
7539
7782
  !declaredReturnType ||
7540
7783
  !returnType ||
@@ -7576,6 +7819,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7576
7819
  continue;
7577
7820
  }
7578
7821
  const proof = mapping.argParams.map((p, i) => (0, overloadResultSelector_1.getFixedOverloadCoverage)(sources[i].type, p.paramType, budget));
7822
+ if (receiver && receiverParam) {
7823
+ proof.unshift((0, overloadResultSelector_1.getFixedOverloadCoverage)(receiver.type, receiverParam, budget));
7824
+ }
7579
7825
  const covered = proof.includes('unsupported')
7580
7826
  ? 'unsupported'
7581
7827
  : proof.includes('not-covered')
@@ -7600,11 +7846,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7600
7846
  : decline('equivalent-or-single-return');
7601
7847
  });
7602
7848
  }
7603
- function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext) {
7849
+ function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext, candidateOverloads) {
7604
7850
  const filteredMatchResults = [];
7605
7851
  let contextFreeArgTypes;
7606
7852
  let isTypeIncomplete = !!typeResult.isIncomplete;
7607
7853
  const type = typeResult.type;
7854
+ const overloads = candidateOverloads ?? types_1.OverloadedType.getOverloads(type);
7608
7855
  const speculativeNode = getSpeculativeNodeForCall(errorNode);
7609
7856
  // Start by evaluating the types of the arguments without any expected
7610
7857
  // type. Also, filter the list of overloads based on the number of
@@ -7613,7 +7860,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7613
7860
  // cache or record any diagnostics at this stage.
7614
7861
  useSpeculativeMode(speculativeNode, () => {
7615
7862
  let overloadIndex = 0;
7616
- types_1.OverloadedType.getOverloads(type).forEach((overload) => {
7863
+ overloads.forEach((overload) => {
7617
7864
  // Consider only the functions that have the @overload decorator,
7618
7865
  // not the final function that omits the overload. This is the
7619
7866
  // intended behavior according to PEP 484.
@@ -7630,7 +7877,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7630
7877
  // Skip the error message if we're in speculative mode because it's very
7631
7878
  // expensive, and we're going to suppress the diagnostic anyway.
7632
7879
  if (!canSkipDiagnosticForNode(errorNode)) {
7633
- const overloads = types_1.OverloadedType.getOverloads(type);
7634
7880
  const functionName = overloads.length > 0 && overloads[0].shared.name
7635
7881
  ? overloads[0].shared.name
7636
7882
  : '<anonymous function>';
@@ -7685,7 +7931,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7685
7931
  }
7686
7932
  let expandedArgTypes = [argList.map((arg) => undefined)];
7687
7933
  while (true) {
7688
- const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext);
7934
+ const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext,
7935
+ /* skipFinalValidation */ candidateOverloads !== undefined);
7689
7936
  if (callResult.isTypeIncomplete) {
7690
7937
  isTypeIncomplete = true;
7691
7938
  }
@@ -7820,24 +8067,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7820
8067
  }), exprNode);
7821
8068
  return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
7822
8069
  }
7823
- let returnType = mapSubtypesExpandTypeVars(callTypeResult.type, { sortSubtypes: true }, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
7824
- return useSpeculativeMode(isLastIteration ? undefined : getSpeculativeNodeForCall(errorNode), () => {
7825
- const callResult = validateCallArgsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, constraints, skipUnknownArgCheck, inferenceContext, recursionCount);
7826
- if (callResult.argumentErrors) {
7827
- argumentErrors = true;
7828
- }
7829
- if (callResult.isTypeIncomplete) {
7830
- isTypeIncomplete = true;
7831
- }
7832
- if (callResult.overloadsUsedForCall) {
7833
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
8070
+ const concreteCallType = makeTopLevelTypeVarsConcrete(callTypeResult.type);
8071
+ const lambdaNodes = (0, types_1.isUnion)(concreteCallType)
8072
+ ? argList
8073
+ .map((arg) => arg.valueExpression)
8074
+ .filter((node) => node?.nodeType === 33 /* ParseNodeType.Lambda */)
8075
+ : undefined;
8076
+ const lambdaTypeCache = lambdaNodes?.length
8077
+ ? { lambdaNodes, entries: new Map(), branchIndex: 0 }
8078
+ : undefined;
8079
+ const previousCache = contextualLambdaTypeCache;
8080
+ let returnType;
8081
+ try {
8082
+ if (lambdaTypeCache) {
8083
+ contextualLambdaTypeCache = lambdaTypeCache;
8084
+ }
8085
+ returnType = mapSubtypesExpandTypeVars(callTypeResult.type, { sortSubtypes: true }, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
8086
+ if (lambdaTypeCache) {
8087
+ lambdaTypeCache.branchIndex++;
7834
8088
  }
7835
- specializedInitSelfType = callResult.specializedInitSelfType;
7836
- return callResult.returnType;
7837
- }, {
7838
- allowDiagnostics: true,
8089
+ return useSpeculativeMode(isLastIteration ? undefined : getSpeculativeNodeForCall(errorNode), () => {
8090
+ const callResult = validateCallArgsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, constraints, skipUnknownArgCheck, inferenceContext, recursionCount);
8091
+ if (callResult.argumentErrors) {
8092
+ argumentErrors = true;
8093
+ }
8094
+ if (callResult.isTypeIncomplete) {
8095
+ isTypeIncomplete = true;
8096
+ }
8097
+ if (callResult.overloadsUsedForCall) {
8098
+ (0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
8099
+ }
8100
+ specializedInitSelfType = callResult.specializedInitSelfType;
8101
+ return callResult.returnType;
8102
+ }, {
8103
+ allowDiagnostics: true,
8104
+ });
7839
8105
  });
7840
- });
8106
+ }
8107
+ finally {
8108
+ contextualLambdaTypeCache = previousCache;
8109
+ }
8110
+ // Keep branch-specific checking and return inference separate from the
8111
+ // combined contextual types retained for subsequent queries.
8112
+ if (!isTypeIncomplete && lambdaTypeCache && lambdaTypeCache.branchIndex > 1) {
8113
+ (0, cancellationUtils_1.invalidateTypeCacheIfCanceled)(() => combineContextualLambdaTypes(lambdaTypeCache));
8114
+ }
7841
8115
  // If we ended up with a "Never" type because all code paths returned
7842
8116
  // undefined due to argument errors, transform the result into an Unknown
7843
8117
  // to avoid subsequent false positives.
@@ -8037,6 +8311,110 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8037
8311
  }
8038
8312
  return { symbol, symbolName, classType, hasImplementation };
8039
8313
  }
8314
+ // The synthesized "get" and "pop" methods for a TypedDict include a
8315
+ // catch-all overload that accepts any str key. When the key argument is a
8316
+ // union of str literals, that catch-all overload matches before union
8317
+ // expansion is attempted, which produces an overly-wide return type. This
8318
+ // function evaluates the call separately for each literal key subtype
8319
+ // (speculatively) and, if every subtype is accepted, returns the union of
8320
+ // the resulting return types.
8321
+ function refineTypedDictMethodCallForUnionKey(errorNode, argList, overloadedType, isCallTypeIncomplete, constraints, inferenceContext) {
8322
+ const overloads = types_1.OverloadedType.getOverloads(overloadedType);
8323
+ const overload = overloads[0];
8324
+ if (!overload || !types_1.FunctionType.isSynthesizedMethod(overload)) {
8325
+ return undefined;
8326
+ }
8327
+ const methodName = overload.shared.name;
8328
+ if (methodName !== 'get' && methodName !== 'pop') {
8329
+ return undefined;
8330
+ }
8331
+ const isBound = (0, types_1.isMethodType)(overload);
8332
+ const receiverType = isBound
8333
+ ? overload.priv.strippedFirstParamType
8334
+ : overload.shared.parameters.length > 0
8335
+ ? types_1.FunctionType.getParamType(overload, 0)
8336
+ : undefined;
8337
+ if (!receiverType || !(0, types_1.isClassInstance)(receiverType) || !types_1.ClassType.isTypedDictClass(receiverType)) {
8338
+ return undefined;
8339
+ }
8340
+ // Unbound generic methods have not specialized their field types from the
8341
+ // receiver. Keep the normal result rather than refining it to Unknown.
8342
+ if (!isBound &&
8343
+ ((0, typeUtils_1.requiresSpecialization)(receiverType) || (0, typeUtils_1.containsAnyOrUnknown)(receiverType, /* recurse */ true))) {
8344
+ return undefined;
8345
+ }
8346
+ // Handle only simple positional calls: (key) or (key, default).
8347
+ const keyIndex = isBound ? 0 : 1;
8348
+ if (argList.length <= keyIndex || argList.length > keyIndex + 2) {
8349
+ return undefined;
8350
+ }
8351
+ if (!argList.every((arg) => !arg.name && arg.argCategory === 0 /* ArgCategory.Simple */)) {
8352
+ return undefined;
8353
+ }
8354
+ const keyArg = argList[keyIndex];
8355
+ const keyTypeResult = keyArg.typeResult ?? (keyArg.valueExpression ? getTypeOfExpression(keyArg.valueExpression) : undefined);
8356
+ if (!keyTypeResult || !(0, types_1.isUnion)(keyTypeResult.type)) {
8357
+ return undefined;
8358
+ }
8359
+ // Every subtype must be a str literal; otherwise keep the normal result.
8360
+ const keySubtypes = [];
8361
+ let allStrLiterals = true;
8362
+ (0, typeUtils_1.doForEachSubtype)(keyTypeResult.type, (subtype) => {
8363
+ if ((0, types_1.isClassInstance)(subtype) &&
8364
+ types_1.ClassType.isBuiltIn(subtype, 'str') &&
8365
+ typeof subtype.priv.literalValue === 'string') {
8366
+ keySubtypes.push(subtype);
8367
+ }
8368
+ else {
8369
+ allStrLiterals = false;
8370
+ }
8371
+ });
8372
+ if (!allStrLiterals || keySubtypes.length < 2 || keySubtypes.length > maxSingleOverloadArgTypeExpansionCount) {
8373
+ return undefined;
8374
+ }
8375
+ let isTypeIncomplete = !!keyTypeResult.isIncomplete;
8376
+ const returnTypes = [];
8377
+ const overloadsUsedForCall = new Set();
8378
+ const succeeded = useSpeculativeMode(getSpeculativeNodeForCall(errorNode), () => {
8379
+ for (const keySubtype of keySubtypes) {
8380
+ // Avoid revalidating unrelated keys and their default parameters.
8381
+ const candidates = overloads.filter((candidate) => {
8382
+ const paramType = types_1.FunctionType.getParamType(candidate, keyIndex);
8383
+ return ((0, types_1.isClassInstance)(paramType) &&
8384
+ types_1.ClassType.isBuiltIn(paramType, 'str') &&
8385
+ (paramType.priv.literalValue === undefined ||
8386
+ paramType.priv.literalValue === keySubtype.priv.literalValue));
8387
+ });
8388
+ if (candidates.length === 0) {
8389
+ return false;
8390
+ }
8391
+ const subtypeArgList = [...argList];
8392
+ subtypeArgList[keyIndex] = {
8393
+ argCategory: 0 /* ArgCategory.Simple */,
8394
+ typeResult: { type: keySubtype, isIncomplete: keyTypeResult.isIncomplete },
8395
+ };
8396
+ const subtypeResult = validateOverloadedArgTypes(errorNode, subtypeArgList, { type: overloadedType, isIncomplete: isCallTypeIncomplete }, constraints?.clone(),
8397
+ /* skipUnknownArgCheck */ true, inferenceContext, candidates);
8398
+ if (subtypeResult.isTypeIncomplete) {
8399
+ isTypeIncomplete = true;
8400
+ }
8401
+ if (subtypeResult.argumentErrors || !subtypeResult.returnType) {
8402
+ return false;
8403
+ }
8404
+ returnTypes.push(subtypeResult.returnType);
8405
+ subtypeResult.overloadsUsedForCall?.forEach((matched) => overloadsUsedForCall.add(matched));
8406
+ }
8407
+ return true;
8408
+ });
8409
+ if (!succeeded) {
8410
+ return undefined;
8411
+ }
8412
+ return {
8413
+ returnType: (0, types_1.combineTypes)(returnTypes),
8414
+ isTypeIncomplete,
8415
+ overloadsUsedForCall: [...overloadsUsedForCall],
8416
+ };
8417
+ }
8040
8418
  function validateCallForOverloaded(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, skipUnknownArgCheck, inferenceContext) {
8041
8419
  const overloads = types_1.OverloadedType.getOverloads(expandedCallType);
8042
8420
  // Handle the 'cast' call as a special case.
@@ -8049,11 +8427,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8049
8427
  let returnType = callResult.returnType ?? types_1.UnknownType.create();
8050
8428
  let isTypeIncomplete = !!callResult.isTypeIncomplete;
8051
8429
  let argumentErrors = !!callResult.argumentErrors;
8430
+ let overloadsUsedForCall = callResult.overloadsUsedForCall;
8052
8431
  if (!argumentErrors) {
8432
+ const refinedResult = refineTypedDictMethodCallForUnionKey(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, inferenceContext);
8433
+ if (refinedResult?.isTypeIncomplete) {
8434
+ isTypeIncomplete = true;
8435
+ }
8436
+ if (refinedResult) {
8437
+ overloadsUsedForCall = refinedResult.overloadsUsedForCall;
8438
+ }
8053
8439
  // Call the function transform logic to handle special-cased functions.
8054
8440
  const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
8055
8441
  argumentErrors: !!callResult.argumentErrors,
8056
- returnType: callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
8442
+ returnType: refinedResult?.returnType ?? callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
8057
8443
  isTypeIncomplete,
8058
8444
  });
8059
8445
  returnType = transformed.returnType;
@@ -8068,7 +8454,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8068
8454
  returnType,
8069
8455
  isTypeIncomplete,
8070
8456
  argumentErrors,
8071
- overloadsUsedForCall: callResult.overloadsUsedForCall,
8457
+ overloadsUsedForCall,
8072
8458
  specializedInitSelfType: callResult.specializedInitSelfType,
8073
8459
  };
8074
8460
  }
@@ -8109,7 +8495,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8109
8495
  return prefetched.functionClass;
8110
8496
  }
8111
8497
  }
8112
- return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
8498
+ // stripLiteralValue retains sentinel literals, but type() of a
8499
+ // sentinel evaluates to its class, not the sentinel object.
8500
+ const classSubtype = (0, typeUtils_1.isSentinelLiteral)(subtype)
8501
+ ? types_1.ClassType.cloneWithLiteral(subtype, /* value */ undefined)
8502
+ : stripLiteralValue(subtype);
8503
+ return (0, typeUtils_1.convertToInstantiable)(classSubtype);
8113
8504
  }
8114
8505
  if (types_1.TypeBase.isInstance(subtype)) {
8115
8506
  if ((0, types_1.isFunction)(subtype) || (0, types_1.isTypeVar)(subtype)) {
@@ -9909,6 +10300,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
9909
10300
  addDiagnostic(diagnosticRules_1.DiagnosticRule.reportArgumentType, message + diag?.getString(), argParam.errorNode, diag?.getEffectiveTextRange() ?? argParam.errorNode);
9910
10301
  }
9911
10302
  }
10303
+ // Retain the wrapped signature for inference after an invalid descriptor
10304
+ // argument without treating the descriptor itself as callable.
10305
+ if ((0, typeUtils_1.requiresSpecialization)(argParam.paramType)) {
10306
+ let methodType = getMethodFromDescriptor(argType);
10307
+ if (methodType && (0, types_1.isOverloaded)(methodType)) {
10308
+ // Recover the runtime signature, not a single overload's
10309
+ // parameters selected when the returned decorator is called.
10310
+ const implementation = types_1.OverloadedType.getImplementation(methodType);
10311
+ if (implementation && (0, types_1.isFunction)(implementation)) {
10312
+ methodType = implementation;
10313
+ }
10314
+ }
10315
+ if (methodType) {
10316
+ const recoveryConstraints = constraints.clone();
10317
+ if (assignType(argParam.paramType, methodType,
10318
+ /* diag */ undefined, recoveryConstraints, assignTypeFlags)) {
10319
+ constraints.copyFromClone(recoveryConstraints);
10320
+ }
10321
+ }
10322
+ }
9912
10323
  return { isCompatible: false, argType, isTypeIncomplete, skippedBareTypeVarExpectedType, condition };
9913
10324
  }
9914
10325
  if (!options.skipUnknownArgCheck) {
@@ -11496,6 +11907,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
11496
11907
  }
11497
11908
  }
11498
11909
  }
11910
+ if (expectedType && !forceSpeculative && !isIncomplete) {
11911
+ captureContextualLambdaTypes(node);
11912
+ }
11499
11913
  }, {
11500
11914
  dependentType: inferenceContext?.expectedType,
11501
11915
  allowDiagnostics: !forceSpeculative && !canSkipDiagnosticForNode(node) && !inferenceContext?.isTypeIncomplete,
@@ -11506,7 +11920,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
11506
11920
  if (expectedType && !assignType(expectedType, functionType)) {
11507
11921
  typeErrors = true;
11508
11922
  }
11509
- return { type: functionType, isIncomplete, typeErrors };
11923
+ const typeResult = { type: functionType, isIncomplete, typeErrors };
11924
+ if (expectedType && !forceSpeculative && !isIncomplete) {
11925
+ captureContextualLambdaTypes(node, typeResult);
11926
+ }
11927
+ return typeResult;
11510
11928
  });
11511
11929
  }
11512
11930
  function getTypeOfComprehension(node, flags, inferenceContext) {
@@ -13666,12 +14084,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
13666
14084
  classType.shared.flags &= ~8192 /* ClassTypeFlags.PartiallyEvaluated */;
13667
14085
  // Now determine the decorated type of the class.
13668
14086
  let decoratedType = classType;
14087
+ let isDecoratedTypeUnknown = false;
13669
14088
  let foundUnknown = false;
13670
14089
  for (let i = node.d.decorators.length - 1; i >= 0; i--) {
13671
14090
  const decorator = node.d.decorators[i];
13672
- const newDecoratedType = useSignatureTracker(node.parent ?? node, () => (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator, nodeInfo));
14091
+ const newDecoratedType = useSignatureTracker(node.parent ?? node, () => (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator, nodeInfo, isDecoratedTypeUnknown));
13673
14092
  const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
13674
14093
  if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
14094
+ isDecoratedTypeUnknown = true;
13675
14095
  // Report this error only on the first unknown type.
13676
14096
  if (!foundUnknown) {
13677
14097
  addDiagnostic(diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.LocMessage.classDecoratorTypeUnknown(), node.d.decorators[i].d.expr);
@@ -13679,6 +14099,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
13679
14099
  }
13680
14100
  }
13681
14101
  else {
14102
+ // Preserving the recovery type also preserves its uncertainty.
14103
+ isDecoratedTypeUnknown = isDecoratedTypeUnknown && (0, types_1.isTypeSame)(newDecoratedType, decoratedType);
13682
14104
  // Apply the decorator only if the type is known.
13683
14105
  decoratedType = newDecoratedType;
13684
14106
  }
@@ -14212,6 +14634,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
14212
14634
  }
14213
14635
  // See if there are any overloads provided by previous function declarations.
14214
14636
  if ((0, types_1.isFunction)(decoratedType)) {
14637
+ if ((types_1.FunctionType.isClassMethod(decoratedType) || types_1.FunctionType.isStaticMethod(decoratedType)) &&
14638
+ decoratedType.shared.declaration !== functionType.shared.declaration) {
14639
+ // A wrapper can replace the signature without replacing the
14640
+ // declaration that supplies the enclosing method descriptor.
14641
+ decoratedType = types_1.FunctionType.clone(decoratedType);
14642
+ decoratedType.shared.declaration = functionType.shared.declaration;
14643
+ }
14215
14644
  decoratedType.shared.deprecatedMessage = functionType.shared.deprecatedMessage;
14216
14645
  if (types_1.FunctionType.isOverloaded(decoratedType)) {
14217
14646
  // Mark all the parameters as accessed.
@@ -18496,6 +18925,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
18496
18925
  const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
18497
18926
  (0, debug_1.assert)(memberInfo !== undefined);
18498
18927
  let destMemberType = getEffectiveTypeOfSymbol(symbol);
18928
+ // The synthesized NamedTuple _replace method adds typed field
18929
+ // parameters to typeshed's "**kwargs: Any" signature. Don't let
18930
+ // them change the variance inferred from the typeshed declaration.
18931
+ if (name === '_replace' &&
18932
+ types_1.ClassType.isNamedTupleClass(destType) &&
18933
+ symbol.getSynthesizedType() &&
18934
+ (0, types_1.isFunction)(destMemberType) &&
18935
+ types_1.FunctionType.isSynthesizedMethod(destMemberType)) {
18936
+ return;
18937
+ }
18499
18938
  const srcMemberType = getTypeOfMember(memberInfo);
18500
18939
  destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType, getTypeClassType());
18501
18940
  // Properties require special processing.
@@ -20885,7 +21324,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
20885
21324
  else if ((0, types_1.isUnknown)(narrowedType)) {
20886
21325
  return { type: (0, types_1.combineTypes)([narrowedType, declaredType]), isIncomplete: assignedTypeResult.isIncomplete };
20887
21326
  }
20888
- return { type: narrowedType, isIncomplete: assignedTypeResult.isIncomplete };
21327
+ return {
21328
+ type: narrowedType.props?.inferredTupleLiteral &&
21329
+ !assignType(declaredType, (0, types_1.getInferredTupleLiteralBase)(narrowedType))
21330
+ ? (0, types_1.preserveInferredTupleLiterals)(narrowedType)
21331
+ : narrowedType,
21332
+ isIncomplete: assignedTypeResult.isIncomplete,
21333
+ };
20889
21334
  }
20890
21335
  function validateOverrideMethod(baseMethod, overrideMethod, baseClass, diag, enforceParamNames = true) {
20891
21336
  // If we're overriding a non-method with a method, report it as an error.