@zzzen/pyright-internal 1.2.0-dev.20261004 → 1.2.0-dev.20261018

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 (108) hide show
  1. package/dist/analyzer/binder.js +8 -0
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +0 -1
  4. package/dist/analyzer/checker.js +21 -42
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/codeFlowEngine.js +75 -28
  7. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  8. package/dist/analyzer/constraintSolver.js +3 -2
  9. package/dist/analyzer/constraintSolver.js.map +1 -1
  10. package/dist/analyzer/operations.d.ts +2 -0
  11. package/dist/analyzer/operations.js +2 -1
  12. package/dist/analyzer/operations.js.map +1 -1
  13. package/dist/analyzer/overloadResultAdmission.js +115 -3
  14. package/dist/analyzer/overloadResultAdmission.js.map +1 -1
  15. package/dist/analyzer/overloadResultController.js +36 -10
  16. package/dist/analyzer/overloadResultController.js.map +1 -1
  17. package/dist/analyzer/overloadResultSelector.js +32 -12
  18. package/dist/analyzer/overloadResultSelector.js.map +1 -1
  19. package/dist/analyzer/parameterUtils.js +2 -1
  20. package/dist/analyzer/parameterUtils.js.map +1 -1
  21. package/dist/analyzer/parseTreeUtils.d.ts +1 -0
  22. package/dist/analyzer/parseTreeUtils.js +13 -0
  23. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  24. package/dist/analyzer/patternMatching.js +105 -35
  25. package/dist/analyzer/patternMatching.js.map +1 -1
  26. package/dist/analyzer/program.d.ts +3 -0
  27. package/dist/analyzer/program.js +34 -9
  28. package/dist/analyzer/program.js.map +1 -1
  29. package/dist/analyzer/properties.d.ts +2 -2
  30. package/dist/analyzer/properties.js +2 -2
  31. package/dist/analyzer/properties.js.map +1 -1
  32. package/dist/analyzer/protocols.d.ts +3 -1
  33. package/dist/analyzer/protocols.js +24 -2
  34. package/dist/analyzer/protocols.js.map +1 -1
  35. package/dist/analyzer/service.js +6 -2
  36. package/dist/analyzer/service.js.map +1 -1
  37. package/dist/analyzer/sourceEnumerator.d.ts +3 -1
  38. package/dist/analyzer/sourceEnumerator.js +30 -11
  39. package/dist/analyzer/sourceEnumerator.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/tuples.js +17 -6
  44. package/dist/analyzer/tuples.js.map +1 -1
  45. package/dist/analyzer/typeEvaluator.js +419 -67
  46. package/dist/analyzer/typeEvaluator.js.map +1 -1
  47. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -1
  48. package/dist/analyzer/typeEvaluatorTypes.js +4 -0
  49. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  50. package/dist/analyzer/typeGuards.d.ts +5 -1
  51. package/dist/analyzer/typeGuards.js +324 -99
  52. package/dist/analyzer/typeGuards.js.map +1 -1
  53. package/dist/analyzer/typePrinter.js +32 -6
  54. package/dist/analyzer/typePrinter.js.map +1 -1
  55. package/dist/analyzer/typeStubRenderer.d.ts +6 -1
  56. package/dist/analyzer/typeStubRenderer.js +19 -12
  57. package/dist/analyzer/typeStubRenderer.js.map +1 -1
  58. package/dist/analyzer/typeUtils.d.ts +1 -0
  59. package/dist/analyzer/typeUtils.js +15 -1
  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 +2 -1
  65. package/dist/analyzer/types.js +9 -0
  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/windowsProcessTree.json +252 -33
  71. package/dist/tests/cacheManager.test.js +19 -15
  72. package/dist/tests/cacheManager.test.js.map +1 -1
  73. package/dist/tests/checker.test.js +50 -0
  74. package/dist/tests/checker.test.js.map +1 -1
  75. package/dist/tests/config.test.js +126 -0
  76. package/dist/tests/config.test.js.map +1 -1
  77. package/dist/tests/constraintSolver.test.d.ts +1 -0
  78. package/dist/tests/constraintSolver.test.js +39 -0
  79. package/dist/tests/constraintSolver.test.js.map +1 -0
  80. package/dist/tests/fourslash/hover.typedDict.get.fourslash.js +11 -0
  81. package/dist/tests/fourslash/hover.typedDict.get.fourslash.js.map +1 -1
  82. package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.d.ts +1 -0
  83. package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js +16 -0
  84. package/dist/tests/fourslash/hover.typedDictUnpacking.dictDisplay.fourslash.js.map +1 -0
  85. package/dist/tests/mypyPrimerAnalysis.test.js +67 -11
  86. package/dist/tests/mypyPrimerAnalysis.test.js.map +1 -1
  87. package/dist/tests/overloadResultController.test.js +379 -1
  88. package/dist/tests/overloadResultController.test.js.map +1 -1
  89. package/dist/tests/signatureHelp.test.js +34 -0
  90. package/dist/tests/signatureHelp.test.js.map +1 -1
  91. package/dist/tests/sourceEnumeratorSymlink.test.js +98 -13
  92. package/dist/tests/sourceEnumeratorSymlink.test.js.map +1 -1
  93. package/dist/tests/sourceMapperUtils.test.js +143 -0
  94. package/dist/tests/sourceMapperUtils.test.js.map +1 -1
  95. package/dist/tests/typeEquality.test.js +85 -2
  96. package/dist/tests/typeEquality.test.js.map +1 -1
  97. package/dist/tests/typeEvaluator1.test.js +47 -3
  98. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  99. package/dist/tests/typeEvaluator3.test.js +23 -0
  100. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  101. package/dist/tests/typeEvaluator5.test.js +1 -1
  102. package/dist/tests/typeEvaluator6.test.js +83 -1
  103. package/dist/tests/typeEvaluator6.test.js.map +1 -1
  104. package/dist/tests/typeEvaluator7.test.js +32 -0
  105. package/dist/tests/typeEvaluator7.test.js.map +1 -1
  106. package/dist/tests/typeEvaluator8.test.js +15 -1
  107. package/dist/tests/typeEvaluator8.test.js.map +1 -1
  108. 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,8 +204,10 @@ 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();
