@zzzen/pyright-internal 1.2.0-dev.20230716 → 1.2.0-dev.20230723

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 (69) hide show
  1. package/dist/analyzer/checker.d.ts +1 -0
  2. package/dist/analyzer/checker.js +13 -21
  3. package/dist/analyzer/checker.js.map +1 -1
  4. package/dist/analyzer/codeFlowEngine.js +12 -1
  5. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  6. package/dist/analyzer/constraintSolver.js +25 -2
  7. package/dist/analyzer/constraintSolver.js.map +1 -1
  8. package/dist/analyzer/constructorTransform.js +11 -1
  9. package/dist/analyzer/constructorTransform.js.map +1 -1
  10. package/dist/analyzer/constructors.js +11 -9
  11. package/dist/analyzer/constructors.js.map +1 -1
  12. package/dist/analyzer/namedTuples.js +1 -0
  13. package/dist/analyzer/namedTuples.js.map +1 -1
  14. package/dist/analyzer/typeCacheUtils.d.ts +7 -2
  15. package/dist/analyzer/typeCacheUtils.js +11 -7
  16. package/dist/analyzer/typeCacheUtils.js.map +1 -1
  17. package/dist/analyzer/typeEvaluator.js +652 -498
  18. package/dist/analyzer/typeEvaluator.js.map +1 -1
  19. package/dist/analyzer/typeEvaluatorTypes.d.ts +3 -2
  20. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  21. package/dist/analyzer/typeGuards.js +42 -7
  22. package/dist/analyzer/typeGuards.js.map +1 -1
  23. package/dist/analyzer/typeUtils.js +10 -0
  24. package/dist/analyzer/typeUtils.js.map +1 -1
  25. package/dist/analyzer/types.d.ts +2 -2
  26. package/dist/analyzer/types.js +11 -2
  27. package/dist/analyzer/types.js.map +1 -1
  28. package/dist/backgroundThreadBase.js +1 -1
  29. package/dist/backgroundThreadBase.js.map +1 -1
  30. package/dist/languageService/callHierarchyProvider.js +7 -10
  31. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  32. package/dist/languageService/completionProvider.js +7 -1
  33. package/dist/languageService/completionProvider.js.map +1 -1
  34. package/dist/languageService/tooltipUtils.js +5 -2
  35. package/dist/languageService/tooltipUtils.js.map +1 -1
  36. package/dist/localization/localize.d.ts +7 -0
  37. package/dist/localization/localize.js +17 -1
  38. package/dist/localization/localize.js.map +1 -1
  39. package/dist/localization/package.nls.cs.json +1 -0
  40. package/dist/localization/package.nls.de.json +1 -0
  41. package/dist/localization/package.nls.en-us.json +6 -5
  42. package/dist/localization/package.nls.es.json +1 -0
  43. package/dist/localization/package.nls.fr.json +1 -0
  44. package/dist/localization/package.nls.it.json +1 -0
  45. package/dist/localization/package.nls.ja.json +1 -0
  46. package/dist/localization/package.nls.ko.json +1 -0
  47. package/dist/localization/package.nls.pl.json +1 -0
  48. package/dist/localization/package.nls.pt-br.json +1 -0
  49. package/dist/localization/package.nls.qps-ploc.json +1 -0
  50. package/dist/localization/package.nls.ru.json +1 -0
  51. package/dist/localization/package.nls.tr.json +1 -0
  52. package/dist/localization/package.nls.zh-cn.json +1 -0
  53. package/dist/localization/package.nls.zh-tw.json +1 -0
  54. package/dist/tests/checker.test.js +2 -2
  55. package/dist/tests/completions.test.js +40 -0
  56. package/dist/tests/completions.test.js.map +1 -1
  57. package/dist/tests/config.test.js +12 -0
  58. package/dist/tests/config.test.js.map +1 -1
  59. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.d.ts +1 -0
  60. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js +40 -0
  61. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js.map +1 -0
  62. package/dist/tests/typeEvaluator1.test.js +17 -1
  63. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  64. package/dist/tests/typeEvaluator2.test.js +13 -1
  65. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  66. package/dist/tests/typeEvaluator3.test.js +1 -1
  67. package/dist/tests/typeEvaluator4.test.js +5 -1
  68. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  69. package/package.json +8 -7
@@ -175,7 +175,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
175
175
  let typeCache = new Map();
176
176
  let effectiveTypeCache = new Map();
177
177
  let expectedTypeCache = new Map();
178
- let classTypeHooks = [];
178
+ let deferredClassCompletions = [];
179
179
  let cancellationToken;
180
180
  let isBasicTypesInitialized = false;
181
181
  let noneType;
@@ -1420,6 +1420,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1420
1420
  let classOrObjectBase;
1421
1421
  let memberAccessClass;
1422
1422
  let bindFunction = true;