210
+ let exceptionTargetSymbolCache = new Map();
208
211
  let expectedTypeCache = new Map();
209
212
  let asymmetricAccessorAssignmentCache = new Set();
210
213
  let deferredClassCompletions = [];
@@ -272,6 +275,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
272
275
  typeCache = new Map();
273
276
  typeFormTypeCache = new Map();
274
277
  effectiveTypeCache = new Map();
278
+ exceptionTargetSymbolCache = new Map();
275
279
  expectedTypeCache = new Map();
276
280
  asymmetricAccessorAssignmentCache = new Set();
277
281
  }
@@ -397,6 +401,55 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
397
401
  function setTypeResultForNode(node, typeResult, flags = 0 /* EvalFlags.None */) {
398
402
  writeTypeCache(node, typeResult, flags);
399
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
+ }
400
453
  function getMaxCodeComplexity() {
401
454
  return maxCodeComplexity;
402
455
  }
@@ -4945,8 +4998,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
4945
4998
  }
4946
4999
  // Determine if we're calling __set__ on an asymmetric descriptor or property.
4947
5000
  let isAsymmetricAccessor = false;
4948
- if (usage.method === 'set' && (0, types_1.isClass)(methodClassType)) {
4949
- if (isAsymmetricDescriptorClass(methodClassType)) {
5001
+ if (usage.method === 'set') {
5002
+ if (isAsymmetricDescriptorClass(concreteMemberType)) {
4950
5003
  isAsymmetricAccessor = true;
4951
5004
  }
4952
5005
  }
@@ -5136,14 +5189,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
5136
5189
  return classType.priv.isAsymmetricDescriptor;
5137
5190
  }
5138
5191
  let isAsymmetric = false;
5139
- const getterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__get__', 2 /* MemberAccessFlags.SkipBaseClasses */);
5140
- const setterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__set__', 2 /* MemberAccessFlags.SkipBaseClasses */);
5192
+ // Accessors can be defined at different levels of the descriptor's MRO.
5193
+ // Ignore instance members so an instance attribute that happens to share
5194
+ // a dunder name doesn't shadow the descriptor protocol during this check.
5195
+ const accessorFlags = 16 /* MemberAccessFlags.SkipInstanceMembers */ | 512 /* MemberAccessFlags.SkipAttributeAccessOverride */;
5196
+ const getterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__get__', accessorFlags);
5197
+ const setterSymbolResult = (0, typeUtils_1.lookUpClassMember)(classType, '__set__', accessorFlags);
5141
5198
  if (!getterSymbolResult || !setterSymbolResult) {
5142
5199
  isAsymmetric = false;
5143
5200
  }
5144
5201
  else {
5145
5202
  let getterType = getTypeOfMember(getterSymbolResult);
5146
- const setterType = getTypeOfMember(setterSymbolResult);
5203
+ let setterType = getTypeOfMember(setterSymbolResult);
5204
+ // The getter and setter can be declared on different classes. Specialize
5205
+ // both against the concrete descriptor class so Self and inherited type
5206
+ // variables are compared in the same context.
5207
+ if (getterSymbolResult.classType && (0, types_1.isInstantiableClass)(getterSymbolResult.classType)) {
5208
+ getterType = (0, typeUtils_1.partiallySpecializeType)(getterType, getterSymbolResult.classType, getTypeClassType(), classType);
5209
+ }
5210
+ if (setterSymbolResult.classType && (0, types_1.isInstantiableClass)(setterSymbolResult.classType)) {
5211
+ setterType = (0, typeUtils_1.partiallySpecializeType)(setterType, setterSymbolResult.classType, getTypeClassType(), classType);
5212
+ }
5147
5213
  // If this is an overload, find the appropriate overload.
5148
5214
  if ((0, types_1.isOverloaded)(getterType)) {
5149
5215
  const getOverloads = types_1.OverloadedType.getOverloads(getterType).filter((overload) => {
@@ -6085,12 +6151,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
6085
6151
  }
6086
6152
  }
6087
6153
  }
6088
- else if ((0, types_1.isClassInstance)(valueType) && types_1.ClassType.isBuiltIn(valueType, 'slice')) {
6154
+ else if (usage.method === 'get' &&
6155
+ index0Expr.nodeType === 46 /* ParseNodeType.Slice */ &&
6156
+ (0, types_1.isClassInstance)(valueType) &&
6157
+ types_1.ClassType.isBuiltIn(valueType, 'slice')) {
6089
6158
  const tupleType = (0, typeUtils_1.getSpecializedTupleType)(baseType);
6090
- if (tupleType && index0Expr.nodeType === 46 /* ParseNodeType.Slice */) {
6091
- const slicedTupleType = (0, tuples_1.getSlicedTupleType)(evaluatorInterface, tupleType, index0Expr);
6092
- if (slicedTupleType) {
6093
- return { type: slicedTupleType };
6159
+ if (tupleType) {
6160
+ // Skip this if a subclass overrides the tuple's __getitem__ method.
6161
+ const getItemMember = (0, typeUtils_1.lookUpObjectMember)(baseType, '__getitem__', 16 /* MemberAccessFlags.SkipInstanceMembers */);
6162
+ const isTupleGetItem = !getItemMember ||
6163
+ ((0, types_1.isInstantiableClass)(getItemMember.classType) &&
6164
+ types_1.ClassType.isBuiltIn(getItemMember.classType, 'tuple'));
6165
+ if (isTupleGetItem) {
6166
+ const slicedTupleType = (0, tuples_1.getSlicedTupleType)(evaluatorInterface, tupleType, index0Expr);
6167
+ if (slicedTupleType) {
6168
+ return { type: slicedTupleType };
6169
+ }
6094
6170
  }
6095
6171
  }
6096
6172
  }
@@ -7203,7 +7279,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7203
7279
  // there will be only one argument list in expandedArgTypes, and all entries
7204
7280
  // (one for each argument) will be undefined. On subsequent calls, this
7205
7281
  // list will grow to include union expansions.
7206
- function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext) {
7282
+ function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, constraints, skipUnknownArgCheck, inferenceContext, skipFinalValidation = false) {
7207
7283
  const returnTypes = [];
7208
7284
  const specializedInitSelfTypes = [];
7209
7285
  let matchedOverloads = [];
@@ -7246,17 +7322,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7246
7322
  if (!callResult.argumentErrors && callResult.returnType) {
7247
7323
  if (evaluatorOptions.experimentalOverloadResult &&
7248
7324
  !callResult.isTypeIncomplete &&
7249
- !overload.priv.boundToType &&
7250
- !overload.shared.methodClass &&
7251
- !overload.shared.declaration?.isMethod &&
7252
7325
  errorNode.nodeType === 9 /* ParseNodeType.Call */ &&
7253
- errorNode.d.leftExpr.nodeType === 38 /* ParseNodeType.Name */ &&
7254
- errorNode.parent?.nodeType === 3 /* ParseNodeType.Assignment */ &&
7255
- errorNode.parent.d.rightExpr === errorNode &&
7326
+ (0, overloadResultSelector_1.isAutomaticOverloadSeedSyntax)(errorNode) &&
7256
7327
  expandedArgTypes.length === 1 &&
7257
- !hasArgTypeOverride &&
7258
- callResult.argResults) {
7259
- evaluatorOptions.experimentalOverloadResult.considerActivation(errorNode, callResult.argResults);
7328
+ !hasArgTypeOverride) {
7329
+ const receiver = overload.priv.boundToType;
7330
+ evaluatorOptions.experimentalOverloadResult.considerActivation(errorNode, receiver && (0, types_1.isClassInstance)(receiver)
7331
+ ? [{ argType: receiver }, ...(callResult.argResults ?? [])]
7332
+ : callResult.argResults ?? []);
7260
7333
  }
7261
7334
  overloadsUsedForCall.push(overload);
7262
7335
  matchedOverload = overload;
@@ -7375,6 +7448,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7375
7448
  if (constraints && isDefinitiveMatchFound) {
7376
7449
  constraints.copyFromClone(matchedOverloads[matchedOverloads.length - 1].constraints);
7377
7450
  }
7451
+ // A speculative refinement does not need to populate the type cache;
7452
+ // the original call has already performed the normal final validation.
7453
+ if (skipFinalValidation) {
7454
+ return {
7455
+ argumentErrors: false,
7456
+ returnType: (0, types_1.combineTypes)(returnTypes),
7457
+ isTypeIncomplete,
7458
+ overloadsUsedForCall,
7459
+ };
7460
+ }
7378
7461
  // And run through the first expanded argument list one more time to
7379
7462
  // populate the type cache, without applying a different branch's constraints.
7380
7463
  const finalConstraints = expandedArgTypes.length > 1
@@ -7503,10 +7586,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7503
7586
  name: arg.d.name,
7504
7587
  }));
7505
7588
  const sources = node.d.args.map((arg) => getTypeOfExpression(arg.d.valueExpr));
7506
- if (sources.some((s) => s.isIncomplete || s.typeErrors || (0, types_1.isAny)(s.type) || !(0, overloadResultSelector_1.isFixedOverloadArgumentShape)(s.type, budget))) {
7589
+ const receiver = node.d.leftExpr.nodeType === 35 /* ParseNodeType.MemberAccess */
7590
+ ? getTypeOfExpression(node.d.leftExpr.d.leftExpr)
7591
+ : undefined;
7592
+ if ([...sources, ...(receiver ? [receiver] : [])].some((s) => s.isIncomplete || s.typeErrors || (0, types_1.isAny)(s.type) || !(0, overloadResultSelector_1.isFixedOverloadArgumentShape)(s.type, budget))) {
7507
7593
  return decline('unsupported-argument-shape');
7508
7594
  }
7509
- if (!sources.some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
7595
+ if (![...sources, ...(receiver ? [receiver] : [])].some((s) => (0, overloadResultSelector_1.hasNestedOverloadAny)(s.type))) {
7510
7596
  return decline('no-invariant-any');
7511
7597
  }
7512
7598
  const returns = [];
@@ -7516,10 +7602,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7516
7602
  const declaration = overload.shared.declaration;
7517
7603
  const declaredReturnType = overload.shared.declaredReturnType;
7518
7604
  const returnType = types_1.FunctionType.getEffectiveReturnType(overload);
7605
+ const receiverParam = overload.priv.strippedFirstParamType;
7606
+ const supportedBinding = receiver
7607
+ ? declaration?.isMethod &&
7608
+ types_1.FunctionType.isInstanceMethod(overload) &&
7609
+ overload.priv.boundToType &&
7610
+ (0, types_1.isClassInstance)(overload.priv.boundToType) &&
7611
+ receiverParam &&
7612
+ (0, types_1.isClassInstance)(receiverParam) &&
7613
+ (0, types_1.isClassInstance)(receiver.type) &&
7614
+ types_1.ClassType.isSameGenericClass(receiver.type, receiverParam) &&
7615
+ overload.shared.methodClass &&
7616
+ types_1.ClassType.isSameGenericClass(receiver.type, types_1.ClassType.cloneAsInstance(overload.shared.methodClass)) &&
7617
+ (0, overloadResultSelector_1.isFixedOverloadArgumentShape)(receiverParam, budget)
7618
+ : !declaration?.isMethod && !overload.shared.methodClass && !overload.priv.boundToType;
7519
7619
  if (!declaration ||
7520
- declaration.isMethod ||
7521
- overload.shared.methodClass ||
7522
- overload.priv.boundToType ||
7620
+ !supportedBinding ||
7523
7621
  overload.shared.typeParams.length ||
7524
7622
  !declaredReturnType ||
7525
7623
  !returnType ||
@@ -7561,6 +7659,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7561
7659
  continue;
7562
7660
  }
7563
7661
  const proof = mapping.argParams.map((p, i) => (0, overloadResultSelector_1.getFixedOverloadCoverage)(sources[i].type, p.paramType, budget));
7662
+ if (receiver && receiverParam) {
7663
+ proof.unshift((0, overloadResultSelector_1.getFixedOverloadCoverage)(receiver.type, receiverParam, budget));
7664
+ }
7564
7665
  const covered = proof.includes('unsupported')
7565
7666
  ? 'unsupported'
7566
7667
  : proof.includes('not-covered')
@@ -7585,11 +7686,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7585
7686
  : decline('equivalent-or-single-return');
7586
7687
  });
7587
7688
  }
7588
- function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext) {
7689
+ function validateOverloadedArgTypes(errorNode, argList, typeResult, constraints, skipUnknownArgCheck, inferenceContext, candidateOverloads) {
7589
7690
  const filteredMatchResults = [];
7590
7691
  let contextFreeArgTypes;
7591
7692
  let isTypeIncomplete = !!typeResult.isIncomplete;
7592
7693
  const type = typeResult.type;
7694
+ const overloads = candidateOverloads ?? types_1.OverloadedType.getOverloads(type);
7593
7695
  const speculativeNode = getSpeculativeNodeForCall(errorNode);
7594
7696
  // Start by evaluating the types of the arguments without any expected
7595
7697
  // type. Also, filter the list of overloads based on the number of
@@ -7598,7 +7700,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7598
7700
  // cache or record any diagnostics at this stage.
7599
7701
  useSpeculativeMode(speculativeNode, () => {
7600
7702
  let overloadIndex = 0;
7601
- types_1.OverloadedType.getOverloads(type).forEach((overload) => {
7703
+ overloads.forEach((overload) => {
7602
7704
  // Consider only the functions that have the @overload decorator,
7603
7705
  // not the final function that omits the overload. This is the
7604
7706
  // intended behavior according to PEP 484.
@@ -7615,7 +7717,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7615
7717
  // Skip the error message if we're in speculative mode because it's very
7616
7718
  // expensive, and we're going to suppress the diagnostic anyway.
7617
7719
  if (!canSkipDiagnosticForNode(errorNode)) {
7618
- const overloads = types_1.OverloadedType.getOverloads(type);
7619
7720
  const functionName = overloads.length > 0 && overloads[0].shared.name
7620
7721
  ? overloads[0].shared.name
7621
7722
  : '<anonymous function>';
@@ -7670,7 +7771,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7670
7771
  }
7671
7772
  let expandedArgTypes = [argList.map((arg) => undefined)];
7672
7773
  while (true) {
7673
- const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext);
7774
+ const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, constraints, skipUnknownArgCheck, inferenceContext,
7775
+ /* skipFinalValidation */ candidateOverloads !== undefined);
7674
7776
  if (callResult.isTypeIncomplete) {
7675
7777
  isTypeIncomplete = true;
7676
7778
  }
@@ -7805,24 +7907,51 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
7805
7907
  }), exprNode);
7806
7908
  return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
7807
7909
  }
7808
- let returnType = mapSubtypesExpandTypeVars(callTypeResult.type, { sortSubtypes: true }, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
7809
- return useSpeculativeMode(isLastIteration ? undefined : getSpeculativeNodeForCall(errorNode), () => {
7810
- const callResult = validateCallArgsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, constraints, skipUnknownArgCheck, inferenceContext, recursionCount);
7811
- if (callResult.argumentErrors) {
7812
- argumentErrors = true;
7813
- }
7814
- if (callResult.isTypeIncomplete) {
7815
- isTypeIncomplete = true;
7816
- }
7817
- if (callResult.overloadsUsedForCall) {
7818
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
7910
+ const concreteCallType = makeTopLevelTypeVarsConcrete(callTypeResult.type);
7911
+ const lambdaNodes = (0, types_1.isUnion)(concreteCallType)
7912
+ ? argList
7913
+ .map((arg) => arg.valueExpression)
7914
+ .filter((node) => node?.nodeType === 33 /* ParseNodeType.Lambda */)
7915
+ : undefined;
7916
+ const lambdaTypeCache = lambdaNodes?.length
7917
+ ? { lambdaNodes, entries: new Map(), branchIndex: 0 }
7918
+ : undefined;
7919
+ const previousCache = contextualLambdaTypeCache;
7920
+ let returnType;
7921
+ try {
7922
+ if (lambdaTypeCache) {
7923
+ contextualLambdaTypeCache = lambdaTypeCache;
7924
+ }
7925
+ returnType = mapSubtypesExpandTypeVars(callTypeResult.type, { sortSubtypes: true }, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
7926
+ if (lambdaTypeCache) {
7927
+ lambdaTypeCache.branchIndex++;
7819
7928
  }
7820
- specializedInitSelfType = callResult.specializedInitSelfType;
7821
- return callResult.returnType;
7822
- }, {
7823
- allowDiagnostics: true,
7929
+ return useSpeculativeMode(isLastIteration ? undefined : getSpeculativeNodeForCall(errorNode), () => {
7930
+ const callResult = validateCallArgsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, constraints, skipUnknownArgCheck, inferenceContext, recursionCount);
7931
+ if (callResult.argumentErrors) {
7932
+ argumentErrors = true;
7933
+ }
7934
+ if (callResult.isTypeIncomplete) {
7935
+ isTypeIncomplete = true;
7936
+ }
7937
+ if (callResult.overloadsUsedForCall) {
7938
+ (0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
7939
+ }
7940
+ specializedInitSelfType = callResult.specializedInitSelfType;
7941
+ return callResult.returnType;
7942
+ }, {
7943
+ allowDiagnostics: true,
7944
+ });
7824
7945
  });
7825
- });
7946
+ }
7947
+ finally {
7948
+ contextualLambdaTypeCache = previousCache;
7949
+ }
7950
+ // Keep branch-specific checking and return inference separate from the
7951
+ // combined contextual types retained for subsequent queries.
7952
+ if (!isTypeIncomplete && lambdaTypeCache && lambdaTypeCache.branchIndex > 1) {
7953
+ (0, cancellationUtils_1.invalidateTypeCacheIfCanceled)(() => combineContextualLambdaTypes(lambdaTypeCache));
7954
+ }
7826
7955
  // If we ended up with a "Never" type because all code paths returned
7827
7956
  // undefined due to argument errors, transform the result into an Unknown
7828
7957
  // to avoid subsequent false positives.
@@ -8022,6 +8151,110 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8022
8151
  }
8023
8152
  return { symbol, symbolName, classType, hasImplementation };
8024
8153
  }
8154
+ // The synthesized "get" and "pop" methods for a TypedDict include a
8155
+ // catch-all overload that accepts any str key. When the key argument is a
8156
+ // union of str literals, that catch-all overload matches before union
8157
+ // expansion is attempted, which produces an overly-wide return type. This
8158
+ // function evaluates the call separately for each literal key subtype
8159
+ // (speculatively) and, if every subtype is accepted, returns the union of
8160
+ // the resulting return types.
8161
+ function refineTypedDictMethodCallForUnionKey(errorNode, argList, overloadedType, isCallTypeIncomplete, constraints, inferenceContext) {
8162
+ const overloads = types_1.OverloadedType.getOverloads(overloadedType);
8163
+ const overload = overloads[0];
8164
+ if (!overload || !types_1.FunctionType.isSynthesizedMethod(overload)) {
8165
+ return undefined;
8166
+ }
8167
+ const methodName = overload.shared.name;
8168
+ if (methodName !== 'get' && methodName !== 'pop') {
8169
+ return undefined;
8170
+ }
8171
+ const isBound = (0, types_1.isMethodType)(overload);
8172
+ const receiverType = isBound
8173
+ ? overload.priv.strippedFirstParamType
8174
+ : overload.shared.parameters.length > 0
8175
+ ? types_1.FunctionType.getParamType(overload, 0)
8176
+ : undefined;
8177
+ if (!receiverType || !(0, types_1.isClassInstance)(receiverType) || !types_1.ClassType.isTypedDictClass(receiverType)) {
8178
+ return undefined;
8179
+ }
8180
+ // Unbound generic methods have not specialized their field types from the
8181
+ // receiver. Keep the normal result rather than refining it to Unknown.
8182
+ if (!isBound &&
8183
+ ((0, typeUtils_1.requiresSpecialization)(receiverType) || (0, typeUtils_1.containsAnyOrUnknown)(receiverType, /* recurse */ true))) {
8184
+ return undefined;
8185
+ }
8186
+ // Handle only simple positional calls: (key) or (key, default).
8187
+ const keyIndex = isBound ? 0 : 1;
8188
+ if (argList.length <= keyIndex || argList.length > keyIndex + 2) {
8189
+ return undefined;
8190
+ }
8191
+ if (!argList.every((arg) => !arg.name && arg.argCategory === 0 /* ArgCategory.Simple */)) {
8192
+ return undefined;
8193
+ }
8194
+ const keyArg = argList[keyIndex];
8195
+ const keyTypeResult = keyArg.typeResult ?? (keyArg.valueExpression ? getTypeOfExpression(keyArg.valueExpression) : undefined);
8196
+ if (!keyTypeResult || !(0, types_1.isUnion)(keyTypeResult.type)) {
8197
+ return undefined;
8198
+ }
8199
+ // Every subtype must be a str literal; otherwise keep the normal result.
8200
+ const keySubtypes = [];
8201
+ let allStrLiterals = true;
8202
+ (0, typeUtils_1.doForEachSubtype)(keyTypeResult.type, (subtype) => {
8203
+ if ((0, types_1.isClassInstance)(subtype) &&
8204
+ types_1.ClassType.isBuiltIn(subtype, 'str') &&
8205
+ typeof subtype.priv.literalValue === 'string') {
8206
+ keySubtypes.push(subtype);
8207
+ }
8208
+ else {
8209
+ allStrLiterals = false;
8210
+ }
8211
+ });
8212
+ if (!allStrLiterals || keySubtypes.length < 2 || keySubtypes.length > maxSingleOverloadArgTypeExpansionCount) {
8213
+ return undefined;
8214
+ }
8215
+ let isTypeIncomplete = !!keyTypeResult.isIncomplete;
8216
+ const returnTypes = [];
8217
+ const overloadsUsedForCall = new Set();
8218
+ const succeeded = useSpeculativeMode(getSpeculativeNodeForCall(errorNode), () => {
8219
+ for (const keySubtype of keySubtypes) {
8220
+ // Avoid revalidating unrelated keys and their default parameters.
8221
+ const candidates = overloads.filter((candidate) => {
8222
+ const paramType = types_1.FunctionType.getParamType(candidate, keyIndex);
8223
+ return ((0, types_1.isClassInstance)(paramType) &&
8224
+ types_1.ClassType.isBuiltIn(paramType, 'str') &&
8225
+ (paramType.priv.literalValue === undefined ||
8226
+ paramType.priv.literalValue === keySubtype.priv.literalValue));
8227
+ });
8228
+ if (candidates.length === 0) {
8229
+ return false;
8230
+ }
8231
+ const subtypeArgList = [...argList];
8232
+ subtypeArgList[keyIndex] = {
8233
+ argCategory: 0 /* ArgCategory.Simple */,
8234
+ typeResult: { type: keySubtype, isIncomplete: keyTypeResult.isIncomplete },
8235
+ };
8236
+ const subtypeResult = validateOverloadedArgTypes(errorNode, subtypeArgList, { type: overloadedType, isIncomplete: isCallTypeIncomplete }, constraints?.clone(),
8237
+ /* skipUnknownArgCheck */ true, inferenceContext, candidates);
8238
+ if (subtypeResult.isTypeIncomplete) {
8239
+ isTypeIncomplete = true;
8240
+ }
8241
+ if (subtypeResult.argumentErrors || !subtypeResult.returnType) {
8242
+ return false;
8243
+ }
8244
+ returnTypes.push(subtypeResult.returnType);
8245
+ subtypeResult.overloadsUsedForCall?.forEach((matched) => overloadsUsedForCall.add(matched));
8246
+ }
8247
+ return true;
8248
+ });
8249
+ if (!succeeded) {
8250
+ return undefined;
8251
+ }
8252
+ return {
8253
+ returnType: (0, types_1.combineTypes)(returnTypes),
8254
+ isTypeIncomplete,
8255
+ overloadsUsedForCall: [...overloadsUsedForCall],
8256
+ };
8257
+ }
8025
8258
  function validateCallForOverloaded(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, skipUnknownArgCheck, inferenceContext) {
8026
8259
  const overloads = types_1.OverloadedType.getOverloads(expandedCallType);
8027
8260
  // Handle the 'cast' call as a special case.
@@ -8034,11 +8267,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8034
8267
  let returnType = callResult.returnType ?? types_1.UnknownType.create();
8035
8268
  let isTypeIncomplete = !!callResult.isTypeIncomplete;
8036
8269
  let argumentErrors = !!callResult.argumentErrors;
8270
+ let overloadsUsedForCall = callResult.overloadsUsedForCall;
8037
8271
  if (!argumentErrors) {
8272
+ const refinedResult = refineTypedDictMethodCallForUnionKey(errorNode, argList, expandedCallType, isCallTypeIncomplete, constraints, inferenceContext);
8273
+ if (refinedResult?.isTypeIncomplete) {
8274
+ isTypeIncomplete = true;
8275
+ }
8276
+ if (refinedResult) {
8277
+ overloadsUsedForCall = refinedResult.overloadsUsedForCall;
8278
+ }
8038
8279
  // Call the function transform logic to handle special-cased functions.
8039
8280
  const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
8040
8281
  argumentErrors: !!callResult.argumentErrors,
8041
- returnType: callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
8282
+ returnType: refinedResult?.returnType ?? callResult.returnType ?? types_1.UnknownType.create(isTypeIncomplete),
8042
8283
  isTypeIncomplete,
8043
8284
  });
8044
8285
  returnType = transformed.returnType;
@@ -8053,7 +8294,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
8053
8294
  returnType,
8054
8295
  isTypeIncomplete,
8055
8296
  argumentErrors,
8056
- overloadsUsedForCall: callResult.overloadsUsedForCall,
8297
+ overloadsUsedForCall,
8057
8298
  specializedInitSelfType: callResult.specializedInitSelfType,
8058
8299
  };
8059
8300
  }
@@ -10922,7 +11163,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
10922
11163
  const tdEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface, unexpandedType,
10923
11164
  /* allowNarrowed */ true);
10924
11165
  tdEntries.knownItems.forEach((entry, name) => {
10925
- if (entry.isRequired || entry.isProvided) {
11166
+ if (!expectedTypedDictEntries || entry.isRequired || entry.isProvided) {
10926
11167
  keyTypes.push({
10927
11168
  node: entryNode,
10928
11169
  type: types_1.ClassType.cloneWithLiteral(strObject, name),
@@ -10931,6 +11172,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
10931
11172
  }
10932
11173
  });
10933
11174
  if (!expectedTypedDictEntries) {
11175
+ // Open TypedDicts can contain extra items with arbitrary value types.
10934
11176
  keyTypes.push({ node: entryNode, type: types_1.ClassType.cloneAsInstance(strObject) });
10935
11177
  valueTypes.push({
10936
11178
  node: entryNode,
@@ -11330,27 +11572,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
11330
11572
  // Pre-cache the incomplete function type in case the evaluation of the
11331
11573
  // lambda depends on itself.
11332
11574
  writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* EvalFlags.None */);
11333
- // We assume for simplicity that the parameter signature of the lambda is
11334
- // the same as the expected type. If this isn't the case, we'll use
11335
- // object for any lambda parameters that don't match. We could make this
11336
- // more sophisticated in the future, but it becomes very complex to handle
11337
- // all of the permutations.
11575
+ // Match positional parameters in order, but allow keyword-only parameters
11576
+ // to be reordered. Unmatched parameters without defaults use Unknown.
11338
11577
  let sawParamMismatch = false;
11578
+ let expectedParamIndex = 0;
11579
+ let expectedKeywordParams;
11580
+ const positionOnlySeparatorIndex = node.d.params.findIndex((param) => param.d.category === 0 /* ParamCategory.Simple */ && !param.d.name);
11339
11581
  node.d.params.forEach((param, index) => {
11340
11582
  let paramType;
11341
11583
  if (expectedParamDetails && !sawParamMismatch) {
11342
- if (index < expectedParamDetails.params.length) {
11343
- const expectedParam = expectedParamDetails.params[index];
11584
+ const isKeywordOnlySeparator = param.d.category === 1 /* ParamCategory.ArgsList */ && !param.d.name;
11585
+ if (isKeywordOnlySeparator) {
11586
+ if (expectedParamIndex < expectedParamDetails.params.length &&
11587
+ expectedParamDetails.params[expectedParamIndex].kind !== parameterUtils_1.ParamKind.Keyword) {
11588
+ sawParamMismatch = true;
11589
+ }
11590
+ }
11591
+ else if (expectedParamIndex < expectedParamDetails.params.length) {
11592
+ let expectedParam = expectedParamDetails.params[expectedParamIndex];
11593
+ const isPositionOnlyParam = (positionOnlySeparatorIndex >= 0 && index < positionOnlySeparatorIndex) ||
11594
+ (positionOnlySeparatorIndex < 0 &&
11595
+ paramsArePositionOnly &&
11596
+ !!param.d.name &&
11597
+ (0, symbolNameUtils_1.isPrivateName)(param.d.name.d.value));
11598
+ if (expectedParam.kind === parameterUtils_1.ParamKind.Keyword &&
11599
+ expectedParam.param.category === 0 /* ParamCategory.Simple */ &&
11600
+ param.d.category === 0 /* ParamCategory.Simple */ &&
11601
+ param.d.name &&
11602
+ !isPositionOnlyParam &&
11603
+ param.d.name.d.value !== expectedParam.param.name) {
11604
+ if (!expectedKeywordParams) {
11605
+ expectedKeywordParams = new Map();
11606
+ for (const keywordParam of expectedParamDetails.params) {
11607
+ if (keywordParam.kind === parameterUtils_1.ParamKind.Keyword &&
11608
+ keywordParam.param.category === 0 /* ParamCategory.Simple */ &&
11609
+ keywordParam.param.name) {
11610
+ expectedKeywordParams.set(keywordParam.param.name, keywordParam);
11611
+ }
11612
+ }
11613
+ }
11614
+ expectedParam = expectedKeywordParams.get(param.d.name.d.value) ?? expectedParam;
11615
+ }
11616
+ const isCompatibleKeywordParam = expectedParam.kind !== parameterUtils_1.ParamKind.Keyword ||
11617
+ expectedParam.param.category === 2 /* ParamCategory.KwargsDict */ ||
11618
+ (!isPositionOnlyParam && param.d.name?.d.value === expectedParam.param.name);
11344
11619
  // If the parameter category matches and both of the parameters are
11345
11620
  // either separators (/ or *) or not separators, copy the type
11346
11621
  // from the expected parameter.
11347
11622
  if (expectedParam.param.category === param.d.category &&
11348
- !param.d.name === !expectedParam.param.name) {
11623
+ !param.d.name === !expectedParam.param.name &&
11624
+ isCompatibleKeywordParam) {
11349
11625
  paramType = expectedParam.type;
11350
11626
  }
11351
11627
  else {
11352
11628
  sawParamMismatch = true;
11353
11629
  }
11630
+ expectedParamIndex++;
11354
11631
  }
11355
11632
  else if (param.d.defaultValue) {
11356
11633
  // If the lambda param has a default value but there is no associated
@@ -11365,15 +11642,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
11365
11642
  // use the default value to infer the parameter's type.
11366
11643
  paramType = inferParamTypeFromDefaultValue(param.d.defaultValue);
11367
11644
  }
11645
+ if (param.d.defaultValue) {
11646
+ const defaultValueResult = getTypeOfExpression(param.d.defaultValue, 1 /* EvalFlags.ConvertEllipsisToAny */, (0, typeUtils_1.makeInferenceContext)(paramType));
11647
+ if (defaultValueResult.isIncomplete) {
11648
+ isIncomplete = true;
11649
+ }
11650
+ // The lambda can also be called with its own default value.
11651
+ if (paramType && !assignType(paramType, defaultValueResult.type)) {
11652
+ paramType = (0, types_1.combineTypes)([paramType, stripLiteralValue(defaultValueResult.type)]);
11653
+ }
11654
+ }
11368
11655
  if (param.d.name) {
11369
11656
  writeTypeCache(param.d.name, {
11370
11657
  type: transformVariadicParamType(node, param.d.category, paramType ?? types_1.UnknownType.create()),
11371
11658
  }, 0 /* EvalFlags.None */);
11372
11659
  }
11373
- if (param.d.defaultValue) {
11374
- // Evaluate the default value if it's present.
11375
- getTypeOfExpression(param.d.defaultValue, 1 /* EvalFlags.ConvertEllipsisToAny */);
11376
- }
11377
11660
  // Determine whether we need to insert an implied position-only parameter.
11378
11661
  // This is needed when a function's parameters are named using the old-style
11379
11662
  // way of specifying position-only parameters.
@@ -11439,6 +11722,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
11439
11722
  }
11440
11723
  }
11441
11724
  }
11725
+ if (expectedType && !forceSpeculative && !isIncomplete) {
11726
+ captureContextualLambdaTypes(node);
11727
+ }
11442
11728
  }, {
11443
11729
  dependentType: inferenceContext?.expectedType,
11444
11730
  allowDiagnostics: !forceSpeculative && !canSkipDiagnosticForNode(node) && !inferenceContext?.isTypeIncomplete,
@@ -11449,7 +11735,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
11449
11735
  if (expectedType && !assignType(expectedType, functionType)) {
11450
11736
  typeErrors = true;
11451
11737
  }
11452
- return { type: functionType, isIncomplete, typeErrors };
11738
+ const typeResult = { type: functionType, isIncomplete, typeErrors };
11739
+ if (expectedType && !forceSpeculative && !isIncomplete) {
11740
+ captureContextualLambdaTypes(node, typeResult);
11741
+ }
11742
+ return typeResult;
11453
11743
  });
11454
11744
  }
11455
11745
  function getTypeOfComprehension(node, flags, inferenceContext) {
@@ -13582,6 +13872,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
13582
13872
  }
13583
13873
  }
13584
13874
  }
13875
+ else {
13876
+ // Callable metaclasses can return classes with different equality semantics.
13877
+ classType.shared.flags |= 134217728 /* ClassTypeFlags.HasUnresolvedMetaclass */;
13878
+ }
13585
13879
  }