1423
+ let useDescriptorSetterType = false;
1423
1424
  switch (expression.nodeType) {
1424
1425
  case 38 /* Name */: {
1425
1426
  const symbolWithScope = lookUpSymbolRecursive(expression, expression.value, /* honorCodeFlow */ true);
@@ -1460,6 +1461,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1460
1461
  if (classMemberInfo === null || classMemberInfo === void 0 ? void 0 : classMemberInfo.isInstanceMember) {
1461
1462
  bindFunction = false;
1462
1463
  }
1464
+ useDescriptorSetterType = true;
1463
1465
  }
1464
1466
  else if ((0, types_1.isInstantiableClass)(baseType)) {
1465
1467
  classMemberInfo = (0, typeUtils_1.lookUpClassMember)(baseType, expression.memberName.value, 8 /* SkipInstanceVariables */ | 16 /* DeclaredTypesOnly */);
@@ -1505,7 +1507,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1505
1507
  let declaredType = (_b = getDeclaredTypeOfSymbol(symbol)) === null || _b === void 0 ? void 0 : _b.type;
1506
1508
  if (declaredType) {
1507
1509
  // If it's a descriptor, we need to get the setter type.
1508
- if ((0, types_1.isClassInstance)(declaredType)) {
1510
+ if (useDescriptorSetterType && (0, types_1.isClassInstance)(declaredType)) {
1509
1511
  const setterInfo = (0, typeUtils_1.lookUpClassMember)(declaredType, '__set__');
1510
1512
  const setter = setterInfo ? getTypeOfMember(setterInfo) : undefined;
1511
1513
  if (setterInfo && setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 3) {
@@ -1908,7 +1910,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1908
1910
  }
1909
1911
  function isDiagnosticSuppressedForNode(node) {
1910
1912
  return (suppressedNodeStack.some((suppressedNode) => ParseTreeUtils.isNodeContainedWithin(node, suppressedNode)) ||
1911
- isSpeculativeModeInUse(node));
1913
+ speculativeTypeTracker.isSpeculative(node, /* ignoreIfDiagnosticsAllowed */ true));
1912
1914
  }
1913
1915
  function addDiagnostic(diagLevel, rule, message, node, range) {
1914
1916
  if (diagLevel === 'none') {
@@ -2392,20 +2394,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2392
2394
  // its bound type and a constrained TypeVar is expanded to its individual
2393
2395
  // constrained types). If conditionFilter is specified, conditions that
2394
2396
  // do not match will be ignored.
2395
- function mapSubtypesExpandTypeVars(type, conditionFilter, callback) {
2397
+ function mapSubtypesExpandTypeVars(type, conditionFilter, callback, recursionCount = 0) {
2396
2398
  const newSubtypes = [];
2397
2399
  let typeChanged = false;
2398
- const expandSubtype = (unexpandedType) => {
2400
+ function expandSubtype(unexpandedType, isLastSubtype) {
2399
2401
  let expandedType = (0, types_1.isUnion)(unexpandedType) ? unexpandedType : makeTopLevelTypeVarsConcrete(unexpandedType);
2400
2402
  expandedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedType);
2401
- (0, typeUtils_1.doForEachSubtype)(expandedType, (subtype) => {
2403
+ (0, typeUtils_1.doForEachSubtype)(expandedType, (subtype, index, allSubtypes) => {
2402
2404
  var _a;
2403
2405
  if (conditionFilter) {
2404
- if (!types_1.TypeCondition.isCompatible((0, typeUtils_1.getTypeCondition)(subtype), conditionFilter)) {
2406
+ const filteredType = applyConditionFilterToType(subtype, conditionFilter, recursionCount);
2407
+ if (!filteredType) {
2405
2408
  return undefined;
2406
2409
  }
2410
+ subtype = filteredType;
2407
2411
  }
2408
- let transformedType = callback(subtype, unexpandedType);
2412
+ let transformedType = callback(subtype, unexpandedType, isLastSubtype && index === allSubtypes.length - 1);
2409
2413
  if (transformedType !== unexpandedType) {
2410
2414
  typeChanged = true;
2411
2415
  }
@@ -2419,14 +2423,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2419
2423
  }
2420
2424
  return undefined;
2421
2425
  });
2422
- };
2426
+ }
2423
2427
  if ((0, types_1.isUnion)(type)) {
2424
- type.subtypes.forEach((subtype) => {
2425
- expandSubtype(subtype);
2428
+ type.subtypes.forEach((subtype, index) => {
2429
+ expandSubtype(subtype, index === type.subtypes.length - 1);
2426
2430
  });
2427
2431
  }
2428
2432
  else {
2429
- expandSubtype(type);
2433
+ expandSubtype(type, /* isLastSubtype */ true);
2430
2434
  }
2431
2435
  if (!typeChanged) {
2432
2436
  return type;
@@ -2438,6 +2442,40 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2438
2442
  }
2439
2443
  return newType;
2440
2444
  }
2445
+ function applyConditionFilterToType(type, conditionFilter, recursionCount) {
2446
+ if (recursionCount > types_1.maxTypeRecursionCount) {
2447
+ return type;
2448
+ }
2449
+ recursionCount++;
2450
+ // If the type has a condition associated with it, make sure it's compatible.
2451
+ if (!types_1.TypeCondition.isCompatible((0, typeUtils_1.getTypeCondition)(type), conditionFilter)) {
2452
+ return undefined;
2453
+ }
2454
+ // If the type is generic, see if any of its type arguments should be filtered.
2455
+ // This is possible only in cases where the type parameter is covariant.
2456
+ // TODO - handle functions and tuples
2457
+ if ((0, types_1.isClass)(type) && type.typeArguments && !type.tupleTypeArguments) {
2458
+ inferTypeParameterVarianceForClass(type);
2459
+ let typeWasTransformed = false;
2460
+ const filteredTypeArgs = type.typeArguments.map((typeArg, index) => {
2461
+ const variance = types_1.TypeVarType.getVariance(type.details.typeParameters[index]);
2462
+ if (variance !== 3 /* Covariant */) {
2463
+ return typeArg;
2464
+ }
2465
+ const filteredTypeArg = mapSubtypesExpandTypeVars(typeArg, conditionFilter, (expandedSubtype) => {
2466
+ return expandedSubtype;
2467
+ }, recursionCount);
2468
+ if (filteredTypeArg !== typeArg) {
2469
+ typeWasTransformed = true;
2470
+ }
2471
+ return filteredTypeArg;
2472
+ });
2473
+ if (typeWasTransformed) {
2474
+ return types_1.ClassType.cloneForSpecialization(type, filteredTypeArgs, /* isTypeArgumentExplicit */ true);
2475
+ }
2476
+ }
2477
+ return type;
2478
+ }
2441
2479
  function markNamesAccessed(node, names) {
2442
2480
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2443
2481
  const scope = ScopeUtils.getScopeForNode(node);
@@ -2814,7 +2852,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2814
2852
  // Verify that the name does not refer to a (non type alias) variable.
2815
2853
  if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
2816
2854
  let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
2817
- if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
2855
+ if ((0, types_1.isClass)(type) && !type.includeSubclasses && !symbol.hasTypedDeclarations()) {
2818
2856
  // This check exempts class types that are created by calling
2819
2857
  // NewType, NamedTuple, and by invoking a metaclass directly.
2820
2858
  isAllowedTypeForVariable = true;
@@ -2892,13 +2930,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2892
2930
  function getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType) {
2893
2931
  // This function applies only to variables, parameters, and imports, not to other
2894
2932
  // types of symbols.
2895
- if (!symbolWithScope.symbol
2896
- .getDeclarations()
2897
- .every((decl) => decl.type === 1 /* Variable */ ||
2933
+ const decls = symbolWithScope.symbol.getDeclarations();
2934
+ if (!decls.every((decl) => decl.type === 1 /* Variable */ ||
2898
2935
  decl.type === 2 /* Parameter */ ||
2899
2936
  decl.type === 8 /* Alias */)) {
2900
2937
  return undefined;
2901
2938
  }
2939
+ // If the symbol is modified in scopes other than the one in which it is
2940
+ // declared (e.g. through a nonlocal or global binding), it is not eligible
2941
+ // for code flow analysis.
2942
+ if (!decls.every((decl) => decl.type === 2 /* Parameter */ ||
2943
+ ScopeUtils.getScopeForNode(decl.node) === symbolWithScope.scope)) {
2944
+ return undefined;
2945
+ }
2902
2946
  // If the symbol is a variable captured by an inner function
2903
2947
  // or lambda, see if we can infer the type from the outer scope.
2904
2948
  const scopeHierarchy = ScopeUtils.getScopeHierarchy(node, symbolWithScope.scope);
@@ -2934,7 +2978,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2934
2978
  return !codeFlowEngine.isFlowNodeReachable(declCodeFlowNode, innerScopeCodeFlowNode,
2935
2979
  /* ignoreNoReturn */ true);
2936
2980
  })) {
2937
- return getFlowTypeOfReference(node, symbolWithScope.symbol.id, effectiveType, innerScopeNode);
2981
+ let typeAtStart = effectiveType;
2982
+ if (symbolWithScope.symbol.isInitiallyUnbound()) {
2983
+ typeAtStart = types_1.UnboundType.create();
2984
+ }
2985
+ return getFlowTypeOfReference(node, symbolWithScope.symbol.id, typeAtStart, innerScopeNode);
2938
2986
  }
2939
2987
  }
2940
2988
  }
@@ -3290,7 +3338,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3290
3338
  baseType = objectType;
3291
3339
  }
3292
3340
  }
3293
- const getTypeOfNoneBase = (subtype) => {
3341
+ function getTypeOfNoneBase(subtype) {
3294
3342
  if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
3295
3343
  if (types_1.TypeBase.isInstance(subtype)) {
3296
3344
  return getTypeOfObjectMember(node.memberName, types_1.ClassType.cloneAsInstance(noneType), memberName, usage, diag);
@@ -3300,7 +3348,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3300
3348
  }
3301
3349
  }
3302
3350
  return undefined;
3303
- };
3351
+ }
3304
3352
  if ((0, types_1.isParamSpec)(baseType) && baseType.paramSpecAccess) {
3305
3353
  baseType = makeTopLevelTypeVarsConcrete(baseType);
3306
3354
  }
@@ -3346,11 +3394,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3346
3394
  if (baseType.details.recursiveTypeAliasName) {
3347
3395
  return { type: types_1.UnknownType.create(/* isIncomplete */ true), isIncomplete: true };
3348
3396
  }
3349
- return getTypeOfMemberAccessWithBaseType(node, {
3350
- type: makeTopLevelTypeVarsConcrete(baseType),
3351
- bindToType: baseType,
3352
- isIncomplete,
3353
- }, usage, 0 /* None */);
3397
+ if (!baseType.details.isVariadic) {
3398
+ return getTypeOfMemberAccessWithBaseType(node, {
3399
+ type: makeTopLevelTypeVarsConcrete(baseType),
3400
+ bindToType: baseType,
3401
+ isIncomplete,
3402
+ }, usage, 0 /* None */);
3403
+ }
3404
+ break;
3354
3405
  }
3355
3406
  case 7 /* Class */: {
3356
3407
  if (types_1.TypeBase.isInstantiable(baseType)) {
@@ -3821,7 +3872,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3821
3872
  type: types_1.ClassType.isClassProperty(lookupClass)
3822
3873
  ? baseTypeClass
3823
3874
  : isAccessedThroughObject
3824
- ? bindToType || types_1.ClassType.cloneAsInstance(baseTypeClass)
3875
+ ? bindToType !== null && bindToType !== void 0 ? bindToType : types_1.ClassType.cloneAsInstance(baseTypeClass)
3825
3876
  : types_1.NoneType.createInstance(),
3826
3877
  },
3827
3878
  },
@@ -3970,8 +4021,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3970
4021
  // If this function is an instance member (e.g. a lambda that was
3971
4022
  // assigned to an instance variable), don't perform any binding.
3972
4023
  if (!isAccessedThroughObject || (memberInfo && !memberInfo.isInstanceMember)) {
4024
+ let effectiveBindToType = bindToType;
4025
+ if (bindToType && !(0, typeUtils_1.isInstantiableMetaclass)(baseTypeClass)) {
4026
+ // If bindToType is an instantiable class or TypeVar but we're targeting
4027
+ // an instance method (in a non-metaclass), we need to convert
4028
+ // the bindToType to an instance.
4029
+ const targetMethod = (0, types_1.isFunction)(concreteSubtype)
4030
+ ? concreteSubtype
4031
+ : concreteSubtype.overloads[0];
4032
+ if (types_1.FunctionType.isInstanceMethod(targetMethod) && !types_1.TypeBase.isInstance(bindToType)) {
4033
+ effectiveBindToType = (0, typeUtils_1.convertToInstance)(bindToType);
4034
+ }
4035
+ }
3973
4036
  return bindFunctionToClassOrObject(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode,
3974
- /* recursionCount */ undefined, treatConstructorAsClassMember, bindToType);
4037
+ /* recursionCount */ undefined, treatConstructorAsClassMember, effectiveBindToType);
3975
4038
  }
3976
4039
  }
3977
4040
  if (usage.method === 'set') {
@@ -5263,6 +5326,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5263
5326
  function getTypeOfCall(node, flags, inferenceContext) {
5264
5327
  var _a;
5265
5328
  let baseTypeResult;
5329
+ // Check for the use of `type(x)` within a type annotation. This isn't
5330
+ // allowed, and it's a common mistake, so we want to emit a diagnostic
5331
+ // that guides the user to the right solution.
5266
5332
  if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
5267
5333
  node.leftExpression.nodeType === 38 /* Name */ &&
5268
5334
  node.leftExpression.value === 'type') {
@@ -5324,20 +5390,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5324
5390
  }
5325
5391
  }
5326
5392
  else {
5327
- // Check for an attempt to invoke an abstract static or class method.
5328
- if ((0, types_1.isFunction)(baseTypeResult.type) &&
5329
- baseTypeResult.type.boundToType &&
5330
- (0, types_1.isInstantiableClass)(baseTypeResult.type.boundToType) &&
5331
- !baseTypeResult.type.boundToType.includeSubclasses) {
5332
- if (types_1.FunctionType.isAbstractMethod(baseTypeResult.type)) {
5333
- if (types_1.FunctionType.isStaticMethod(baseTypeResult.type) ||
5334
- types_1.FunctionType.isClassMethod(baseTypeResult.type)) {
5335
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
5336
- method: baseTypeResult.type.details.name,
5337
- }), node.leftExpression);
5338
- }
5339
- }
5340
- }
5341
5393
  const callResult = validateCallArguments(node, argList, baseTypeResult,
5342
5394
  /* typeVarContext */ undefined,
5343
5395
  /* skipUnknownArgCheck */ false, inferenceContext);
@@ -5776,7 +5828,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5776
5828
  // If there were multiple possible matches, evaluate the type as
5777
5829
  // Unknown, but include the "possible types" to allow for completion
5778
5830
  // suggestions.
5779
- if (!isDefinitiveMatchFound) {
5831
+ if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
5780
5832
  possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
5781
5833
  // Did the filtering produce a single result? If so, we're done.
5782
5834
  if (possibleMatchResults.length === 1) {
@@ -5984,24 +6036,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5984
6036
  }
5985
6037
  return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
5986
6038
  }
5987
- // Create a helper function that evaluates the overload that matches
5988
- // the arg/param lists.
5989
- function evaluateUsingLastMatchingOverload(skipUnknownArgCheck) {
5990
- // Find the match with the largest overload index (i.e. the last overload
5991
- // that was in the overload list).
5992
- const lastMatch = filteredMatchResults.reduce((previous, current) => {
5993
- return current.overloadIndex > previous.overloadIndex ? current : previous;
6039
+ // Create a helper function that evaluates the overload that best
6040
+ // matches the arg/param lists.
6041
+ function evaluateUsingBestMatchingOverload(skipUnknownArgCheck) {
6042
+ // Find the match with the smallest argument match score. If there
6043
+ // are more than one with the same score, use the one with the
6044
+ // largest index. Later overloads tend to be more general.
6045
+ const bestMatch = filteredMatchResults.reduce((previous, current) => {
6046
+ if (current.argumentMatchScore === previous.argumentMatchScore) {
6047
+ return current.overloadIndex > previous.overloadIndex ? current : previous;
6048
+ }
6049
+ return current.argumentMatchScore < previous.argumentMatchScore ? current : previous;
5994
6050
  });
5995
6051
  const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
5996
- effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(lastMatch.overload));
6052
+ effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(bestMatch.overload));
5997
6053
  effectiveTypeVarContext.unlock();
5998
- return validateFunctionArgumentTypesWithContext(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
6054
+ return validateFunctionArgumentTypesWithContext(errorNode, bestMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
5999
6055
  }
6000
6056
  // If there is only one possible arg/param match among the overloads,
6001
6057
  // use the normal type matching mechanism because it is faster and
6002
6058
  // will provide a clearer error message.
6003
6059
  if (filteredMatchResults.length === 1) {
6004
- return evaluateUsingLastMatchingOverload(/* skipUnknownArgCheck */ false);
6060
+ return evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ false);
6005
6061
  }
6006
6062
  let expandedArgTypes = [argList.map((arg) => undefined)];
6007
6063
  let isTypeIncomplete = !!typeResult.isIncomplete;
@@ -6044,7 +6100,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6044
6100
  // in speculative mode because it's very expensive, and we're going to
6045
6101
  // suppress the diagnostic anyway.
6046
6102
  if (!isDiagnosticSuppressedForNode(errorNode) && !isTypeIncomplete) {
6047
- const result = evaluateUsingLastMatchingOverload(/* skipUnknownArgCheck */ true);
6103
+ const result = evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ true);
6048
6104
  // Replace the result with an unknown type since we don't know
6049
6105
  // what overload should have been used.
6050
6106
  result.returnType = types_1.UnknownType.create();
@@ -6120,334 +6176,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6120
6176
  return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
6121
6177
  }
6122
6178
  let returnType = mapSubtypesExpandTypeVars(callTypeResult.type,
6123
- /* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype) => {
6124
- var _a, _b, _c, _d, _e, _f, _g;
6125
- switch (expandedSubtype.category) {
6126
- case 1 /* Unknown */:
6127
- case 2 /* Any */: {
6128
- // Touch all of the args so they're marked accessed. Don't bother
6129
- // doing this if the call type is incomplete because this will need
6130
- // to be done again once it is complete.
6131
- if (!callTypeResult.isIncomplete) {
6132
- argList.forEach((arg) => {
6133
- if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
6134
- getTypeOfArgument(arg);
6135
- }
6136
- });
6137
- }
6138
- return expandedSubtype;
6139
- }
6140
- case 5 /* Function */: {
6141
- if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
6142
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
6143
- type: printType(expandedSubtype),
6144
- }), errorNode);
6145
- argumentErrors = true;
6146
- return undefined;
6147
- }
6148
- // The stdlib collections/__init__.pyi stub file defines namedtuple
6149
- // as a function rather than a class, so we need to check for it here.
6150
- if (expandedSubtype.details.builtInName === 'namedtuple') {
6151
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
6152
- return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
6153
- /* includesTypes */ false);
6154
- }
6155
- // Handle the NewType specially, replacing the normal return type.
6156
- if (expandedSubtype.details.builtInName === 'NewType') {
6157
- return createNewType(errorNode, argList);
6158
- }
6159
- let effectiveTypeVarContext = typeVarContext;
6160
- if (!effectiveTypeVarContext) {
6161
- // If a typeVarContext wasn't provided by the caller, allocate one here.
6162
- effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
6163
- // There are certain cases, such as with super().__new__(cls) calls where
6164
- // the call is a constructor but the proper TypeVar scope has been lost.
6165
- // We'll add a wildcard TypeVar scope here. This is a bit of a hack and
6166
- // we may need to revisit this in the future.
6167
- if (types_1.FunctionType.isConstructorMethod(expandedSubtype)) {
6168
- effectiveTypeVarContext.addSolveForScope(types_1.WildcardTypeVarScopeId);
6169
- }
6170
- }
6171
- const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
6172
- if (functionResult.isTypeIncomplete) {
6173
- isTypeIncomplete = true;
6174
- }
6175
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
6176
- if (functionResult.argumentErrors) {
6177
- argumentErrors = true;
6178
- }
6179
- else {
6180
- specializedInitSelfType = functionResult.specializedInitSelfType;
6181
- // Call the function transform logic to handle special-cased functions.
6182
- const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
6183
- argumentErrors: functionResult.argumentErrors,
6184
- returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
6185
- isTypeIncomplete,
6186
- });
6187
- functionResult.returnType = transformed.returnType;
6188
- if (transformed.isTypeIncomplete) {
6189
- isTypeIncomplete = true;
6190
- }
6191
- if (transformed.argumentErrors) {
6192
- argumentErrors = true;
6193
- }
6194
- }
6195
- if (expandedSubtype.details.builtInName === '__import__') {
6196
- // For the special __import__ type, we'll override the return type to be "Any".
6197
- // This is required because we don't know what module was imported, and we don't
6198
- // want to fail type checks when accessing members of the resulting module type.
6199
- return types_1.AnyType.create();
6200
- }
6201
- return functionResult.returnType;
6202
- }
6203
- case 6 /* OverloadedFunction */: {
6204
- // Handle the 'cast' call as a special case.
6205
- if (expandedSubtype.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
6206
- return evaluateCastCall(argList, errorNode);
6207
- }
6208
- const functionResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
6209
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
6210
- if (functionResult.isTypeIncomplete) {
6211
- isTypeIncomplete = true;
6212
- }
6213
- if (functionResult.argumentErrors) {
6214
- argumentErrors = true;
6215
- }
6216
- else {
6217
- specializedInitSelfType = functionResult.specializedInitSelfType;
6218
- // Call the function transform logic to handle special-cased functions.
6219
- const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
6220
- argumentErrors: functionResult.argumentErrors,
6221
- returnType: (_b = functionResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
6222
- isTypeIncomplete,
6223
- });
6224
- functionResult.returnType = transformed.returnType;
6225
- if (transformed.isTypeIncomplete) {
6226
- isTypeIncomplete = true;
6227
- }
6228
- if (transformed.argumentErrors) {
6229
- argumentErrors = true;
6230
- }
6231
- }
6232
- return (_c = functionResult.returnType) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
6233
- }
6234
- case 7 /* Class */: {
6235
- if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
6236
- if (expandedSubtype.literalValue !== undefined) {
6237
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
6238
- argumentErrors = true;
6239
- return types_1.UnknownType.create();
6240
- }
6241
- if (types_1.ClassType.isBuiltIn(expandedSubtype)) {
6242
- const className = expandedSubtype.aliasName || expandedSubtype.details.name;
6243
- if (className === 'type') {
6244
- // Validate the constructor arguments.
6245
- (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6246
- // Handle the 'type' call specially.
6247
- if (argList.length === 1) {
6248
- // The one-parameter form of "type" returns the class
6249
- // for the specified object.
6250
- const argType = getTypeOfArgument(argList[0]).type;
6251
- return (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
6252
- if ((0, types_1.isClassInstance)(subtype) ||
6253
- ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
6254
- (0, types_1.isNoneInstance)(subtype)) {
6255
- return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
6256
- }
6257
- else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
6258
- return types_1.FunctionType.cloneAsInstantiable(subtype);
6259
- }
6260
- return types_1.AnyType.create();
6261
- });
6262
- }
6263
- else if (argList.length >= 2) {
6264
- // The two-parameter form of "type" returns a new class type
6265
- // built from the specified base types.
6266
- return createType(errorNode, argList) || types_1.AnyType.create();
6267
- }
6268
- // If the parameter to type() is not statically known,
6269
- // fall back to Any.
6270
- return types_1.AnyType.create();
6271
- }
6272
- if (className === 'TypeVar') {
6273
- return createTypeVarType(errorNode, expandedSubtype, argList);
6274
- }
6275
- if (className === 'TypeVarTuple') {
6276
- return createTypeVarTupleType(errorNode, expandedSubtype, argList);
6277
- }
6278
- if (className === 'ParamSpec') {
6279
- return createParamSpecType(errorNode, expandedSubtype, argList);
6280
- }
6281
- if (className === 'TypeAliasType') {
6282
- const newTypeAlias = createTypeAliasType(errorNode, argList);
6283
- if (newTypeAlias) {
6284
- return newTypeAlias;
6285
- }
6286
- }
6287
- if (className === 'NamedTuple') {
6288
- return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
6289
- /* includesTypes */ true);
6290
- }
6291
- if (className === 'NewType') {
6292
- return createNewType(errorNode, argList);
6293
- }
6294
- if (className === 'Protocol' ||
6295
- className === 'Generic' ||
6296
- className === 'Callable' ||
6297
- className === 'Concatenate' ||
6298
- className === 'Type') {
6299
- const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
6300
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
6301
- return types_1.AnyType.create();
6302
- }
6303
- if ((0, types_1.isClass)(unexpandedSubtype) && (0, enums_1.isKnownEnumType)(className)) {
6304
- return ((_d = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedSubtype, argList)) !== null && _d !== void 0 ? _d : types_1.UnknownType.create());
6305
- }
6306
- if (className === 'TypedDict') {
6307
- return (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedSubtype, argList);
6308
- }
6309
- if (className === 'auto' && argList.length === 0) {
6310
- return (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode);
6311
- }
6312
- }
6313
- if (types_1.ClassType.supportsAbstractMethods(expandedSubtype)) {
6314
- const abstractMethods = getAbstractMethods(expandedSubtype);
6315
- if (abstractMethods.length > 0 &&
6316
- !expandedSubtype.includeSubclasses &&
6317
- !(0, types_1.isTypeVar)(unexpandedSubtype)) {
6318
- // If the class is abstract, it can't be instantiated.
6319
- const diagAddendum = new diagnostic_1.DiagnosticAddendum();
6320
- const errorsToDisplay = 2;
6321
- abstractMethods.forEach((abstractMethod, index) => {
6322
- if (index === errorsToDisplay) {
6323
- diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
6324
- count: abstractMethods.length - errorsToDisplay,
6325
- }));
6326
- }
6327
- else if (index < errorsToDisplay) {
6328
- if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
6329
- const className = abstractMethod.classType.details.name;
6330
- diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
6331
- type: className,
6332
- name: abstractMethod.symbolName,
6333
- }));
6334
- }
6335
- }
6336
- });
6337
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
6338
- .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
6339
- type: expandedSubtype.details.name,
6340
- }) + diagAddendum.getString(), errorNode);
6341
- }
6342
- }
6343
- if (types_1.ClassType.isProtocolClass(expandedSubtype) && !expandedSubtype.includeSubclasses) {
6344
- // If the class is a protocol, it can't be instantiated.
6345
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
6346
- type: expandedSubtype.details.name,
6347
- }), errorNode);
6348
- }
6349
- // Assume this is a call to the constructor.
6350
- const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6351
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, constructorResult.overloadsUsedForCall);
6352
- if (constructorResult.argumentErrors) {
6353
- argumentErrors = true;
6354
- }
6355
- if (constructorResult.isTypeIncomplete) {
6356
- isTypeIncomplete = true;
6357
- }
6358
- let returnType = constructorResult.returnType;
6359
- // If the expandedSubtype originated from a TypeVar, convert
6360
- // the constructed type back to the TypeVar. For example, if
6361
- // we have `cls: Type[_T]` followed by `_T()`.
6362
- if ((0, types_1.isTypeVar)(unexpandedSubtype)) {
6363
- returnType = (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
6364
- }
6365
- // If we instantiated a type, transform it into a class.
6366
- // This can happen if someone directly instantiates a metaclass
6367
- // deriving from type.
6368
- if (returnType &&
6369
- (0, types_1.isClassInstance)(returnType) &&
6370
- returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
6371
- let newClassName = '__class_' + returnType.details.name;
6372
- if (argList.length === 3) {
6373
- const firstArgType = getTypeOfArgument(argList[0]).type;
6374
- if ((0, types_1.isClassInstance)(firstArgType) &&
6375
- types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
6376
- typeof firstArgType.literalValue === 'string') {
6377
- newClassName = firstArgType.literalValue;
6378
- }
6379
- }
6380
- const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '', AnalyzerNodeInfo.getFileInfo(errorNode).filePath, 0 /* None */, ParseTreeUtils.getTypeSourceId(errorNode), types_1.ClassType.cloneAsInstantiable(returnType), types_1.ClassType.cloneAsInstantiable(returnType));
6381
- newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
6382
- newClassType.details.effectiveMetaclass = expandedSubtype;
6383
- (0, typeUtils_1.computeMroLinearization)(newClassType);
6384
- return newClassType;
6385
- }
6386
- return returnType;
6387
- }
6388
- else {
6389
- const memberType = (_e = getTypeOfObjectMember(errorNode, expandedSubtype, '__call__',
6390
- /* usage */ undefined,
6391
- /* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _e === void 0 ? void 0 : _e.type;
6392
- if (memberType) {
6393
- const functionResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6394
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
6395
- if (functionResult.argumentErrors) {
6396
- argumentErrors = true;
6397
- }
6398
- if ((0, types_1.isTypeVar)(unexpandedSubtype) &&
6399
- types_1.TypeBase.isInstantiable(unexpandedSubtype) &&
6400
- (0, types_1.isClass)(expandedSubtype) &&
6401
- types_1.ClassType.isBuiltIn(expandedSubtype, 'type')) {
6402
- // Handle the case where a Type[T] is being called. We presume this
6403
- // will instantiate an object of type T.
6404
- return (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
6405
- }
6406
- return (_f = functionResult.returnType) !== null && _f !== void 0 ? _f : types_1.UnknownType.create();
6407
- }
6408
- if (!memberType || !(0, types_1.isAnyOrUnknown)(memberType)) {
6409
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6410
- type: printType(expandedSubtype),
6411
- }), errorNode);
6412
- }
6413
- return types_1.UnknownType.create();
6414
- }
6179
+ /* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype, isLastIteration) => {
6180
+ return useSpeculativeMode(isLastIteration ? undefined : errorNode, () => {
6181
+ const callResult = validateCallArgumentsForSubtype(errorNode, argList, expandedSubtype, unexpandedSubtype, !!callTypeResult.isIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6182
+ if (callResult.argumentErrors) {
6183
+ argumentErrors = true;
6415
6184
  }
6416
- case 3 /* None */: {
6417
- if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
6418
- if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
6419
- const functionResult = validateCallArguments(errorNode, argList, { type: noneType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6420
- if (functionResult.isTypeIncomplete) {
6421
- isTypeIncomplete = true;
6422
- }
6423
- if (functionResult.argumentErrors) {
6424
- argumentErrors = true;
6425
- }
6426
- }
6427
- return types_1.NoneType.createInstance();
6428
- }
6429
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
6430
- return undefined;
6185
+ if (callResult.isTypeIncomplete) {
6186
+ isTypeIncomplete = true;
6431
6187
  }
6432
- // TypeVars should have been expanded in most cases,
6433
- // but we still need to handle the case of Type[T] where
6434
- // T is a constrained type that contains a union. We also
6435
- // need to handle recursive type aliases.
6436
- case 10 /* TypeVar */: {
6437
- expandedSubtype = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedSubtype);
6438
- const callResult = validateCallArguments(errorNode, argList, { type: expandedSubtype }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6188
+ if (callResult.overloadsUsedForCall) {
6439
6189
  (0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
6440
- if (callResult.argumentErrors) {
6441
- argumentErrors = true;
6442
- }
6443
- return (_g = callResult.returnType) !== null && _g !== void 0 ? _g : types_1.UnknownType.create();
6444
- }
6445
- case 8 /* Module */: {
6446
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
6447
- return undefined;
6448
6190
  }
6449
- }
6450
- return undefined;
6191
+ specializedInitSelfType = callResult.specializedInitSelfType;
6192
+ return callResult.returnType;
6193
+ }, {
6194
+ allowDiagnostics: true,
6195
+ });
6451
6196
  });
6452
6197
  // If we ended up with a "Never" type because all code paths returned
6453
6198
  // undefined due to argument errors, transform the result into an Unknown
@@ -6463,10 +6208,350 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6463
6208
  overloadsUsedForCall,
6464
6209
  };
6465
6210
  }
6211
+ function validateCallArgumentsForSubtype(errorNode, argList, expandedCallType, unexpandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
6212
+ switch (expandedCallType.category) {
6213
+ case 4 /* Never */:
6214
+ case 1 /* Unknown */:
6215
+ case 2 /* Any */: {
6216
+ // Touch all of the args so they're marked accessed. Don't bother
6217
+ // doing this if the call type is incomplete because this will need
6218
+ // to be done again once it is complete.
6219
+ if (!isCallTypeIncomplete) {
6220
+ argList.forEach((arg) => {
6221
+ if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
6222
+ getTypeOfArgument(arg);
6223
+ }
6224
+ });
6225
+ }
6226
+ return { returnType: expandedCallType };
6227
+ }
6228
+ case 5 /* Function */: {
6229
+ return validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
6230
+ }
6231
+ case 6 /* OverloadedFunction */: {
6232
+ return validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext);
6233
+ }
6234
+ case 7 /* Class */: {
6235
+ if (types_1.TypeBase.isInstantiable(expandedCallType)) {
6236
+ return validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext);
6237
+ }
6238
+ return validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6239
+ }
6240
+ case 3 /* None */: {
6241
+ if (types_1.TypeBase.isInstantiable(expandedCallType)) {
6242
+ if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
6243
+ const callResult = validateCallForInstantiableClass(errorNode, argList, noneType, noneType, skipUnknownArgCheck, inferenceContext);
6244
+ return { ...callResult, returnType: types_1.NoneType.createInstance() };
6245
+ }
6246
+ return { returnType: types_1.NoneType.createInstance() };
6247
+ }
6248
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
6249
+ return { argumentErrors: true };
6250
+ }
6251
+ // TypeVars should have been expanded in most cases,
6252
+ // but we still need to handle the case of Type[T] where
6253
+ // T is a constrained type that contains a union. We also
6254
+ // need to handle recursive type aliases.
6255
+ case 10 /* TypeVar */: {
6256
+ return validateCallArguments(errorNode, argList, { type: (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedCallType), isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6257
+ }
6258
+ case 8 /* Module */: {
6259
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
6260
+ return { argumentErrors: true };
6261
+ }
6262
+ }
6263
+ return { argumentErrors: true };
6264
+ }
6265
+ function validateCallForFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
6266
+ var _a;
6267
+ if (types_1.TypeBase.isInstantiable(expandedCallType)) {
6268
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
6269
+ type: printType(expandedCallType),
6270
+ }), errorNode);
6271
+ return { returnType: undefined, argumentErrors: true };
6272
+ }
6273
+ // Check for an attempt to invoke an abstract static or class method.
6274
+ if (expandedCallType.boundToType &&
6275
+ (0, types_1.isInstantiableClass)(expandedCallType.boundToType) &&
6276
+ !expandedCallType.boundToType.includeSubclasses) {
6277
+ if (types_1.FunctionType.isAbstractMethod(expandedCallType)) {
6278
+ if (types_1.FunctionType.isStaticMethod(expandedCallType) || types_1.FunctionType.isClassMethod(expandedCallType)) {
6279
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
6280
+ method: expandedCallType.details.name,
6281
+ }), errorNode.nodeType === 9 /* Call */ ? errorNode.leftExpression : errorNode);
6282
+ }
6283
+ }
6284
+ }
6285
+ // The stdlib collections/__init__.pyi stub file defines namedtuple
6286
+ // as a function rather than a class, so we need to check for it here.
6287
+ if (expandedCallType.details.builtInName === 'namedtuple') {
6288
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
6289
+ return {
6290
+ returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ false),
6291
+ };
6292
+ }
6293
+ // Handle the NewType specially, replacing the normal return type.
6294
+ if (expandedCallType.details.builtInName === 'NewType') {
6295
+ return { returnType: createNewType(errorNode, argList) };
6296
+ }
6297
+ let effectiveTypeVarContext = typeVarContext;
6298
+ if (!effectiveTypeVarContext) {
6299
+ // If a typeVarContext wasn't provided by the caller, allocate one here.
6300
+ effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
6301
+ }
6302
+ const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
6303
+ let isTypeIncomplete = !!functionResult.isTypeIncomplete;
6304
+ let returnType = functionResult.returnType;
6305
+ let argumentErrors = !!functionResult.argumentErrors;
6306
+ if (!argumentErrors) {
6307
+ // Call the function transform logic to handle special-cased functions.
6308
+ const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
6309
+ argumentErrors: !!functionResult.argumentErrors,
6310
+ returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
6311
+ isTypeIncomplete,
6312
+ });
6313
+ returnType = transformed.returnType;
6314
+ if (transformed.isTypeIncomplete) {
6315
+ isTypeIncomplete = true;
6316
+ }
6317
+ if (transformed.argumentErrors) {
6318
+ argumentErrors = true;
6319
+ }
6320
+ }
6321
+ if (expandedCallType.details.builtInName === '__import__') {
6322
+ // For the special __import__ type, we'll override the return type to be "Any".
6323
+ // This is required because we don't know what module was imported, and we don't
6324
+ // want to fail type checks when accessing members of the resulting module type.
6325
+ returnType = types_1.AnyType.create();
6326
+ }
6327
+ return {
6328
+ returnType,
6329
+ isTypeIncomplete,
6330
+ argumentErrors,
6331
+ overloadsUsedForCall: functionResult.overloadsUsedForCall,
6332
+ specializedInitSelfType: functionResult.specializedInitSelfType,
6333
+ };
6334
+ }
6335
+ function validateCallForOverloadedFunction(errorNode, argList, expandedCallType, isCallTypeIncomplete, typeVarContext, skipUnknownArgCheck, inferenceContext) {
6336
+ var _a, _b;
6337
+ // Handle the 'cast' call as a special case.
6338
+ if (expandedCallType.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
6339
+ return { returnType: evaluateCastCall(argList, errorNode) };
6340
+ }
6341
+ const callResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
6342
+ let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
6343
+ let isTypeIncomplete = !!callResult.isTypeIncomplete;
6344
+ let argumentErrors = !!callResult.argumentErrors;
6345
+ if (!argumentErrors) {
6346
+ // Call the function transform logic to handle special-cased functions.
6347
+ const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedCallType, {
6348
+ argumentErrors: !!callResult.argumentErrors,
6349
+ returnType: (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
6350
+ isTypeIncomplete,
6351
+ });
6352
+ returnType = transformed.returnType;
6353
+ if (transformed.isTypeIncomplete) {
6354
+ isTypeIncomplete = true;
6355
+ }
6356
+ if (transformed.argumentErrors) {
6357
+ argumentErrors = true;
6358
+ }
6359
+ }
6360
+ return {
6361
+ returnType,
6362
+ isTypeIncomplete,
6363
+ argumentErrors,
6364
+ overloadsUsedForCall: callResult.overloadsUsedForCall,
6365
+ specializedInitSelfType: callResult.specializedInitSelfType,
6366
+ };
6367
+ }
6368
+ function validateCallForInstantiableClass(errorNode, argList, expandedCallType, unexpandedCallType, skipUnknownArgCheck, inferenceContext) {
6369
+ var _a;
6370
+ if (expandedCallType.literalValue !== undefined) {
6371
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
6372
+ return { returnType: types_1.UnknownType.create(), argumentErrors: true };
6373
+ }
6374
+ if (types_1.ClassType.isBuiltIn(expandedCallType)) {
6375
+ const className = expandedCallType.aliasName || expandedCallType.details.name;
6376
+ if (className === 'type') {
6377
+ // Validate the constructor arguments.
6378
+ (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
6379
+ // Handle the 'type' call specially.
6380
+ if (argList.length === 1) {
6381
+ // The one-parameter form of "type" returns the class
6382
+ // for the specified object.
6383
+ const argType = getTypeOfArgument(argList[0]).type;
6384
+ const returnType = (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
6385
+ if ((0, types_1.isClassInstance)(subtype) ||
6386
+ ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
6387
+ (0, types_1.isNoneInstance)(subtype)) {
6388
+ return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
6389
+ }
6390
+ else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
6391
+ return types_1.FunctionType.cloneAsInstantiable(subtype);
6392
+ }
6393
+ return types_1.AnyType.create();
6394
+ });
6395
+ return { returnType };
6396
+ }
6397
+ if (argList.length >= 2) {
6398
+ // The two-parameter form of "type" returns a new class type
6399
+ // built from the specified base types.
6400
+ return { returnType: createType(errorNode, argList) || types_1.AnyType.create() };
6401
+ }
6402
+ // If the parameter to type() is not statically known,
6403
+ // fall back to Any.
6404
+ return { returnType: types_1.AnyType.create() };
6405
+ }
6406
+ if (className === 'TypeVar') {
6407
+ return {
6408
+ returnType: createTypeVarType(errorNode, expandedCallType, argList),
6409
+ };
6410
+ }
6411
+ if (className === 'TypeVarTuple') {
6412
+ return {
6413
+ returnType: createTypeVarTupleType(errorNode, expandedCallType, argList),
6414
+ };
6415
+ }
6416
+ if (className === 'ParamSpec') {
6417
+ return {
6418
+ returnType: createParamSpecType(errorNode, expandedCallType, argList),
6419
+ };
6420
+ }
6421
+ if (className === 'TypeAliasType') {
6422
+ const newTypeAlias = createTypeAliasType(errorNode, argList);
6423
+ if (newTypeAlias) {
6424
+ return { returnType: newTypeAlias };
6425
+ }
6426
+ }
6427
+ if (className === 'NamedTuple') {
6428
+ return {
6429
+ returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
6430
+ };
6431
+ }
6432
+ if (className === 'NewType') {
6433
+ return { returnType: createNewType(errorNode, argList) };
6434
+ }
6435
+ if (className === 'Protocol' ||
6436
+ className === 'Generic' ||
6437
+ className === 'Callable' ||
6438
+ className === 'Concatenate' ||
6439
+ className === 'Type') {
6440
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
6441
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
6442
+ return { returnType: types_1.AnyType.create() };
6443
+ }
6444
+ if ((0, types_1.isClass)(unexpandedCallType) && (0, enums_1.isKnownEnumType)(className)) {
6445
+ return {
6446
+ returnType: (_a = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedCallType, argList)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(),
6447
+ };
6448
+ }
6449
+ if (className === 'TypedDict') {
6450
+ return { returnType: (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedCallType, argList) };
6451
+ }
6452
+ if (className === 'auto' && argList.length === 0) {
6453
+ return { returnType: (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode) };
6454
+ }
6455
+ }
6456
+ if (types_1.ClassType.supportsAbstractMethods(expandedCallType)) {
6457
+ const abstractMethods = getAbstractMethods(expandedCallType);
6458
+ if (abstractMethods.length > 0 && !expandedCallType.includeSubclasses && !(0, types_1.isTypeVar)(unexpandedCallType)) {
6459
+ // If the class is abstract, it can't be instantiated.
6460
+ const diagAddendum = new diagnostic_1.DiagnosticAddendum();
6461
+ const errorsToDisplay = 2;
6462
+ abstractMethods.forEach((abstractMethod, index) => {
6463
+ if (index === errorsToDisplay) {
6464
+ diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
6465
+ count: abstractMethods.length - errorsToDisplay,
6466
+ }));
6467
+ }
6468
+ else if (index < errorsToDisplay) {
6469
+ if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
6470
+ const className = abstractMethod.classType.details.name;
6471
+ diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
6472
+ type: className,
6473
+ name: abstractMethod.symbolName,
6474
+ }));
6475
+ }
6476
+ }
6477
+ });
6478
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
6479
+ type: expandedCallType.details.name,
6480
+ }) + diagAddendum.getString(), errorNode);
6481
+ }
6482
+ }
6483
+ if (types_1.ClassType.isProtocolClass(expandedCallType) && !expandedCallType.includeSubclasses) {
6484
+ // If the class is a protocol, it can't be instantiated.
6485
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
6486
+ type: expandedCallType.details.name,
6487
+ }), errorNode);
6488
+ }
6489
+ // Assume this is a call to the constructor.
6490
+ const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedCallType, skipUnknownArgCheck, inferenceContext);
6491
+ const overloadsUsedForCall = constructorResult.overloadsUsedForCall;
6492
+ const argumentErrors = constructorResult.argumentErrors;
6493
+ const isTypeIncomplete = constructorResult.isTypeIncomplete;
6494
+ let returnType = constructorResult.returnType;
6495
+ // If the expandedCallType originated from a TypeVar, convert
6496
+ // the constructed type back to the TypeVar. For example, if
6497
+ // we have `cls: Type[_T]` followed by `_T()`.
6498
+ if ((0, types_1.isTypeVar)(unexpandedCallType)) {
6499
+ returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
6500
+ }
6501
+ // If we instantiated a type, transform it into a class.
6502
+ // This can happen if someone directly instantiates a metaclass
6503
+ // deriving from type.
6504
+ if (returnType &&
6505
+ (0, types_1.isClassInstance)(returnType) &&
6506
+ returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
6507
+ let newClassName = '__class_' + returnType.details.name;
6508
+ if (argList.length === 3) {
6509
+ const firstArgType = getTypeOfArgument(argList[0]).type;
6510
+ if ((0, types_1.isClassInstance)(firstArgType) &&
6511
+ types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
6512
+ typeof firstArgType.literalValue === 'string') {
6513
+ newClassName = firstArgType.literalValue;
6514
+ }
6515
+ }
6516
+ const newClassType = types_1.ClassType.createInstantiable(newClassName, '', '', AnalyzerNodeInfo.getFileInfo(errorNode).filePath, 0 /* None */, ParseTreeUtils.getTypeSourceId(errorNode), types_1.ClassType.cloneAsInstantiable(returnType), types_1.ClassType.cloneAsInstantiable(returnType));
6517
+ newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
6518
+ newClassType.details.effectiveMetaclass = expandedCallType;
6519
+ (0, typeUtils_1.computeMroLinearization)(newClassType);
6520
+ returnType = newClassType;
6521
+ }
6522
+ return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
6523
+ }
6524
+ function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
6525
+ var _a, _b;
6526
+ const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
6527
+ /* usage */ undefined,
6528
+ /* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
6529
+ if (!memberType) {
6530
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6531
+ type: printType(expandedCallType),
6532
+ }), errorNode);
6533
+ return { returnType: types_1.UnknownType.create(), argumentErrors: true };
6534
+ }
6535
+ const callResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6536
+ let returnType = (_b = callResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create();
6537
+ if ((0, types_1.isTypeVar)(unexpandedCallType) &&
6538
+ types_1.TypeBase.isInstantiable(unexpandedCallType) &&
6539
+ (0, types_1.isClass)(expandedCallType) &&
6540
+ types_1.ClassType.isBuiltIn(expandedCallType, 'type')) {
6541
+ // Handle the case where a Type[T] is being called. We presume this
6542
+ // will instantiate an object of type T.
6543
+ returnType = (0, typeUtils_1.convertToInstance)(unexpandedCallType);
6544
+ }
6545
+ return {
6546
+ returnType,
6547
+ argumentErrors: callResult.argumentErrors,
6548
+ overloadsUsedForCall: callResult.overloadsUsedForCall,
6549
+ };
6550
+ }
6466
6551
  // Evaluates the type of the "cast" call.
6467
6552
  function evaluateCastCall(argList, errorNode) {
6468
6553
  // Verify that the cast is necessary.
6469
- const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
6554
+ const castToType = getTypeOfArgumentExpectingType(argList[0], { enforceTypeAnnotationRules: true }).type;
6470
6555
  const castFromType = getTypeOfArgument(argList[1]).type;
6471
6556
  if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
6472
6557
  if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
@@ -7328,6 +7413,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7328
7413
  paramSpecArgList,
7329
7414
  activeParam,
7330
7415
  relevance,
7416
+ argumentMatchScore: 0,
7331
7417
  };
7332
7418
  }
7333
7419
  // After having matched arguments with parameters, this function evaluates the
@@ -7403,7 +7489,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7403
7489
  const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
7404
7490
  /* typeArguments */ undefined,