13586
13880
  const effectiveMetaclass = computeEffectiveMetaclass(classType, node.d.name);
13587
13881
  const enumMemberSetMayBeDynamicallyModified = types_1.ClassType.isEnumClass(classType) &&
@@ -14994,9 +15288,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
14994
15288
  }
14995
15289
  return getExceptionType(subType, node.d.typeExpr);
14996
15290
  });
14997
- // If this is an except group, wrap the exception type in an ExceptionGroup
14998
- // or BaseExceptionGroup depending on whether the target exception is
14999
- // a BaseException.
15291
+ // If this is an except group, use a BaseExceptionGroup when it can contain
15292
+ // an exception outside the Exception hierarchy.
15000
15293
  if (node.d.isExceptGroup) {
15001
15294
  targetType = getBuiltInObject(node, includesBaseException ? 'BaseExceptionGroup' : 'ExceptionGroup', [
15002
15295
  targetType,
@@ -17799,8 +18092,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
17799
18092
  // This will avoid a pathological performance condition for unannotated
17800
18093
  // code that reassigns the same variable hundreds of times. If the symbol
17801
18094
  // effectively has an "Any" annotation, it won't be narrowed.
17802
- if (symbol.getDeclarations().length > maxDeclarationsToUseForInference) {
17803
- return { type: types_1.UnknownType.create() };
18095
+ const declarations = symbol.getDeclarations();
18096
+ if (declarations.length > maxDeclarationsToUseForInference) {
18097
+ let isExceptionVariable = exceptionTargetSymbolCache.get(symbol.id);
18098
+ if (isExceptionVariable === undefined) {
18099
+ isExceptionVariable = declarations.every((decl) => {
18100
+ if (decl.type !== 1 /* DeclarationType.Variable */) {
18101
+ return false;
18102
+ }
18103
+ const parent = decl.node.parent;
18104
+ return parent?.nodeType === 28 /* ParseNodeType.Except */ && parent.d.name === decl.node;
18105
+ });
18106
+ exceptionTargetSymbolCache.set(symbol.id, isExceptionVariable);
18107
+ }
18108
+ // Exception targets get their types from code flow. Don't let the
18109
+ // declaration-count safeguard turn repeated targets into declared Unknown.
18110
+ if (!isExceptionVariable) {
18111
+ return { type: types_1.UnknownType.create() };
18112
+ }
17804
18113
  }
17805
18114
  // There was no declaration with a defined type.
17806
18115
  return { type: undefined };
@@ -18430,7 +18739,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
18430
18739
  if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType,
18431
18740
  /* diag */ undefined,
18432
18741
  /* constraints */ undefined,
18433
- /* selfConstraints */ undefined, recursionCount)) {
18742
+ /* selfConstraints */ undefined, 0 /* AssignTypeFlags.Default */, recursionCount)) {
18434
18743
  isAssignable = false;
18435
18744
  }
18436
18745
  }