7405
7491
  /* isTypeArgumentExplicit */ false);
7406
- effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext);
7492
+ effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext, {
7493
+ unknownIfNotFound: true,
7494
+ });
7407
7495
  }
7408
7496
  }
7409
7497
  else if ((0, types_1.isFunction)(effectiveReturnType)) {
@@ -7426,6 +7514,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7426
7514
  const type = matchResults.overload;
7427
7515
  let isTypeIncomplete = matchResults.isTypeIncomplete;
7428
7516
  let argumentErrors = false;
7517
+ let argumentMatchScore = 0;
7429
7518
  let specializedInitSelfType;
7430
7519
  let anyOrUnknownArgument;
7431
7520
  const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
@@ -7527,7 +7616,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7527
7616
  let sawParamSpecKwargs = false;
7528
7617
  let condition = [];
7529
7618
  const argResults = [];
7530
- matchResults.argParams.forEach((argParam) => {
7619
+ matchResults.argParams.forEach((argParam, argParamIndex) => {
7531
7620
  var _a;
7532
7621
  const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
7533
7622
  skipUnknownArgCheck,
@@ -7536,6 +7625,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7536
7625
  argResults.push(argResult);
7537
7626
  if (!argResult.isCompatible) {
7538
7627
  argumentErrors = true;
7628
+ // Add the inverse index so earlier parameters represent larger errors.
7629
+ // This will help the heuristics in the overload error paths to pick the
7630
+ // most likely intended overload if none of them match.
7631
+ argumentMatchScore += 1 + (matchResults.argParams.length - argParamIndex);
7539
7632
  }
7540
7633
  if (argResult.isTypeIncomplete) {
7541
7634
  isTypeIncomplete = true;
@@ -7565,6 +7658,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7565
7658
  if (matchResults.paramSpecArgList && matchResults.paramSpecTarget) {
7566
7659
  if (!validateFunctionArgumentsForParamSpec(errorNode, matchResults.paramSpecArgList, matchResults.paramSpecTarget, typeVarContext, typeCondition)) {
7567
7660
  argumentErrors = true;
7661
+ argumentMatchScore += 1;
7568
7662
  }
7569
7663
  }
7570
7664
  else if (type.details.paramSpec) {
@@ -7573,6 +7667,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7573
7667
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecArgsMissing().format({ type: printType(type.details.paramSpec) }), errorNode);
7574
7668
  }
7575
7669
  argumentErrors = true;
7670
+ argumentMatchScore += 1;
7576
7671
  }
7577
7672
  }
7578
7673
  // Calculate the return type.
@@ -7654,6 +7749,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7654
7749
  if (specializedInitSelfType) {
7655
7750
  specializedInitSelfType = (0, typeUtils_1.applySolvedTypeVars)(specializedInitSelfType, typeVarContext);
7656
7751
  }
7752
+ matchResults.argumentMatchScore = argumentMatchScore;
7657
7753
  return {
7658
7754
  argumentErrors,
7659
7755
  argResults,
@@ -7698,7 +7794,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7698
7794
  // specific use case. We may need to make this more sophisticated in
7699
7795
  // the future.
7700
7796
  if ((0, types_1.isFunction)(returnType) && !returnType.details.name) {
7701
- return types_1.FunctionType.cloneWithNewTypeVarScopeId(returnType, types_1.WildcardTypeVarScopeId);
7797
+ const typeVarsInReturnType = (0, typeUtils_1.getTypeVarArgumentsRecursive)(returnType);
7798
+ // If there are no unsolved type variables, we're done. If there are
7799
+ // unsolved type parameters, treat them as though they are rescoped
7800
+ // to the callable.
7801
+ if (typeVarsInReturnType.length > 0) {
7802
+ return types_1.FunctionType.cloneWithNewTypeVarScopeId(returnType, types_1.WildcardTypeVarScopeId, typeVarsInReturnType);
7803
+ }
7702
7804
  }
7703
7805
  return returnType;
7704
7806
  }
@@ -8816,9 +8918,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8816
8918
  // Dict and MutableMapping types have invariant value types, so they
8817
8919
  // cannot be narrowed further. Other super-types like Mapping, Collection,
8818
8920
  // and Iterable use covariant value types, so they can be narrowed.
8819
- const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
8820
- (types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
8821
- types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
8921
+ let isValueTypeInvariant = false;
8922
+ if ((0, types_1.isClassInstance)(inferenceContext.expectedType)) {
8923
+ if (inferenceContext.expectedType.details.typeParameters.length >= 2) {
8924
+ const valueTypeParam = inferenceContext.expectedType.details.typeParameters[1];
8925
+ if (types_1.TypeVarType.getVariance(valueTypeParam) === 2 /* Invariant */) {
8926
+ isValueTypeInvariant = true;
8927
+ }
8928
+ }
8929
+ }
8822
8930
  // Infer the key and value types if possible.
8823
8931
  if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
8824
8932
  /* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
@@ -9416,7 +9524,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9416
9524
  if (returnTypeResult.isIncomplete) {
9417
9525
  isIncomplete = true;
9418
9526
  }
9419
- }, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType);
9527
+ }, {
9528
+ dependentType: inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType,
9529
+ });
9420
9530
  // Mark the function type as no longer being evaluated.
9421
9531
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
9422
9532
  return { type: functionType, isIncomplete };
@@ -9642,13 +9752,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9642
9752
  }
9643
9753
  return true;
9644
9754
  }
9645
- // Converts the type parameters for a Callable type. It should
9646
- // have zero to two parameters. The first parameter, if present, should be
9647
- // either an ellipsis or a list of parameter types. The second parameter, if
9648
- // present, should specify the return type.
9755
+ // Evaluates the type arguments for a Callable type. It should have zero
9756
+ // to two arguments.The first argument, if present, should be an ellipsis,
9757
+ // a ParamSpec, a Concatenate, or a list of positional parameter types.
9758
+ // The second argument, if present, should specify the return type.
9649
9759
  function createCallableType(typeArgs, errorNode) {
9650
- // Create a new function that is marked as "static" so there is later
9651
- // no attempt to bind it as though it's an instance or class method.
9652
9760
  const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
9653
9761
  types_1.TypeBase.setSpecialForm(functionType);
9654
9762
  functionType.details.declaredReturnType = types_1.UnknownType.create();
@@ -10342,12 +10450,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10342
10450
  // Determine if there are any generic type parameters associated
10343
10451
  // with this type alias.
10344
10452
  typeParameters = [];
10345
- // Skip this for a simple TypeVar (one that's not part of a union).
10346
- if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
10347
- (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10348
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10349
- });
10350
- }
10453
+ (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10454
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10455
+ });
10351
10456
  // Don't include any synthesized type variables.
10352
10457
  typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
10353
10458
  }
@@ -10881,10 +10986,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10881
10986
  // If the base class is partially evaluated, install a callback
10882
10987
  // so we can fix up this class (e.g. compute the MRO) when the
10883
10988
  // dependent class is completed.
10884
- classTypeHooks.push({
10885
- dependency: argType,
10886
- callback: () => completeClassTypeDeferred(classType, node, node.name),
10887
- });
10989
+ registerDeferredClassCompletion(node, argType);
10888
10990
  }
10889
10991
  if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
10890
10992
  if (!fileInfo.isStubFile &&
@@ -11200,8 +11302,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11200
11302
  (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11201
11303
  (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11202
11304
  }
11203
- // Run any class hooks that depend on this class.
11204
- runClassTypeHooks(classType);
11305
+ // Run any deferred class completions that depend on this class.
11306
+ runDeferredClassCompletions(classType);
11307
+ // If there are any outstanding deferred class completions registered that
11308
+ // were not removed by the call to runDeferredClassCompletions, assume that
11309
+ // the current class may depend on them and register for deferred completion.
11310
+ registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
11205
11311
  // Synthesize TypedDict methods.
11206
11312
  if (types_1.ClassType.isTypedDictClass(classType)) {
11207
11313
  (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
@@ -11434,21 +11540,47 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11434
11540
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarsNotInGenericOrProtocol() + diag.getString(), errorNode);
11435
11541
  }
11436
11542
  }
11437
- // Runs any registered "callback hooks" that depend on the specified class type.
11438
- // This allows us to complete any work that requires dependent classes to be
11439
- // completed.
11440
- function runClassTypeHooks(type) {
11441
- classTypeHooks.forEach((hook) => {
11442
- if (types_1.ClassType.isSameGenericClass(hook.dependency, type)) {
11443
- hook.callback();
11543
+ // Records the fact that the specified class requires "deferred completion" because
11544
+ // one of its base classes has not yet been fully evaluated. If the caller passes
11545
+ // undefined for "dependsUpon", then the class is added to all outstanding deferred
11546
+ // completions.
11547
+ function registerDeferredClassCompletion(classToComplete, dependsUpon) {
11548
+ if (dependsUpon) {
11549
+ // See if there is an existing entry for this dependency.
11550
+ const entry = deferredClassCompletions.find((e) => types_1.ClassType.isSameGenericClass(e.dependsUpon, dependsUpon));
11551
+ if (entry) {
11552
+ entry.classesToComplete.push(classToComplete);
11553
+ }
11554
+ else {
11555
+ deferredClassCompletions.push({ dependsUpon, classesToComplete: [classToComplete] });
11556
+ }
11557
+ }
11558
+ else {
11559
+ deferredClassCompletions.forEach((e) => {
11560
+ e.classesToComplete.push(classToComplete);
11561
+ });
11562
+ }
11563
+ }
11564
+ // Runs any registered "deferred class completions" that depend on the specified
11565
+ // class type. This allows us to complete any work that requires dependent classes
11566
+ // to be completed.
11567
+ function runDeferredClassCompletions(type) {
11568
+ deferredClassCompletions.forEach((e) => {
11569
+ if (types_1.ClassType.isSameGenericClass(e.dependsUpon, type)) {
11570
+ e.classesToComplete.forEach((classNode) => {
11571
+ const classType = readTypeCache(classNode.name, 0 /* None */);
11572
+ if (classType) {
11573
+ completeClassTypeDeferred(classType, classNode.name);
11574
+ }
11575
+ });
11444
11576
  }