@@ -20131,6 +20440,34 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
20131
20440
  return true;
20132
20441
  }
20133
20442
  }
20443
+ // Determines whether the dest accepts every argument list the source
20444
+ // accepts, apart from parameters that overlap only when omitted.
20445
+ function isParamListOverlapOnlyByOmission(destType, srcType, destParamDetails, srcParamDetails, recursionCount) {
20446
+ if (destParamDetails.params.length !== srcParamDetails.params.length) {
20447
+ return false;
20448
+ }
20449
+ const destScopeIds = (0, typeUtils_1.getTypeVarScopeIds)(destType);
20450
+ const srcScopeIds = (0, typeUtils_1.getTypeVarScopeIds)(srcType);
20451
+ const constraints = new constraintTracker_1.ConstraintTracker();
20452
+ return destParamDetails.params.every((destParam, index) => {
20453
+ const srcParam = srcParamDetails.params[index];
20454
+ if (destParam.kind !== srcParam.kind ||
20455
+ destParam.param.category !== srcParam.param.category ||
20456
+ destParam.param.name !== srcParam.param.name) {
20457
+ return false;
20458
+ }
20459
+ if (destParam.defaultType && srcParam.defaultType) {
20460
+ if ((0, typeUtils_1.isOverlapOnlyByOmission)(destParam.type, destParam.defaultType, srcParam.type)) {
20461
+ return true;
20462
+ }
20463
+ }
20464
+ else if (srcParam.defaultType) {
20465
+ return false;
20466
+ }
20467
+ return assignType((0, typeUtils_1.makeTypeVarsFree)(destParam.type, destScopeIds), (0, typeUtils_1.makeTypeVarsBound)(srcParam.type, srcScopeIds),
20468
+ /* diag */ undefined, constraints, 0 /* AssignTypeFlags.Default */, recursionCount);
20469
+ });
20470
+ }
20134
20471
  function assignFunction(destType, srcType, diag, constraints, flags, recursionCount) {
20135
20472
  let canAssign = true;
20136
20473
  const checkReturnType = (flags & 64 /* AssignTypeFlags.SkipReturnTypeCheck */) === 0;
@@ -20151,6 +20488,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
20151
20488
  disallowExtraKwargsForTd: (flags & 131072 /* AssignTypeFlags.DisallowExtraKwargsForTd */) !== 0,
20152
20489
  });
20153
20490
  adjustSourceParamDetailsForDestVariadic(isContra ? destParamDetails : srcParamDetails, isContra ? srcParamDetails : destParamDetails);
20491
+ let paramListOmissionResult;
20492
+ const checkParamListOmission = () => {
20493
+ if (paramListOmissionResult === undefined) {
20494
+ paramListOmissionResult = isParamListOverlapOnlyByOmission(destType, srcType, destParamDetails, srcParamDetails, recursionCount);
20495
+ }
20496
+ return paramListOmissionResult;
20497
+ };
20154
20498
  const targetIncludesParamSpec = isContra ? !!srcParamSpec : !!destParamSpec;
20155
20499
  const destPositionalCount = destParamDetails.firstKeywordOnlyIndex ?? destParamDetails.params.length;
20156
20500
  const srcPositionalCount = srcParamDetails.firstKeywordOnlyIndex ?? srcParamDetails.params.length;
@@ -20212,6 +20556,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
20212
20556
  // be a match.
20213
20557
  if ((flags & 32 /* AssignTypeFlags.PartialOverloadOverlap */) !== 0) {
20214
20558
  if (srcParam.defaultType) {
20559
+ if ((0, typeUtils_1.isOverlapOnlyByOmission)(destParamType, destParam.defaultType, srcParamType) &&
20560
+ checkParamListOmission()) {
20561
+ canAssign = false;
20562
+ }
20215
20563
  continue;
20216
20564
  }
20217
20565
  }
@@ -20483,6 +20831,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions, wrapWithLogger) {
20483
20831
  // be a match.
20484
20832
  if (srcParamInfo.defaultType && destParamInfo.defaultType) {
20485
20833
  if ((flags & 32 /* AssignTypeFlags.PartialOverloadOverlap */) !== 0) {
20834
+ if ((0, typeUtils_1.isOverlapOnlyByOmission)(destParamInfo.type, destParamInfo.defaultType, srcParamType) &&
20835
+ checkParamListOmission()) {
20836
+ canAssign = false;
20837
+ }
20486
20838
  destParamMap.delete(srcParamInfo.param.name);
20487
20839
  return;
20488
20840
  }