11445
11577
  });
11446
- // Remove any hooks that depend on this type.
11447
- classTypeHooks = classTypeHooks.filter((hook) => !types_1.ClassType.isSameGenericClass(hook.dependency, type));
11578
+ // Remove any completions that depend on this type.
11579
+ deferredClassCompletions = deferredClassCompletions.filter((e) => !types_1.ClassType.isSameGenericClass(e.dependsUpon, type));
11448
11580
  }
11449
11581
  // Recomputes the MRO and effective metaclass for the class after dependent
11450
11582
  // classes have been fully constructed.
11451
- function completeClassTypeDeferred(type, node, errorNode) {
11583
+ function completeClassTypeDeferred(type, errorNode) {
11452
11584
  // Recompute the MRO linearization.
11453
11585
  if (!(0, typeUtils_1.computeMroLinearization)(type)) {
11454
11586
  addError(localize_1.Localizer.Diagnostic.methodOrdering(), errorNode);
@@ -13273,10 +13405,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13273
13405
  // Handle "type" specially, since it needs to act like "Type"
13274
13406
  // in Python 3.9 and newer.
13275
13407
  if (types_1.ClassType.isBuiltIn(classType, 'type') && typeArgs) {
13276
- // PEP 484 says that type[Any] should be considered
13277
- // equivalent to type.
13278
- if (typeArgs.length === 1 && (0, types_1.isAnyOrUnknown)(typeArgs[0].type)) {
13279
- return { type: classType };
13408
+ if (typeArgs.length >= 1) {
13409
+ // PEP 484 says that type[Any] should be considered
13410
+ // equivalent to type.
13411
+ if ((0, types_1.isAnyOrUnknown)(typeArgs[0].type)) {
13412
+ return { type: classType };
13413
+ }
13414
+ // Treat type[function] as illegal.
13415
+ if ((0, types_1.isFunction)(typeArgs[0].type) || (0, types_1.isOverloadedFunction)(typeArgs[0].type)) {
13416
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationWithCallable(), typeArgs[0].node);
13417
+ return { type: types_1.UnknownType.create() };
13418
+ }
13280
13419
  }
13281
13420
  const typeClass = getTypingType(errorNode, 'Type');
13282
13421
  if (typeClass && (0, types_1.isInstantiableClass)(typeClass)) {
@@ -13528,13 +13667,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13528
13667
  // used in cases where the argument is expected to be a type
13529
13668
  // and therefore follows the normal rules of types (e.g. they
13530
13669
  // can be forward-declared in stubs, etc.).
13531
- function getTypeOfArgumentExpectingType(arg) {
13670
+ function getTypeOfArgumentExpectingType(arg, options) {
13532
13671
  if (arg.typeResult) {
13533
13672
  return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
13534
13673
  }
13535
13674
  // If there was no defined type provided, there should always
13536
13675
  // be a value expression from which we can retrieve the type.
13537
- return getTypeOfExpressionExpectingType(arg.valueExpression);
13676
+ return getTypeOfExpressionExpectingType(arg.valueExpression, options);
13538
13677
  }
13539
13678
  function getTypeOfExpressionExpectingType(node, options) {
13540
13679
  let flags = 128 /* ExpectingInstantiableType */ |
@@ -13565,6 +13704,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13565
13704
  if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
13566
13705
  flags |= 32 /* DisallowParamSpec */;
13567
13706
  }
13707
+ if (options === null || options === void 0 ? void 0 : options.enforceTypeAnnotationRules) {
13708
+ flags |= 256 /* ExpectingTypeAnnotation */;
13709
+ }
13568
13710
  return getTypeOfExpression(node, flags);
13569
13711
  }
13570
13712
  function getBuiltInType(node, name) {
@@ -13695,11 +13837,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13695
13837
  // types, under the assumption that we're performing speculative evaluations.
13696
13838
  // If speculativeNode is undefined, speculative mode is not used. This is
13697
13839
  // useful in cases where we conditionally want to use speculative mode.
13698
- function useSpeculativeMode(speculativeNode, callback, dependentType) {
13840
+ function useSpeculativeMode(speculativeNode, callback, options) {
13699
13841
  if (!speculativeNode) {
13700
13842
  return callback();
13701
13843
  }
13702
- speculativeTypeTracker.enterSpeculativeContext(speculativeNode, dependentType);
13844
+ speculativeTypeTracker.enterSpeculativeContext(speculativeNode, options);
13703
13845
  try {
13704
13846
  const result = callback();
13705
13847
  speculativeTypeTracker.leaveSpeculativeContext();
@@ -15156,6 +15298,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15156
15298
  }
15157
15299
  }
15158
15300
  });
15301
+ if (!isAssignable) {
15302
+ return false;
15303
+ }
15159
15304
  // Now handle generic base classes.
15160
15305
  destType.details.baseClasses.forEach((baseClass) => {
15161
15306
  if ((0, types_1.isInstantiableClass)(baseClass) &&
@@ -15401,63 +15546,50 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15401
15546
  srcTypeArgs = srcType.typeArguments;
15402
15547
  }
15403
15548
  let isCompatible = true;
15404
- if (srcTypeArgs) {
15405
- for (let srcArgIndex = 0; srcArgIndex < srcTypeArgs.length; srcArgIndex++) {
15406
- const srcTypeArg = srcTypeArgs[srcArgIndex];
15407
- // In most cases, the number of type args should match the number
15408
- // of type arguments, but there are a few special cases where this
15409
- // isn't true (e.g. assigning a Tuple[X, Y, Z] to a tuple[W]).
15410
- const destArgIndex = srcArgIndex >= destTypeArgs.length ? destTypeArgs.length - 1 : srcArgIndex;
15411
- const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
15412
- const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
15413
- const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
15414
- if (!destTypeParam || types_1.TypeVarType.getVariance(destTypeParam) === 3 /* Covariant */) {
15415
- if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15416
- if (diag) {
15417
- if (destTypeParam) {
15418
- const childDiag = diag.createAddendum();
15419
- childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant().format({
15420
- name: types_1.TypeVarType.getReadableName(destTypeParam),
15421
- }));
15422
- childDiag.addAddendum(assignmentDiag);
15423
- }
15424
- else {
15425
- diag.addAddendum(assignmentDiag);
15426
- }
15427
- }
15428
- isCompatible = false;
15429
- }
15430
- }
15431
- else if (types_1.TypeVarType.getVariance(destTypeParam) === 4 /* Contravariant */) {
15432
- if (!assignType(srcTypeArg, destTypeArg, assignmentDiag, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15433
- if (diag) {
15549
+ srcTypeArgs === null || srcTypeArgs === void 0 ? void 0 : srcTypeArgs.forEach((srcTypeArg, srcArgIndex) => {
15550
+ // In most cases, the number of type args should match the number
15551
+ // of type arguments, but there are a few special cases where this
15552
+ // isn't true (e.g. assigning a Tuple[X, Y, Z] to a tuple[W]).
15553
+ const destArgIndex = srcArgIndex >= destTypeArgs.length ? destTypeArgs.length - 1 : srcArgIndex;
15554
+ const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
15555
+ const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
15556
+ const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
15557
+ const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
15558
+ let effectiveFlags;
15559
+ let errorSource;
15560
+ if (variance === 3 /* Covariant */) {
15561
+ effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
15562
+ errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
15563
+ }
15564
+ else if (variance === 4 /* Contravariant */) {
15565
+ effectiveFlags =
15566
+ (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */;
15567
+ errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant;
15568
+ }
15569
+ else {
15570
+ effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
15571
+ errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
15572
+ }
15573
+ if (!assignType(variance === 4 /* Contravariant */ ? srcTypeArg : destTypeArg, variance === 4 /* Contravariant */ ? destTypeArg : srcTypeArg, assignmentDiag, variance === 4 /* Contravariant */ ? srcTypeVarContext : destTypeVarContext, variance === 4 /* Contravariant */ ? destTypeVarContext : srcTypeVarContext, effectiveFlags, recursionCount)) {
15574
+ // Don't report errors with type variables in "pseudo-random"
15575
+ // classes since these type variables are not real.
15576
+ if (!types_1.ClassType.isPseudoGenericClass(destType)) {
15577
+ if (diag) {
15578
+ if (destTypeParam) {
15434
15579
  const childDiag = diag.createAddendum();
15435
- childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant().format({
15580
+ childDiag.addMessage(errorSource().format({
15436
15581
  name: types_1.TypeVarType.getReadableName(destTypeParam),
15582
+ ...printSrcDestTypes(srcTypeArg, destTypeArg),
15437
15583
  }));
15438
- childDiag.addAddendum(assignmentDiag);
15439
15584
  }
15440
- isCompatible = false;
15441
- }
15442
- }
15443
- else {
15444
- if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15445
- // Don't report errors with type variables in "pseudo-random"
15446
- // classes since these type variables are not real.
15447
- if (!types_1.ClassType.isPseudoGenericClass(destType)) {
15448
- if (diag) {
15449
- const childDiag = diag.createAddendum();
15450
- childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant().format({
15451
- name: types_1.TypeVarType.getReadableName(destTypeParam),
15452
- }));
15453
- childDiag.addAddendum(assignmentDiag);
15454
- }
15455
- isCompatible = false;
15585
+ else {
15586
+ diag.addAddendum(assignmentDiag);
15456
15587
  }
15457
15588
  }
15589
+ isCompatible = false;
15458
15590
  }
15459
15591
  }
15460
- }
15592
+ });
15461
15593
  return isCompatible;
15462
15594
  }
15463
15595
  // Determines if the source type can be assigned to the dest type.
@@ -15647,8 +15779,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15647
15779
  destType.details.parameters.length <= 2) {
15648
15780
  return true;
15649
15781
  }
15650
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
15651
- return false;
15782
+ if (!(0, types_1.isUnion)(destType)) {
15783
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
15784
+ return false;
15785
+ }
15652
15786
  }
15653
15787
  }
15654
15788
  if ((0, types_1.isAnyOrUnknown)(destType)) {
@@ -15678,25 +15812,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15678
15812
  return true;
15679
15813
  }
15680
15814
  if ((0, types_1.isUnion)(destType)) {
15815
+ // If both the source and dest are unions, use assignFromUnionType which has
15816
+ // special-case logic to handle this case.
15681
15817
  if ((0, types_1.isUnion)(srcType)) {
15682
- if (assignFromUnionType(destType, srcType,
15683
- /* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount)) {
15684
- return true;
15685
- }
15818
+ return assignFromUnionType(destType, srcType,
15819
+ /* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount);
15686
15820
  }
15687
- else {
15688
- const clonedDestTypeVarContext = destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone();
15689
- const clonedSrcTypeVarContext = srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone();
15690
- if (assignToUnionType(destType, srcType,
15691
- /* diag */ undefined, clonedDestTypeVarContext, clonedSrcTypeVarContext, originalFlags, recursionCount)) {
15692
- if (destTypeVarContext && clonedDestTypeVarContext) {
15693
- destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
15694
- }
15695
- if (srcTypeVarContext && clonedSrcTypeVarContext) {
15696
- srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
15697
- }
15698
- return true;
15821
+ const clonedDestTypeVarContext = destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone();
15822
+ const clonedSrcTypeVarContext = srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone();
15823
+ if (assignToUnionType(destType, srcType,
15824
+ /* diag */ undefined, clonedDestTypeVarContext, clonedSrcTypeVarContext, originalFlags, recursionCount)) {
15825
+ if (destTypeVarContext && clonedDestTypeVarContext) {
15826
+ destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
15827
+ }
15828
+ if (srcTypeVarContext && clonedSrcTypeVarContext) {
15829
+ srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
15699
15830
  }
15831
+ return true;
15700
15832
  }
15701
15833
  }
15702
15834
  const expandedSrcType = makeTopLevelTypeVarsConcrete(srcType);
@@ -16047,6 +16179,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16047
16179
  // whose primary type matches.
16048
16180
  remainingSrcSubtypes.forEach((srcSubtype) => {
16049
16181
  const destTypeIndex = remainingDestSubtypes.findIndex((destSubtype) => {
16182
+ if ((0, types_1.isTypeSame)(destSubtype, srcSubtype)) {
16183
+ return true;
16184
+ }
16050
16185
  if ((0, types_1.isClass)(srcSubtype) &&
16051
16186
  (0, types_1.isClass)(destSubtype) &&
16052
16187
  types_1.TypeBase.isInstance(srcSubtype) === types_1.TypeBase.isInstance(destSubtype) &&
@@ -16071,6 +16206,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16071
16206
  // If there is are remaining dest subtypes and they're all type variables,
16072
16207
  // attempt to assign the remaining source subtypes to them.
16073
16208
  if (canUseFastPath && (remainingDestSubtypes.length !== 0 || remainingSrcSubtypes.length !== 0)) {
16209
+ if ((flags & 1 /* EnforceInvariance */) !== 0) {
16210
+ // If we have no src subtypes remaining but not all dest types have been subsumed
16211
+ // by other dest types, then the types are not compatible if we're enforcing invariance.
16212
+ if (remainingSrcSubtypes.length === 0) {
16213
+ return remainingDestSubtypes.every((destSubtype) => isTypeSubsumedByOtherType(destSubtype, destType.subtypes,
16214
+ /* allowAnyToSubsume */ true, recursionCount));
16215
+ }
16216
+ }
16074
16217
  const isReversed = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
16075
16218
  const effectiveDestSubtypes = isReversed ? remainingSrcSubtypes : remainingDestSubtypes;
16076
16219
  if (effectiveDestSubtypes.length === 0 || effectiveDestSubtypes.some((t) => !(0, types_1.isTypeVar)(t))) {
@@ -16122,21 +16265,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16122
16265
  }
16123
16266
  if (!assignType(destType, subtype,
16124
16267
  /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
16125
- const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
16126
16268
  // Determine if the current subtype is subsumed by another subtype
16127
16269
  // in the same union. If so, we can ignore this.
16128
- let isSubtypeSubsumed = false;
16129
- srcType.subtypes.forEach((innerSubtype) => {
16130
- if (!isSubtypeSubsumed &&
16131
- !(0, types_1.isTypeSame)(innerSubtype, subtype) &&
16132
- !(0, types_1.isAnyOrUnknown)(innerSubtype) &&
16133
- isProperSubtype(innerSubtype, concreteSubtype, recursionCount)) {
16134
- isSubtypeSubsumed = true;
16135
- }
16136
- });
16270
+ const isSubtypeSubsumed = isTypeSubsumedByOtherType(subtype, srcType.subtypes,
16271
+ /* allowAnyToSubsume */ false, recursionCount);
16137
16272
  // Try again with a concrete version of the subtype.
16138
16273
  if (!isSubtypeSubsumed &&
16139
- !assignType(destType, concreteSubtype, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
16274
+ !assignType(destType, subtype, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
16140
16275
  isIncompatible = true;
16141
16276
  }
16142
16277
  }
@@ -16147,6 +16282,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16147
16282
  }
16148
16283
  return true;
16149
16284
  }
16285
+ // Determines whether a type is "subsumed by" (i.e. is a proper subtype of) one
16286
+ // of the other types in a list.
16287
+ function isTypeSubsumedByOtherType(type, otherTypes, allowAnyToSubsume, recursionCount = 0) {
16288
+ const concreteType = makeTopLevelTypeVarsConcrete(type);
16289
+ for (const otherType of otherTypes) {
16290
+ if ((0, types_1.isTypeSame)(otherType, type)) {
16291
+ continue;
16292
+ }
16293
+ if ((0, types_1.isAnyOrUnknown)(otherType)) {
16294
+ if (allowAnyToSubsume) {
16295
+ return true;
16296
+ }
16297
+ }
16298
+ else if (isProperSubtype(otherType, concreteType, recursionCount)) {
16299
+ return true;
16300
+ }
16301
+ }
16302
+ return false;
16303
+ }
16150
16304
  // Determines whether the srcType is a subtype of destType but the converse
16151
16305
  // is not true. It's important that we check both directions to avoid
16152
16306
  // matches for types like `tuple[Any]` and `tuple[int]` from being considered