@zzzen/pyright-internal 1.2.0-dev.20230709 → 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 (135) hide show
  1. package/dist/analyzer/backgroundAnalysisProgram.d.ts +2 -2
  2. package/dist/analyzer/backgroundAnalysisProgram.js +3 -3
  3. package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
  4. package/dist/analyzer/binder.d.ts +1 -0
  5. package/dist/analyzer/binder.js +19 -2
  6. package/dist/analyzer/binder.js.map +1 -1
  7. package/dist/analyzer/checker.d.ts +1 -0
  8. package/dist/analyzer/checker.js +14 -24
  9. package/dist/analyzer/checker.js.map +1 -1
  10. package/dist/analyzer/codeFlowEngine.js +12 -1
  11. package/dist/analyzer/codeFlowEngine.js.map +1 -1
  12. package/dist/analyzer/constraintSolver.js +42 -36
  13. package/dist/analyzer/constraintSolver.js.map +1 -1
  14. package/dist/analyzer/constructorTransform.js +11 -1
  15. package/dist/analyzer/constructorTransform.js.map +1 -1
  16. package/dist/analyzer/constructors.js +11 -9
  17. package/dist/analyzer/constructors.js.map +1 -1
  18. package/dist/analyzer/enums.js +21 -8
  19. package/dist/analyzer/enums.js.map +1 -1
  20. package/dist/analyzer/namedTuples.js +33 -1
  21. package/dist/analyzer/namedTuples.js.map +1 -1
  22. package/dist/analyzer/patternMatching.d.ts +1 -1
  23. package/dist/analyzer/patternMatching.js +79 -66
  24. package/dist/analyzer/patternMatching.js.map +1 -1
  25. package/dist/analyzer/program.d.ts +5 -2
  26. package/dist/analyzer/program.js +18 -7
  27. package/dist/analyzer/program.js.map +1 -1
  28. package/dist/analyzer/protocols.js +57 -19
  29. package/dist/analyzer/protocols.js.map +1 -1
  30. package/dist/analyzer/service.js +1 -10
  31. package/dist/analyzer/service.js.map +1 -1
  32. package/dist/analyzer/sourceFile.d.ts +4 -3
  33. package/dist/analyzer/sourceFile.js +26 -22
  34. package/dist/analyzer/sourceFile.js.map +1 -1
  35. package/dist/analyzer/typeCacheUtils.d.ts +7 -2
  36. package/dist/analyzer/typeCacheUtils.js +11 -7
  37. package/dist/analyzer/typeCacheUtils.js.map +1 -1
  38. package/dist/analyzer/typeEvaluator.js +829 -601
  39. package/dist/analyzer/typeEvaluator.js.map +1 -1
  40. package/dist/analyzer/typeEvaluatorTypes.d.ts +8 -2
  41. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  42. package/dist/analyzer/typeGuards.d.ts +2 -2
  43. package/dist/analyzer/typeGuards.js +72 -12
  44. package/dist/analyzer/typeGuards.js.map +1 -1
  45. package/dist/analyzer/typePrinter.d.ts +2 -1
  46. package/dist/analyzer/typePrinter.js +26 -5
  47. package/dist/analyzer/typePrinter.js.map +1 -1
  48. package/dist/analyzer/typeUtils.js +11 -1
  49. package/dist/analyzer/typeUtils.js.map +1 -1
  50. package/dist/analyzer/typedDicts.js +1 -3
  51. package/dist/analyzer/typedDicts.js.map +1 -1
  52. package/dist/analyzer/types.d.ts +10 -3
  53. package/dist/analyzer/types.js +11 -2
  54. package/dist/analyzer/types.js.map +1 -1
  55. package/dist/backgroundAnalysisBase.d.ts +5 -5
  56. package/dist/backgroundAnalysisBase.js +2 -2
  57. package/dist/backgroundAnalysisBase.js.map +1 -1
  58. package/dist/backgroundThreadBase.js +1 -1
  59. package/dist/backgroundThreadBase.js.map +1 -1
  60. package/dist/common/console.d.ts +4 -1
  61. package/dist/common/console.js +7 -0
  62. package/dist/common/console.js.map +1 -1
  63. package/dist/languageServerBase.d.ts +8 -3
  64. package/dist/languageServerBase.js +30 -25
  65. package/dist/languageServerBase.js.map +1 -1
  66. package/dist/languageService/callHierarchyProvider.js +7 -10
  67. package/dist/languageService/callHierarchyProvider.js.map +1 -1
  68. package/dist/languageService/codeActionProvider.d.ts +1 -0
  69. package/dist/languageService/codeActionProvider.js +11 -0
  70. package/dist/languageService/codeActionProvider.js.map +1 -1
  71. package/dist/languageService/completionProvider.d.ts +1 -1
  72. package/dist/languageService/completionProvider.js +10 -4
  73. package/dist/languageService/completionProvider.js.map +1 -1
  74. package/dist/languageService/tooltipUtils.js +5 -2
  75. package/dist/languageService/tooltipUtils.js.map +1 -1
  76. package/dist/localization/localize.d.ts +9 -0
  77. package/dist/localization/localize.js +29 -3
  78. package/dist/localization/localize.js.map +1 -1
  79. package/dist/localization/package.nls.cs.json +719 -0
  80. package/dist/localization/package.nls.de.json +719 -1
  81. package/dist/localization/package.nls.en-us.json +7 -5
  82. package/dist/localization/package.nls.es.json +719 -1
  83. package/dist/localization/package.nls.fr.json +719 -1
  84. package/dist/localization/package.nls.it.json +719 -0
  85. package/dist/localization/package.nls.ja.json +719 -1
  86. package/dist/localization/package.nls.ko.json +719 -0
  87. package/dist/localization/package.nls.pl.json +719 -0
  88. package/dist/localization/package.nls.pt-br.json +719 -0
  89. package/dist/localization/package.nls.qps-ploc.json +719 -0
  90. package/dist/localization/package.nls.ru.json +719 -1
  91. package/dist/localization/package.nls.tr.json +719 -0
  92. package/dist/localization/package.nls.zh-cn.json +719 -1
  93. package/dist/localization/package.nls.zh-tw.json +719 -1
  94. package/dist/parser/parser.d.ts +3 -0
  95. package/dist/parser/parser.js +2 -31
  96. package/dist/parser/parser.js.map +1 -1
  97. package/dist/parser/tokenizer.d.ts +5 -2
  98. package/dist/parser/tokenizer.js +16 -4
  99. package/dist/parser/tokenizer.js.map +1 -1
  100. package/dist/parser/tokenizerTypes.d.ts +2 -2
  101. package/dist/parser/tokenizerTypes.js.map +1 -1
  102. package/dist/pprof/profiler.d.ts +36 -0
  103. package/dist/pprof/profiler.js +64 -0
  104. package/dist/pprof/profiler.js.map +1 -0
  105. package/dist/tests/checker.test.js +2 -2
  106. package/dist/tests/completions.test.js +40 -0
  107. package/dist/tests/completions.test.js.map +1 -1
  108. package/dist/tests/config.test.js +12 -0
  109. package/dist/tests/config.test.js.map +1 -1
  110. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.d.ts +1 -0
  111. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js +40 -0
  112. package/dist/tests/fourslash/showcallhierarchy.incomingCalls.overriddenFunction.fourslash.js.map +1 -0
  113. package/dist/tests/harness/fourslash/testState.d.ts +6 -4
  114. package/dist/tests/harness/fourslash/testState.js +50 -39
  115. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  116. package/dist/tests/harness/vfs/factory.d.ts +1 -0
  117. package/dist/tests/harness/vfs/factory.js +7 -1
  118. package/dist/tests/harness/vfs/factory.js.map +1 -1
  119. package/dist/tests/harness/vfs/filesystem.d.ts +2 -2
  120. package/dist/tests/harness/vfs/filesystem.js +13 -8
  121. package/dist/tests/harness/vfs/filesystem.js.map +1 -1
  122. package/dist/tests/localizer.test.js +20 -0
  123. package/dist/tests/localizer.test.js.map +1 -1
  124. package/dist/tests/typeEvaluator1.test.js +21 -1
  125. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  126. package/dist/tests/typeEvaluator2.test.js +21 -1
  127. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  128. package/dist/tests/typeEvaluator3.test.js +1 -1
  129. package/dist/tests/typeEvaluator4.test.js +14 -2
  130. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  131. package/dist/tests/typeEvaluator5.test.js +4 -0
  132. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  133. package/dist/workspaceFactory.js +5 -3
  134. package/dist/workspaceFactory.js.map +1 -1
  135. package/package.json +10 -8
@@ -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;
@@ -566,7 +566,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
566
566
  }
567
567
  case 31 /* List */:
568
568
  case 45 /* Set */: {
569
- typeResult = getTypeOfListOrSet(node, inferenceContext);
569
+ typeResult = getTypeOfListOrSet(node, flags, inferenceContext);
570
570
  break;
571
571
  }
572
572
  case 46 /* Slice */: {
@@ -586,7 +586,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
586
586
  break;
587
587
  }
588
588
  case 15 /* Dictionary */: {
589
- typeResult = getTypeOfDictionary(node, inferenceContext);
589
+ typeResult = getTypeOfDictionary(node, flags, inferenceContext);
590
590
  break;
591
591
  }
592
592
  case 30 /* Lambda */: {
@@ -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') {
@@ -1990,10 +1992,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1990
1992
  if (expectedTypeDiagAddendum) {
1991
1993
  diagAddendum = expectedTypeDiagAddendum;
1992
1994
  }
1993
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAssignmentMismatch().format({
1994
- sourceType: printType(type),
1995
- destType: printType(declaredType),
1996
- }) + diagAddendum.getString(), srcExpression !== null && srcExpression !== void 0 ? srcExpression : nameNode, (_c = (_b = diagAddendum.getEffectiveTextRange()) !== null && _b !== void 0 ? _b : srcExpression) !== null && _c !== void 0 ? _c : nameNode);
1995
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAssignmentMismatch().format(printSrcDestTypes(type, declaredType)) +
1996
+ diagAddendum.getString(), srcExpression !== null && srcExpression !== void 0 ? srcExpression : nameNode, (_c = (_b = diagAddendum.getEffectiveTextRange()) !== null && _b !== void 0 ? _b : srcExpression) !== null && _c !== void 0 ? _c : nameNode);
1997
1997
  // Replace the assigned type with the (unnarrowed) declared type.
1998
1998
  destType = declaredType;
1999
1999
  }
@@ -2394,20 +2394,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2394
2394
  // its bound type and a constrained TypeVar is expanded to its individual
2395
2395
  // constrained types). If conditionFilter is specified, conditions that
2396
2396
  // do not match will be ignored.
2397
- function mapSubtypesExpandTypeVars(type, conditionFilter, callback) {
2397
+ function mapSubtypesExpandTypeVars(type, conditionFilter, callback, recursionCount = 0) {
2398
2398
  const newSubtypes = [];
2399
2399
  let typeChanged = false;
2400
- const expandSubtype = (unexpandedType) => {
2400
+ function expandSubtype(unexpandedType, isLastSubtype) {
2401
2401
  let expandedType = (0, types_1.isUnion)(unexpandedType) ? unexpandedType : makeTopLevelTypeVarsConcrete(unexpandedType);
2402
2402
  expandedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedType);
2403
- (0, typeUtils_1.doForEachSubtype)(expandedType, (subtype) => {
2403
+ (0, typeUtils_1.doForEachSubtype)(expandedType, (subtype, index, allSubtypes) => {
2404
2404
  var _a;
2405
2405
  if (conditionFilter) {
2406
- if (!types_1.TypeCondition.isCompatible((0, typeUtils_1.getTypeCondition)(subtype), conditionFilter)) {
2406
+ const filteredType = applyConditionFilterToType(subtype, conditionFilter, recursionCount);
2407
+ if (!filteredType) {
2407
2408
  return undefined;
2408
2409
  }
2410
+ subtype = filteredType;
2409
2411
  }
2410
- let transformedType = callback(subtype, unexpandedType);
2412
+ let transformedType = callback(subtype, unexpandedType, isLastSubtype && index === allSubtypes.length - 1);
2411
2413
  if (transformedType !== unexpandedType) {
2412
2414
  typeChanged = true;
2413
2415
  }
@@ -2421,14 +2423,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2421
2423
  }
2422
2424
  return undefined;
2423
2425
  });
2424
- };
2426
+ }
2425
2427
  if ((0, types_1.isUnion)(type)) {
2426
- type.subtypes.forEach((subtype) => {
2427
- expandSubtype(subtype);
2428
+ type.subtypes.forEach((subtype, index) => {
2429
+ expandSubtype(subtype, index === type.subtypes.length - 1);
2428
2430
  });
2429
2431
  }
2430
2432
  else {
2431
- expandSubtype(type);
2433
+ expandSubtype(type, /* isLastSubtype */ true);
2432
2434
  }
2433
2435
  if (!typeChanged) {
2434
2436
  return type;
@@ -2440,6 +2442,40 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2440
2442
  }
2441
2443
  return newType;
2442
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
+ }
2443
2479
  function markNamesAccessed(node, names) {
2444
2480
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2445
2481
  const scope = ScopeUtils.getScopeForNode(node);
@@ -2816,7 +2852,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2816
2852
  // Verify that the name does not refer to a (non type alias) variable.
2817
2853
  if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
2818
2854
  let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
2819
- if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
2855
+ if ((0, types_1.isClass)(type) && !type.includeSubclasses && !symbol.hasTypedDeclarations()) {
2820
2856
  // This check exempts class types that are created by calling
2821
2857
  // NewType, NamedTuple, and by invoking a metaclass directly.
2822
2858
  isAllowedTypeForVariable = true;
@@ -2894,13 +2930,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2894
2930
  function getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType) {
2895
2931
  // This function applies only to variables, parameters, and imports, not to other
2896
2932
  // types of symbols.
2897
- if (!symbolWithScope.symbol
2898
- .getDeclarations()
2899
- .every((decl) => decl.type === 1 /* Variable */ ||
2933
+ const decls = symbolWithScope.symbol.getDeclarations();
2934
+ if (!decls.every((decl) => decl.type === 1 /* Variable */ ||
2900
2935
  decl.type === 2 /* Parameter */ ||
2901
2936
  decl.type === 8 /* Alias */)) {
2902
2937
  return undefined;
2903
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
+ }
2904
2946
  // If the symbol is a variable captured by an inner function
2905
2947
  // or lambda, see if we can infer the type from the outer scope.
2906
2948
  const scopeHierarchy = ScopeUtils.getScopeHierarchy(node, symbolWithScope.scope);
@@ -2936,7 +2978,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2936
2978
  return !codeFlowEngine.isFlowNodeReachable(declCodeFlowNode, innerScopeCodeFlowNode,
2937
2979
  /* ignoreNoReturn */ true);
2938
2980
  })) {
2939
- 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);
2940
2986
  }
2941
2987
  }
2942
2988
  }
@@ -3292,7 +3338,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3292
3338
  baseType = objectType;
3293
3339
  }
3294
3340
  }
3295
- const getTypeOfNoneBase = (subtype) => {
3341
+ function getTypeOfNoneBase(subtype) {
3296
3342
  if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
3297
3343
  if (types_1.TypeBase.isInstance(subtype)) {
3298
3344
  return getTypeOfObjectMember(node.memberName, types_1.ClassType.cloneAsInstance(noneType), memberName, usage, diag);
@@ -3302,7 +3348,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3302
3348
  }
3303
3349
  }
3304
3350
  return undefined;
3305
- };
3351
+ }
3306
3352
  if ((0, types_1.isParamSpec)(baseType) && baseType.paramSpecAccess) {
3307
3353
  baseType = makeTopLevelTypeVarsConcrete(baseType);
3308
3354
  }
@@ -3348,11 +3394,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3348
3394
  if (baseType.details.recursiveTypeAliasName) {
3349
3395
  return { type: types_1.UnknownType.create(/* isIncomplete */ true), isIncomplete: true };
3350
3396
  }
3351
- return getTypeOfMemberAccessWithBaseType(node, {
3352
- type: makeTopLevelTypeVarsConcrete(baseType),
3353
- bindToType: baseType,
3354
- isIncomplete,
3355
- }, 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;
3356
3405
  }
3357
3406
  case 7 /* Class */: {
3358
3407
  if (types_1.TypeBase.isInstantiable(baseType)) {
@@ -3681,6 +3730,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3681
3730
  types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
3682
3731
  setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
3683
3732
  }
3733
+ // Special-case `__init_subclass` and `__class_getitem__` because
3734
+ // these are always treated as class methods even if they're not
3735
+ // decorated as such.
3736
+ if (memberName === '__init_subclass__' || memberName === '__class_getitem__') {
3737
+ if ((0, types_1.isFunction)(type) && !types_1.FunctionType.isClassMethod(type)) {
3738
+ type = types_1.FunctionType.cloneWithNewFlags(type, type.details.flags | 2 /* ClassMethod */);
3739
+ }
3740
+ }
3684
3741
  }
3685
3742
  const descriptorResult = applyDescriptorAccessMethod(type, memberInfo, classType, bindToType, isAccessedThroughObject, flags, errorNode, memberName, usage, diag);
3686
3743
  if (!descriptorResult) {
@@ -3815,7 +3872,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3815
3872
  type: types_1.ClassType.isClassProperty(lookupClass)
3816
3873
  ? baseTypeClass
3817
3874
  : isAccessedThroughObject
3818
- ? bindToType || types_1.ClassType.cloneAsInstance(baseTypeClass)
3875
+ ? bindToType !== null && bindToType !== void 0 ? bindToType : types_1.ClassType.cloneAsInstance(baseTypeClass)
3819
3876
  : types_1.NoneType.createInstance(),
3820
3877
  },
3821
3878
  },
@@ -3964,8 +4021,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
3964
4021
  // If this function is an instance member (e.g. a lambda that was
3965
4022
  // assigned to an instance variable), don't perform any binding.
3966
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
+ }
3967
4036
  return bindFunctionToClassOrObject(isAccessedThroughObject ? types_1.ClassType.cloneAsInstance(baseTypeClass) : baseTypeClass, concreteSubtype, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, errorNode,
3968
- /* recursionCount */ undefined, treatConstructorAsClassMember, bindToType);
4037
+ /* recursionCount */ undefined, treatConstructorAsClassMember, effectiveBindToType);
3969
4038
  }
3970
4039
  }
3971
4040
  if (usage.method === 'set') {
@@ -4212,7 +4281,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4212
4281
  // We limit type narrowing for index expressions to built-in types that are
4213
4282
  // known to have symmetric __getitem__ and __setitem__ methods (i.e. the value
4214
4283
  // passed to __setitem__ is the same type as the value returned by __getitem__).
4215
- let baseTypeSupportsIndexNarrowing = true;
4284
+ let baseTypeSupportsIndexNarrowing = !(0, types_1.isAny)(baseTypeResult.type);
4216
4285
  mapSubtypesExpandTypeVars(baseTypeResult.type, /* conditionFilter */ undefined, (subtype) => {
4217
4286
  if (!(0, types_1.isClassInstance)(subtype) ||
4218
4287
  !(types_1.ClassType.isBuiltIn(subtype) || types_1.ClassType.isTypedDictClass(subtype))) {
@@ -4971,14 +5040,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4971
5040
  const getTypeArgTypeResult = (expr, argIndex) => {
4972
5041
  let typeResult;
4973
5042
  // If it's a custom __class_getitem__, none of the arguments should be
4974
- // treated as types. If it's an Annotated[a, b, c], only the first index
4975
- // should be treated as a type. The others can be regular (non-type) objects.
4976
- if ((options === null || options === void 0 ? void 0 : options.hasCustomClassGetItem) || ((options === null || options === void 0 ? void 0 : options.isAnnotatedClass) && argIndex > 0)) {
5043
+ // treated as types.
5044
+ if (options === null || options === void 0 ? void 0 : options.hasCustomClassGetItem) {
5045
+ adjFlags =
5046
+ 32 /* DisallowParamSpec */ |
5047
+ 64 /* DisallowTypeVarTuple */ |
5048
+ 2 /* DoNotSpecialize */ |
5049
+ 131072 /* DisallowClassVar */;
4977
5050
  typeResult = {
4978
- ...getTypeOfExpression(expr, 32 /* DisallowParamSpec */ |
5051
+ ...getTypeOfExpression(expr, adjFlags),
5052
+ node: expr,
5053
+ };
5054
+ }
5055
+ else if ((options === null || options === void 0 ? void 0 : options.isAnnotatedClass) && argIndex > 0) {
5056
+ // If it's an Annotated[a, b, c], only the first index should be
5057
+ // treated as a type.The others can be regular(non - type) objects.
5058
+ adjFlags =
5059
+ 32 /* DisallowParamSpec */ |
4979
5060
  64 /* DisallowTypeVarTuple */ |
4980
5061
  2 /* DoNotSpecialize */ |
4981
- 131072 /* DisallowClassVar */),
5062
+ 131072 /* DisallowClassVar */;
5063
+ if ((0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(AnalyzerNodeInfo.getFileInfo(node))) {
5064
+ adjFlags |= 4 /* AllowForwardReferences */;
5065
+ }
5066
+ typeResult = {
5067
+ ...getTypeOfExpression(expr, adjFlags),
4982
5068
  node: expr,
4983
5069
  };
4984
5070
  }
@@ -5073,6 +5159,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5073
5159
  return typeResult;
5074
5160
  }
5075
5161
  function getTypeOfTuple(node, flags, inferenceContext) {
5162
+ var _a;
5163
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
5164
+ ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 1 /* Argument */) {
5165
+ // This is allowed inside of an index trailer, specifically
5166
+ // to support Tuple[()], which is the documented way to annotate
5167
+ // a zero-length tuple.
5168
+ const diag = new diagnostic_1.DiagnosticAddendum();
5169
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useTupleInstead());
5170
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.tupleInAnnotation() + diag.getString(), node);
5171
+ }
5076
5172
  if ((flags & 128 /* ExpectingInstantiableType */) !== 0 &&
5077
5173
  node.expressions.length === 0 &&
5078
5174
  !inferenceContext) {
@@ -5230,12 +5326,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5230
5326
  function getTypeOfCall(node, flags, inferenceContext) {
5231
5327
  var _a;
5232
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.
5332
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
5333
+ node.leftExpression.nodeType === 38 /* Name */ &&
5334
+ node.leftExpression.value === 'type') {
5335
+ const diag = new diagnostic_1.DiagnosticAddendum();
5336
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useTypeInstead());
5337
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeCallNotAllowed() + diag.getString(), node);
5338
+ }
5233
5339
  // Handle immediate calls of lambdas specially.
5234
5340
  if (node.leftExpression.nodeType === 30 /* Lambda */) {
5235
5341
  baseTypeResult = getTypeOfLambdaForCall(node, inferenceContext);
5236
5342
  }
5237
5343
  else {
5238
- baseTypeResult = getTypeOfExpression(node.leftExpression, 2 /* DoNotSpecialize */);
5344
+ baseTypeResult = getTypeOfExpression(node.leftExpression, 2 /* DoNotSpecialize */ | (flags & 4 /* AllowForwardReferences */));
5239
5345
  }
5240
5346
  const argList = node.arguments.map((arg) => {
5241
5347
  const functionArg = {
@@ -5284,20 +5390,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5284
5390
  }
5285
5391
  }
5286
5392
  else {
5287
- // Check for an attempt to invoke an abstract static or class method.
5288
- if ((0, types_1.isFunction)(baseTypeResult.type) &&
5289
- baseTypeResult.type.boundToType &&
5290
- (0, types_1.isInstantiableClass)(baseTypeResult.type.boundToType) &&
5291
- !baseTypeResult.type.boundToType.includeSubclasses) {
5292
- if (types_1.FunctionType.isAbstractMethod(baseTypeResult.type)) {
5293
- if (types_1.FunctionType.isStaticMethod(baseTypeResult.type) ||
5294
- types_1.FunctionType.isClassMethod(baseTypeResult.type)) {
5295
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.abstractMethodInvocation().format({
5296
- method: baseTypeResult.type.details.name,
5297
- }), node.leftExpression);
5298
- }
5299
- }
5300
- }
5301
5393
  const callResult = validateCallArguments(node, argList, baseTypeResult,
5302
5394
  /* typeVarContext */ undefined,
5303
5395
  /* skipUnknownArgCheck */ false, inferenceContext);
@@ -5736,7 +5828,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5736
5828
  // If there were multiple possible matches, evaluate the type as
5737
5829
  // Unknown, but include the "possible types" to allow for completion
5738
5830
  // suggestions.
5739
- if (!isDefinitiveMatchFound) {
5831
+ if (!isDefinitiveMatchFound && possibleMatchResults.length > 0) {
5740
5832
  possibleMatchResults = filterOverloadMatchesForAnyArgs(possibleMatchResults);
5741
5833
  // Did the filtering produce a single result? If so, we're done.
5742
5834
  if (possibleMatchResults.length === 1) {
@@ -5944,24 +6036,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5944
6036
  }
5945
6037
  return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
5946
6038
  }
5947
- // Create a helper function that evaluates the overload that matches
5948
- // the arg/param lists.
5949
- function evaluateUsingLastMatchingOverload(skipUnknownArgCheck) {
5950
- // Find the match with the largest overload index (i.e. the last overload
5951
- // that was in the overload list).
5952
- const lastMatch = filteredMatchResults.reduce((previous, current) => {
5953
- 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;
5954
6050
  });
5955
6051
  const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
5956
- effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(lastMatch.overload));
6052
+ effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(bestMatch.overload));
5957
6053
  effectiveTypeVarContext.unlock();
5958
- return validateFunctionArgumentTypesWithContext(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
6054
+ return validateFunctionArgumentTypesWithContext(errorNode, bestMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
5959
6055
  }
5960
6056
  // If there is only one possible arg/param match among the overloads,
5961
6057
  // use the normal type matching mechanism because it is faster and
5962
6058
  // will provide a clearer error message.
5963
6059
  if (filteredMatchResults.length === 1) {
5964
- return evaluateUsingLastMatchingOverload(/* skipUnknownArgCheck */ false);
6060
+ return evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ false);
5965
6061
  }
5966
6062
  let expandedArgTypes = [argList.map((arg) => undefined)];
5967
6063
  let isTypeIncomplete = !!typeResult.isIncomplete;
@@ -6004,7 +6100,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6004
6100
  // in speculative mode because it's very expensive, and we're going to
6005
6101
  // suppress the diagnostic anyway.
6006
6102
  if (!isDiagnosticSuppressedForNode(errorNode) && !isTypeIncomplete) {
6007
- const result = evaluateUsingLastMatchingOverload(/* skipUnknownArgCheck */ true);
6103
+ const result = evaluateUsingBestMatchingOverload(/* skipUnknownArgCheck */ true);
6008
6104
  // Replace the result with an unknown type since we don't know
6009
6105
  // what overload should have been used.
6010
6106
  result.returnType = types_1.UnknownType.create();
@@ -6080,346 +6176,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6080
6176
  return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
6081
6177
  }
6082
6178
  let returnType = mapSubtypesExpandTypeVars(callTypeResult.type,
6083
- /* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype) => {
6084
- var _a, _b, _c, _d, _e, _f, _g;
6085
- switch (expandedSubtype.category) {
6086
- case 1 /* Unknown */:
6087
- case 2 /* Any */: {
6088
- // Touch all of the args so they're marked accessed. Don't bother
6089
- // doing this if the call type is incomplete because this will need
6090
- // to be done again once it is complete.
6091
- if (!callTypeResult.isIncomplete) {
6092
- argList.forEach((arg) => {
6093
- if (arg.valueExpression && !isSpeculativeModeInUse(arg.valueExpression)) {
6094
- getTypeOfArgument(arg);
6095
- }
6096
- });
6097
- }
6098
- return expandedSubtype;
6099
- }
6100
- case 5 /* Function */: {
6101
- if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
6102
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.callableNotInstantiable().format({
6103
- type: printType(expandedSubtype),
6104
- }), errorNode);
6105
- argumentErrors = true;
6106
- return undefined;
6107
- }
6108
- // The stdlib collections/__init__.pyi stub file defines namedtuple
6109
- // as a function rather than a class, so we need to check for it here.
6110
- if (expandedSubtype.details.builtInName === 'namedtuple') {
6111
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
6112
- return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
6113
- /* includesTypes */ false);
6114
- }
6115
- // Handle the NewType specially, replacing the normal return type.
6116
- if (expandedSubtype.details.builtInName === 'NewType') {
6117
- return createNewType(errorNode, argList);
6118
- }
6119
- let effectiveTypeVarContext = typeVarContext;
6120
- if (!effectiveTypeVarContext) {
6121
- // If a typeVarContext wasn't provided by the caller, allocate one here.
6122
- effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedSubtype));
6123
- // There are certain cases, such as with super().__new__(cls) calls where
6124
- // the call is a constructor but the proper TypeVar scope has been lost.
6125
- // We'll add a wildcard TypeVar scope here. This is a bit of a hack and
6126
- // we may need to revisit this in the future.
6127
- if (types_1.FunctionType.isConstructorMethod(expandedSubtype)) {
6128
- effectiveTypeVarContext.addSolveForScope(types_1.WildcardTypeVarScopeId);
6129
- }
6130
- }
6131
- const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
6132
- if (functionResult.isTypeIncomplete) {
6133
- isTypeIncomplete = true;
6134
- }
6135
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
6136
- if (functionResult.argumentErrors) {
6137
- argumentErrors = true;
6138
- }
6139
- else {
6140
- specializedInitSelfType = functionResult.specializedInitSelfType;
6141
- // Call the function transform logic to handle special-cased functions.
6142
- const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
6143
- argumentErrors: functionResult.argumentErrors,
6144
- returnType: (_a = functionResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(isTypeIncomplete),
6145
- isTypeIncomplete,
6146
- });
6147
- functionResult.returnType = transformed.returnType;
6148
- if (transformed.isTypeIncomplete) {
6149
- isTypeIncomplete = true;
6150
- }
6151
- if (transformed.argumentErrors) {
6152
- argumentErrors = true;
6153
- }
6154
- }
6155
- if (expandedSubtype.details.builtInName === '__import__') {
6156
- // For the special __import__ type, we'll override the return type to be "Any".
6157
- // This is required because we don't know what module was imported, and we don't
6158
- // want to fail type checks when accessing members of the resulting module type.
6159
- return types_1.AnyType.create();
6160
- }
6161
- return functionResult.returnType;
6162
- }
6163
- case 6 /* OverloadedFunction */: {
6164
- // Handle the 'cast' call as a special case.
6165
- if (expandedSubtype.overloads[0].details.builtInName === 'cast' && argList.length === 2) {
6166
- // Verify that the cast is necessary.
6167
- const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
6168
- const castFromType = getTypeOfArgument(argList[1]).type;
6169
- if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
6170
- if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
6171
- ignorePseudoGeneric: true,
6172
- })) {
6173
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUnnecessaryCast, diagnosticRules_1.DiagnosticRule.reportUnnecessaryCast, localize_1.Localizer.Diagnostic.unnecessaryCast().format({
6174
- type: printType(castFromType),
6175
- }), errorNode);
6176
- }
6177
- }
6178
- return (0, typeUtils_1.convertToInstance)(castToType);
6179
- }
6180
- const functionResult = validateOverloadedFunctionArguments(errorNode, argList, { type: expandedSubtype, isIncomplete: callTypeResult.isIncomplete }, typeVarContext, skipUnknownArgCheck, inferenceContext);
6181
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
6182
- if (functionResult.isTypeIncomplete) {
6183
- isTypeIncomplete = true;
6184
- }
6185
- if (functionResult.argumentErrors) {
6186
- argumentErrors = true;
6187
- }
6188
- else {
6189
- specializedInitSelfType = functionResult.specializedInitSelfType;
6190
- // Call the function transform logic to handle special-cased functions.
6191
- const transformed = (0, functionTransform_1.applyFunctionTransform)(evaluatorInterface, errorNode, argList, expandedSubtype, {
6192
- argumentErrors: functionResult.argumentErrors,
6193
- returnType: (_b = functionResult.returnType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(isTypeIncomplete),
6194
- isTypeIncomplete,
6195
- });
6196
- functionResult.returnType = transformed.returnType;
6197
- if (transformed.isTypeIncomplete) {
6198
- isTypeIncomplete = true;
6199
- }
6200
- if (transformed.argumentErrors) {
6201
- argumentErrors = true;
6202
- }
6203
- }
6204
- return (_c = functionResult.returnType) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
6205
- }
6206
- case 7 /* Class */: {
6207
- if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
6208
- if (expandedSubtype.literalValue !== undefined) {
6209
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.literalNotCallable(), errorNode);
6210
- argumentErrors = true;
6211
- return types_1.UnknownType.create();
6212
- }
6213
- if (types_1.ClassType.isBuiltIn(expandedSubtype)) {
6214
- const className = expandedSubtype.aliasName || expandedSubtype.details.name;
6215
- if (className === 'type') {
6216
- // Validate the constructor arguments.
6217
- (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6218
- // Handle the 'type' call specially.
6219
- if (argList.length === 1) {
6220
- // The one-parameter form of "type" returns the class
6221
- // for the specified object.
6222
- const argType = getTypeOfArgument(argList[0]).type;
6223
- return (0, typeUtils_1.mapSubtypes)(argType, (subtype) => {
6224
- if ((0, types_1.isClassInstance)(subtype) ||
6225
- ((0, types_1.isTypeVar)(subtype) && types_1.TypeBase.isInstance(subtype)) ||
6226
- (0, types_1.isNoneInstance)(subtype)) {
6227
- return (0, typeUtils_1.convertToInstantiable)(stripLiteralValue(subtype));
6228
- }
6229
- else if ((0, types_1.isFunction)(subtype) && types_1.TypeBase.isInstance(subtype)) {
6230
- return types_1.FunctionType.cloneAsInstantiable(subtype);
6231
- }
6232
- return types_1.AnyType.create();
6233
- });
6234
- }
6235
- else if (argList.length >= 2) {
6236
- // The two-parameter form of "type" returns a new class type
6237
- // built from the specified base types.
6238
- return createType(errorNode, argList) || types_1.AnyType.create();
6239
- }
6240
- // If the parameter to type() is not statically known,
6241
- // fall back to Any.
6242
- return types_1.AnyType.create();
6243
- }
6244
- if (className === 'TypeVar') {
6245
- return createTypeVarType(errorNode, expandedSubtype, argList);
6246
- }
6247
- if (className === 'TypeVarTuple') {
6248
- return createTypeVarTupleType(errorNode, expandedSubtype, argList);
6249
- }
6250
- if (className === 'ParamSpec') {
6251
- return createParamSpecType(errorNode, expandedSubtype, argList);
6252
- }
6253
- if (className === 'TypeAliasType') {
6254
- const newTypeAlias = createTypeAliasType(errorNode, argList);
6255
- if (newTypeAlias) {
6256
- return newTypeAlias;
6257
- }
6258
- }
6259
- if (className === 'NamedTuple') {
6260
- return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
6261
- /* includesTypes */ true);
6262
- }
6263
- if (className === 'NewType') {
6264
- return createNewType(errorNode, argList);
6265
- }
6266
- if (className === 'Protocol' ||
6267
- className === 'Generic' ||
6268
- className === 'Callable' ||
6269
- className === 'Concatenate' ||
6270
- className === 'Type') {
6271
- const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
6272
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotIntantiable().format({ type: className }), errorNode);
6273
- return types_1.AnyType.create();
6274
- }
6275
- if ((0, types_1.isClass)(unexpandedSubtype) && (0, enums_1.isKnownEnumType)(className)) {
6276
- return ((_d = (0, enums_1.createEnumType)(evaluatorInterface, errorNode, expandedSubtype, argList)) !== null && _d !== void 0 ? _d : types_1.UnknownType.create());
6277
- }
6278
- if (className === 'TypedDict') {
6279
- return (0, typedDicts_1.createTypedDictType)(evaluatorInterface, errorNode, expandedSubtype, argList);
6280
- }
6281
- if (className === 'auto' && argList.length === 0) {
6282
- return (0, enums_1.getEnumAutoValueType)(evaluatorInterface, errorNode);
6283
- }
6284
- }
6285
- if (types_1.ClassType.supportsAbstractMethods(expandedSubtype)) {
6286
- const abstractMethods = getAbstractMethods(expandedSubtype);
6287
- if (abstractMethods.length > 0 &&
6288
- !expandedSubtype.includeSubclasses &&
6289
- !(0, types_1.isTypeVar)(unexpandedSubtype)) {
6290
- // If the class is abstract, it can't be instantiated.
6291
- const diagAddendum = new diagnostic_1.DiagnosticAddendum();
6292
- const errorsToDisplay = 2;
6293
- abstractMethods.forEach((abstractMethod, index) => {
6294
- if (index === errorsToDisplay) {
6295
- diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstractMore().format({
6296
- count: abstractMethods.length - errorsToDisplay,
6297
- }));
6298
- }
6299
- else if (index < errorsToDisplay) {
6300
- if ((0, types_1.isInstantiableClass)(abstractMethod.classType)) {
6301
- const className = abstractMethod.classType.details.name;
6302
- diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsAbstract().format({
6303
- type: className,
6304
- name: abstractMethod.symbolName,
6305
- }));
6306
- }
6307
- }
6308
- });
6309
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
6310
- .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateAbstract().format({
6311
- type: expandedSubtype.details.name,
6312
- }) + diagAddendum.getString(), errorNode);
6313
- }
6314
- }
6315
- if (types_1.ClassType.isProtocolClass(expandedSubtype) && !expandedSubtype.includeSubclasses) {
6316
- // If the class is a protocol, it can't be instantiated.
6317
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.instantiateProtocol().format({
6318
- type: expandedSubtype.details.name,
6319
- }), errorNode);
6320
- }
6321
- // Assume this is a call to the constructor.
6322
- const constructorResult = (0, constructors_1.validateConstructorArguments)(evaluatorInterface, errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
6323
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, constructorResult.overloadsUsedForCall);
6324
- if (constructorResult.argumentErrors) {
6325
- argumentErrors = true;
6326
- }
6327
- if (constructorResult.isTypeIncomplete) {
6328
- isTypeIncomplete = true;
6329
- }
6330
- let returnType = constructorResult.returnType;
6331
- // If the expandedSubtype originated from a TypeVar, convert
6332
- // the constructed type back to the TypeVar. For example, if
6333
- // we have `cls: Type[_T]` followed by `_T()`.
6334
- if ((0, types_1.isTypeVar)(unexpandedSubtype)) {
6335
- returnType = (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
6336
- }
6337
- // If we instantiated a type, transform it into a class.
6338
- // This can happen if someone directly instantiates a metaclass
6339
- // deriving from type.
6340
- if (returnType &&
6341
- (0, types_1.isClassInstance)(returnType) &&
6342
- returnType.details.mro.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, 'type'))) {
6343
- let newClassName = '__class_' + returnType.details.name;
6344
- if (argList.length === 3) {
6345
- const firstArgType = getTypeOfArgument(argList[0]).type;
6346
- if ((0, types_1.isClassInstance)(firstArgType) &&
6347
- types_1.ClassType.isBuiltIn(firstArgType, 'str') &&
6348
- typeof firstArgType.literalValue === 'string') {
6349
- newClassName = firstArgType.literalValue;
6350
- }
6351
- }
6352
- 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));
6353
- newClassType.details.baseClasses.push(getBuiltInType(errorNode, 'object'));
6354
- newClassType.details.effectiveMetaclass = expandedSubtype;
6355
- (0, typeUtils_1.computeMroLinearization)(newClassType);
6356
- return newClassType;
6357
- }
6358
- return returnType;
6359
- }
6360
- else {
6361
- const memberType = (_e = getTypeOfObjectMember(errorNode, expandedSubtype, '__call__',
6362
- /* usage */ undefined,
6363
- /* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _e === void 0 ? void 0 : _e.type;
6364
- if (memberType) {
6365
- const functionResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6366
- (0, collectionUtils_1.appendArray)(overloadsUsedForCall, functionResult.overloadsUsedForCall);
6367
- if (functionResult.argumentErrors) {
6368
- argumentErrors = true;
6369
- }
6370
- if ((0, types_1.isTypeVar)(unexpandedSubtype) &&
6371
- types_1.TypeBase.isInstantiable(unexpandedSubtype) &&
6372
- (0, types_1.isClass)(expandedSubtype) &&
6373
- types_1.ClassType.isBuiltIn(expandedSubtype, 'type')) {
6374
- // Handle the case where a Type[T] is being called. We presume this
6375
- // will instantiate an object of type T.
6376
- return (0, typeUtils_1.convertToInstance)(unexpandedSubtype);
6377
- }
6378
- return (_f = functionResult.returnType) !== null && _f !== void 0 ? _f : types_1.UnknownType.create();
6379
- }
6380
- if (!memberType || !(0, types_1.isAnyOrUnknown)(memberType)) {
6381
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
6382
- type: printType(expandedSubtype),
6383
- }), errorNode);
6384
- }
6385
- return types_1.UnknownType.create();
6386
- }
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;
6387
6184
  }
6388
- case 3 /* None */: {
6389
- if (types_1.TypeBase.isInstantiable(expandedSubtype)) {
6390
- if (noneType && (0, types_1.isInstantiableClass)(noneType)) {
6391
- const functionResult = validateCallArguments(errorNode, argList, { type: noneType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6392
- if (functionResult.isTypeIncomplete) {
6393
- isTypeIncomplete = true;
6394
- }
6395
- if (functionResult.argumentErrors) {
6396
- argumentErrors = true;
6397
- }
6398
- }
6399
- return types_1.NoneType.createInstance();
6400
- }
6401
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportOptionalCall, diagnosticRules_1.DiagnosticRule.reportOptionalCall, localize_1.Localizer.Diagnostic.noneNotCallable(), errorNode);
6402
- return undefined;
6185
+ if (callResult.isTypeIncomplete) {
6186
+ isTypeIncomplete = true;
6403
6187
  }
6404
- // TypeVars should have been expanded in most cases,
6405
- // but we still need to handle the case of Type[T] where
6406
- // T is a constrained type that contains a union. We also
6407
- // need to handle recursive type aliases.
6408
- case 10 /* TypeVar */: {
6409
- expandedSubtype = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedSubtype);
6410
- const callResult = validateCallArguments(errorNode, argList, { type: expandedSubtype }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
6188
+ if (callResult.overloadsUsedForCall) {
6411
6189
  (0, collectionUtils_1.appendArray)(overloadsUsedForCall, callResult.overloadsUsedForCall);
6412
- if (callResult.argumentErrors) {
6413
- argumentErrors = true;
6414
- }
6415
- return (_g = callResult.returnType) !== null && _g !== void 0 ? _g : types_1.UnknownType.create();
6416
6190
  }
6417
- case 8 /* Module */: {
6418
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.moduleNotCallable(), errorNode);
6419
- return undefined;
6420
- }
6421
- }
6422
- return undefined;
6191
+ specializedInitSelfType = callResult.specializedInitSelfType;
6192
+ return callResult.returnType;
6193
+ }, {
6194
+ allowDiagnostics: true,
6195
+ });
6423
6196
  });
6424
6197
  // If we ended up with a "Never" type because all code paths returned
6425
6198
  // undefined due to argument errors, transform the result into an Unknown
@@ -6435,6 +6208,362 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6435
6208
  overloadsUsedForCall,
6436
6209
  };
6437
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
+ }
6551
+ // Evaluates the type of the "cast" call.
6552
+ function evaluateCastCall(argList, errorNode) {
6553
+ // Verify that the cast is necessary.
6554
+ const castToType = getTypeOfArgumentExpectingType(argList[0], { enforceTypeAnnotationRules: true }).type;
6555
+ const castFromType = getTypeOfArgument(argList[1]).type;
6556
+ if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
6557
+ if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
6558
+ ignorePseudoGeneric: true,
6559
+ })) {
6560
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUnnecessaryCast, diagnosticRules_1.DiagnosticRule.reportUnnecessaryCast, localize_1.Localizer.Diagnostic.unnecessaryCast().format({
6561
+ type: printType(castFromType),
6562
+ }), errorNode);
6563
+ }
6564
+ }
6565
+ return (0, typeUtils_1.convertToInstance)(castToType);
6566
+ }
6438
6567
  // Expands any unpacked tuples within an argument list.
6439
6568
  function expandArgList(argList) {
6440
6569
  var _a;
@@ -6530,8 +6659,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6530
6659
  // Does this function define the param spec, or is it an inner
6531
6660
  // function nested within another function that defines the param
6532
6661
  // spec? We need to handle these two cases differently.
6533
- if (varArgListParam.type.scopeId === typeResult.type.details.typeVarScopeId ||
6534
- varArgListParam.type.scopeId === typeResult.type.details.constructorTypeVarScopeId) {
6662
+ const paramSpecScopeId = varArgListParam.type.scopeId;
6663
+ if (paramSpecScopeId === typeResult.type.details.typeVarScopeId ||
6664
+ paramSpecScopeId === typeResult.type.details.constructorTypeVarScopeId) {
6535
6665
  paramSpecArgList = [];
6536
6666
  paramSpecTarget = types_1.TypeVarType.cloneForParamSpecAccess(varArgListParam.type, /* access */ undefined);
6537
6667
  }
@@ -6540,6 +6670,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6540
6670
  }
6541
6671
  }
6542
6672
  }
6673
+ else if (typeResult.type.details.paramSpec) {
6674
+ const paramSpecScopeId = typeResult.type.details.paramSpec.scopeId;
6675
+ if (paramSpecScopeId === typeResult.type.details.typeVarScopeId ||
6676
+ paramSpecScopeId === typeResult.type.details.constructorTypeVarScopeId) {
6677
+ hasParamSpecArgsKwargs = true;
6678
+ paramSpecArgList = [];
6679
+ paramSpecTarget = types_1.TypeVarType.cloneForParamSpecAccess(typeResult.type.details.paramSpec,
6680
+ /* access */ undefined);
6681
+ }
6682
+ }
6543
6683
  // If there are keyword arguments present after a *args argument,
6544
6684
  // the keyword arguments may target one or more parameters that are positional.
6545
6685
  // In this case, we will limit the number of positional parameters so the
@@ -7028,27 +7168,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7028
7168
  trySetActive(argList[argIndex], paramDetails.params[paramInfoIndex].param);
7029
7169
  }
7030
7170
  }
7171
+ else if (paramSpecArgList) {
7172
+ paramSpecArgList.push(argList[argIndex]);
7173
+ }
7031
7174
  else if (paramDetails.kwargsIndex !== undefined) {
7032
- if (paramSpecArgList) {
7033
- paramSpecArgList.push(argList[argIndex]);
7034
- }
7035
- else {
7036
- const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
7037
- validateArgTypeParams.push({
7038
- paramCategory: 2 /* KwargsDict */,
7039
- paramType,
7040
- requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7041
- argument: argList[argIndex],
7042
- errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
7043
- paramName: paramNameValue,
7044
- });
7045
- // Remember that this parameter has already received a value.
7046
- paramMap.set(paramNameValue, {
7047
- argsNeeded: 1,
7048
- argsReceived: 1,
7049
- isPositionalOnly: false,
7050
- });
7051
- }
7175
+ const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
7176
+ validateArgTypeParams.push({
7177
+ paramCategory: 2 /* KwargsDict */,
7178
+ paramType,
7179
+ requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
7180
+ argument: argList[argIndex],
7181
+ errorNode: (_h = argList[argIndex].valueExpression) !== null && _h !== void 0 ? _h : errorNode,
7182
+ paramName: paramNameValue,
7183
+ });
7184
+ // Remember that this parameter has already received a value.
7185
+ paramMap.set(paramNameValue, {
7186
+ argsNeeded: 1,
7187
+ argsReceived: 1,
7188
+ isPositionalOnly: false,
7189
+ });
7052
7190
  (0, debug_1.assert)(paramDetails.params[paramDetails.kwargsIndex], 'paramDetails.kwargsIndex params entry is undefined');
7053
7191
  trySetActive(argList[argIndex], paramDetails.params[paramDetails.kwargsIndex].param);
7054
7192
  }
@@ -7058,15 +7196,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7058
7196
  }
7059
7197
  }
7060
7198
  else if (argList[argIndex].argumentCategory === 0 /* Simple */) {
7061
- if (!isDiagnosticSuppressedForNode(errorNode)) {
7062
- const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
7063
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, positionParamLimitIndex === 1
7064
- ? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
7065
- : localize_1.Localizer.Diagnostic.argPositionalExpectedCount().format({
7066
- expected: positionParamLimitIndex,
7067
- }), argList[argIndex].valueExpression || errorNode);
7199
+ if (paramSpecArgList) {
7200
+ paramSpecArgList.push(argList[argIndex]);
7201
+ }
7202
+ else {
7203
+ if (!isDiagnosticSuppressedForNode(errorNode)) {
7204
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(errorNode);
7205
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, positionParamLimitIndex === 1
7206
+ ? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
7207
+ : localize_1.Localizer.Diagnostic.argPositionalExpectedCount().format({
7208
+ expected: positionParamLimitIndex,
7209
+ }), argList[argIndex].valueExpression || errorNode);
7210
+ }
7211
+ reportedArgError = true;
7068
7212
  }
7069
- reportedArgError = true;
7070
7213
  }
7071
7214
  else if (argList[argIndex].argumentCategory === 1 /* UnpackedList */) {
7072
7215
  // Handle the case where a *args: P.args is passed as an argument to
@@ -7270,6 +7413,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7270
7413
  paramSpecArgList,
7271
7414
  activeParam,
7272
7415
  relevance,
7416
+ argumentMatchScore: 0,
7273
7417
  };
7274
7418
  }
7275
7419
  // After having matched arguments with parameters, this function evaluates the
@@ -7345,7 +7489,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7345
7489
  const genericReturnType = types_1.ClassType.cloneForSpecialization(effectiveReturnType,
7346
7490
  /* typeArguments */ undefined,
7347
7491
  /* isTypeArgumentExplicit */ false);
7348
- effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext);
7492
+ effectiveExpectedType = (0, typeUtils_1.applySolvedTypeVars)(genericReturnType, tempTypeVarContext, {
7493
+ unknownIfNotFound: true,
7494
+ });
7349
7495
  }
7350
7496
  }
7351
7497
  else if ((0, types_1.isFunction)(effectiveReturnType)) {
@@ -7368,6 +7514,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7368
7514
  const type = matchResults.overload;
7369
7515
  let isTypeIncomplete = matchResults.isTypeIncomplete;
7370
7516
  let argumentErrors = false;
7517
+ let argumentMatchScore = 0;
7371
7518
  let specializedInitSelfType;
7372
7519
  let anyOrUnknownArgument;
7373
7520
  const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
@@ -7469,7 +7616,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7469
7616
  let sawParamSpecKwargs = false;
7470
7617
  let condition = [];
7471
7618
  const argResults = [];
7472
- matchResults.argParams.forEach((argParam) => {
7619
+ matchResults.argParams.forEach((argParam, argParamIndex) => {
7473
7620
  var _a;
7474
7621
  const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
7475
7622
  skipUnknownArgCheck,
@@ -7478,6 +7625,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7478
7625
  argResults.push(argResult);
7479
7626
  if (!argResult.isCompatible) {
7480
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);
7481
7632
  }
7482
7633
  if (argResult.isTypeIncomplete) {
7483
7634
  isTypeIncomplete = true;
@@ -7507,6 +7658,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7507
7658
  if (matchResults.paramSpecArgList && matchResults.paramSpecTarget) {
7508
7659
  if (!validateFunctionArgumentsForParamSpec(errorNode, matchResults.paramSpecArgList, matchResults.paramSpecTarget, typeVarContext, typeCondition)) {
7509
7660
  argumentErrors = true;
7661
+ argumentMatchScore += 1;
7510
7662
  }
7511
7663
  }
7512
7664
  else if (type.details.paramSpec) {
@@ -7515,6 +7667,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7515
7667
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramSpecArgsMissing().format({ type: printType(type.details.paramSpec) }), errorNode);
7516
7668
  }
7517
7669
  argumentErrors = true;
7670
+ argumentMatchScore += 1;
7518
7671
  }
7519
7672
  }
7520
7673
  // Calculate the return type.
@@ -7596,6 +7749,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7596
7749
  if (specializedInitSelfType) {
7597
7750
  specializedInitSelfType = (0, typeUtils_1.applySolvedTypeVars)(specializedInitSelfType, typeVarContext);
7598
7751
  }
7752
+ matchResults.argumentMatchScore = argumentMatchScore;
7599
7753
  return {
7600
7754
  argumentErrors,
7601
7755
  argResults,
@@ -7640,7 +7794,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7640
7794
  // specific use case. We may need to make this more sophisticated in
7641
7795
  // the future.
7642
7796
  if ((0, types_1.isFunction)(returnType) && !returnType.details.name) {
7643
- 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
+ }
7644
7804
  }
7645
7805
  return returnType;
7646
7806
  }
@@ -7700,7 +7860,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7700
7860
  return false;
7701
7861
  }
7702
7862
  const liveTypeVarScopes = ParseTreeUtils.getTypeVarScopesForNode(errorNode);
7703
- const srcTypeVarContext = new typeVarContext_1.TypeVarContext(paramSpecType.details.typeVarScopeId);
7863
+ const srcTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(paramSpecType));
7704
7864
  let reportedArgError = false;
7705
7865
  // Build a map of all named parameters.
7706
7866
  const paramMap = new Map();
@@ -8663,7 +8823,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8663
8823
  }
8664
8824
  return returnType;
8665
8825
  }
8666
- function getTypeOfDictionary(node, inferenceContext) {
8826
+ function getTypeOfDictionary(node, flags, inferenceContext) {
8827
+ var _a;
8828
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
8829
+ ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 1 /* Argument */) {
8830
+ const diag = new diagnostic_1.DiagnosticAddendum();
8831
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useDictInstead());
8832
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dictInAnnotation() + diag.getString(), node);
8833
+ }
8667
8834
  // If the expected type is a union, analyze for each of the subtypes
8668
8835
  // to find one that matches.
8669
8836
  let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
@@ -8751,9 +8918,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8751
8918
  // Dict and MutableMapping types have invariant value types, so they
8752
8919
  // cannot be narrowed further. Other super-types like Mapping, Collection,
8753
8920
  // and Iterable use covariant value types, so they can be narrowed.
8754
- const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
8755
- (types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
8756
- 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
+ }
8757
8930
  // Infer the key and value types if possible.
8758
8931
  if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
8759
8932
  /* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
@@ -8823,7 +8996,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8823
8996
  let isIncomplete = false;
8824
8997
  // Infer the key and value types if possible.
8825
8998
  node.entries.forEach((entryNode, index) => {
8826
- var _a, _b, _c;
8999
+ var _a;
8827
9000
  let addUnknown = true;
8828
9001
  if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
8829
9002
  const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
@@ -8857,8 +9030,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8857
9030
  /* flags */ undefined, entryInferenceContext);
8858
9031
  }
8859
9032
  if (entryInferenceContext && !valueTypeResult.typeErrors) {
8860
- valueTypeResult.type =
8861
- (_a = inferTypeArgFromExpectedEntryType(entryInferenceContext, [valueTypeResult.type], !isValueTypeInvariant)) !== null && _a !== void 0 ? _a : valueTypeResult.type;
9033
+ const fromExpectedType = inferTypeArgFromExpectedEntryType(entryInferenceContext, [valueTypeResult.type], !isValueTypeInvariant);
9034
+ if (fromExpectedType) {
9035
+ valueTypeResult = { ...valueTypeResult, type: fromExpectedType };
9036
+ }
8862
9037
  }
8863
9038
  if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
8864
9039
  expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
@@ -8882,11 +9057,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8882
9057
  }
8883
9058
  }
8884
9059
  const entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(expectedType);
8885
- const unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
9060
+ let unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
8886
9061
  /* flags */ undefined, entryInferenceContext);
8887
9062
  if (entryInferenceContext && !unexpandedTypeResult.typeErrors) {
8888
- unexpandedTypeResult.type =
8889
- (_b = inferTypeArgFromExpectedEntryType(entryInferenceContext, [unexpandedTypeResult.type], !isValueTypeInvariant)) !== null && _b !== void 0 ? _b : unexpandedTypeResult.type;
9063
+ const fromExpectedType = inferTypeArgFromExpectedEntryType(entryInferenceContext, [unexpandedTypeResult.type], !isValueTypeInvariant);
9064
+ if (fromExpectedType) {
9065
+ unexpandedTypeResult = { ...unexpandedTypeResult, type: fromExpectedType };
9066
+ }
8890
9067
  }
8891
9068
  if (unexpandedTypeResult.isIncomplete) {
8892
9069
  isIncomplete = true;
@@ -8942,7 +9119,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8942
9119
  }
8943
9120
  // The result should be a tuple.
8944
9121
  if ((0, types_1.isClassInstance)(dictEntryType) && (0, typeUtils_1.isTupleClass)(dictEntryType)) {
8945
- const typeArgs = (_c = dictEntryType.tupleTypeArguments) === null || _c === void 0 ? void 0 : _c.map((t) => t.type);
9122
+ const typeArgs = (_a = dictEntryType.tupleTypeArguments) === null || _a === void 0 ? void 0 : _a.map((t) => t.type);
8946
9123
  if (typeArgs && typeArgs.length === 2) {
8947
9124
  if (forceStrictInference || index < maxEntriesToUseForInference) {
8948
9125
  keyTypes.push({ node: entryNode, type: typeArgs[0] });
@@ -8961,7 +9138,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
8961
9138
  });
8962
9139
  return isIncomplete;
8963
9140
  }
8964
- function getTypeOfListOrSet(node, inferenceContext) {
9141
+ function getTypeOfListOrSet(node, flags, inferenceContext) {
9142
+ var _a;
9143
+ if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0 &&
9144
+ node.nodeType === 31 /* List */ &&
9145
+ ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 1 /* Argument */) {
9146
+ const diag = new diagnostic_1.DiagnosticAddendum();
9147
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.useListInstead());
9148
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.listInAnnotation() + diag.getString(), node);
9149
+ }
8965
9150
  // If the expected type is a union, recursively call for each of the subtypes
8966
9151
  // to find one that matches.
8967
9152
  let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
@@ -9339,7 +9524,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9339
9524
  if (returnTypeResult.isIncomplete) {
9340
9525
  isIncomplete = true;
9341
9526
  }
9342
- }, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType);
9527
+ }, {
9528
+ dependentType: inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType,
9529
+ });
9343
9530
  // Mark the function type as no longer being evaluated.
9344
9531
  functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
9345
9532
  return { type: functionType, isIncomplete };
@@ -9565,13 +9752,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9565
9752
  }
9566
9753
  return true;
9567
9754
  }
9568
- // Converts the type parameters for a Callable type. It should
9569
- // have zero to two parameters. The first parameter, if present, should be
9570
- // either an ellipsis or a list of parameter types. The second parameter, if
9571
- // 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.
9572
9759
  function createCallableType(typeArgs, errorNode) {
9573
- // Create a new function that is marked as "static" so there is later
9574
- // no attempt to bind it as though it's an instance or class method.
9575
9760
  const functionType = types_1.FunctionType.createInstantiable(0 /* None */);
9576
9761
  types_1.TypeBase.setSpecialForm(functionType);
9577
9762
  functionType.details.declaredReturnType = types_1.UnknownType.create();
@@ -10265,12 +10450,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10265
10450
  // Determine if there are any generic type parameters associated
10266
10451
  // with this type alias.
10267
10452
  typeParameters = [];
10268
- // Skip this for a simple TypeVar (one that's not part of a union).
10269
- if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
10270
- (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10271
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10272
- });
10273
- }
10453
+ (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
10454
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
10455
+ });
10274
10456
  // Don't include any synthesized type variables.
10275
10457
  typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
10276
10458
  }
@@ -10804,10 +10986,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10804
10986
  // If the base class is partially evaluated, install a callback
10805
10987
  // so we can fix up this class (e.g. compute the MRO) when the
10806
10988
  // dependent class is completed.
10807
- classTypeHooks.push({
10808
- dependency: argType,
10809
- callback: () => completeClassTypeDeferred(classType, node, node.name),
10810
- });
10989
+ registerDeferredClassCompletion(node, argType);
10811
10990
  }
10812
10991
  if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
10813
10992
  if (!fileInfo.isStubFile &&
@@ -11123,8 +11302,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11123
11302
  (0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
11124
11303
  (0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
11125
11304
  }
11126
- // Run any class hooks that depend on this class.
11127
- 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);
11128
11311
  // Synthesize TypedDict methods.
11129
11312
  if (types_1.ClassType.isTypedDictClass(classType)) {
11130
11313
  (0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
@@ -11357,21 +11540,47 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11357
11540
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarsNotInGenericOrProtocol() + diag.getString(), errorNode);
11358
11541
  }
11359
11542
  }
11360
- // Runs any registered "callback hooks" that depend on the specified class type.
11361
- // This allows us to complete any work that requires dependent classes to be
11362
- // completed.
11363
- function runClassTypeHooks(type) {
11364
- classTypeHooks.forEach((hook) => {
11365
- if (types_1.ClassType.isSameGenericClass(hook.dependency, type)) {
11366
- 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
+ });
11367
11576
  }
11368
11577
  });
11369
- // Remove any hooks that depend on this type.
11370
- 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));
11371
11580
  }
11372
11581
  // Recomputes the MRO and effective metaclass for the class after dependent
11373
11582
  // classes have been fully constructed.
11374
- function completeClassTypeDeferred(type, node, errorNode) {
11583
+ function completeClassTypeDeferred(type, errorNode) {
11375
11584
  // Recompute the MRO linearization.
11376
11585
  if (!(0, typeUtils_1.computeMroLinearization)(type)) {
11377
11586
  addError(localize_1.Localizer.Diagnostic.methodOrdering(), errorNode);
@@ -12039,6 +12248,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12039
12248
  }
12040
12249
  // Note that the inferred type, once lazily computed, needs to wrap the
12041
12250
  // resulting type in an awaitable.
12251
+ functionType.details.flags |= 1024 /* WrapReturnTypeInAwait */;
12042
12252
  awaitableFunctionType.details.flags |= 1024 /* WrapReturnTypeInAwait */;
12043
12253
  return awaitableFunctionType;
12044
12254
  }
@@ -12525,18 +12735,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12525
12735
  /* isPositiveTest */ false);
12526
12736
  }
12527
12737
  }
12528
- // Determine if the pre-narrowed subject type contains an object.
12529
- let subjectIsObject = false;
12530
- (0, typeUtils_1.doForEachSubtype)(makeTopLevelTypeVarsConcrete(subjectType), (subtype) => {
12531
- if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, 'object')) {
12532
- subjectIsObject = true;
12533
- }
12534
- });
12535
- // Apply positive narrowing for the current case statement.
12536
- subjectType = (0, patternMatching_1.narrowTypeBasedOnPattern)(evaluatorInterface, subjectType, node.pattern,
12537
- /* isPositiveTest */ true);
12538
- (0, patternMatching_1.assignTypeToPatternTargets)(evaluatorInterface, subjectType, !!subjectTypeResult.isIncomplete, subjectIsObject, node.pattern);
12539
- writeTypeCache(node, { type: subjectType, isIncomplete: !!subjectTypeResult.isIncomplete }, 0 /* None */);
12738
+ const narrowedSubjectType = (0, patternMatching_1.assignTypeToPatternTargets)(evaluatorInterface, subjectType, !!subjectTypeResult.isIncomplete, node.pattern);
12739
+ writeTypeCache(node, { type: narrowedSubjectType, isIncomplete: !!subjectTypeResult.isIncomplete }, 0 /* None */);
12540
12740
  }
12541
12741
  function evaluateTypesForImportFrom(node) {
12542
12742
  if (isTypeCached(node)) {
@@ -13205,10 +13405,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13205
13405
  // Handle "type" specially, since it needs to act like "Type"
13206
13406
  // in Python 3.9 and newer.
13207
13407
  if (types_1.ClassType.isBuiltIn(classType, 'type') && typeArgs) {
13208
- // PEP 484 says that type[Any] should be considered
13209
- // equivalent to type.
13210
- if (typeArgs.length === 1 && (0, types_1.isAnyOrUnknown)(typeArgs[0].type)) {
13211
- 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
+ }
13212
13419
  }
13213
13420
  const typeClass = getTypingType(errorNode, 'Type');
13214
13421
  if (typeClass && (0, types_1.isInstantiableClass)(typeClass)) {
@@ -13460,13 +13667,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13460
13667
  // used in cases where the argument is expected to be a type
13461
13668
  // and therefore follows the normal rules of types (e.g. they
13462
13669
  // can be forward-declared in stubs, etc.).
13463
- function getTypeOfArgumentExpectingType(arg) {
13670
+ function getTypeOfArgumentExpectingType(arg, options) {
13464
13671
  if (arg.typeResult) {
13465
13672
  return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
13466
13673
  }
13467
13674
  // If there was no defined type provided, there should always
13468
13675
  // be a value expression from which we can retrieve the type.
13469
- return getTypeOfExpressionExpectingType(arg.valueExpression);
13676
+ return getTypeOfExpressionExpectingType(arg.valueExpression, options);
13470
13677
  }
13471
13678
  function getTypeOfExpressionExpectingType(node, options) {
13472
13679
  let flags = 128 /* ExpectingInstantiableType */ |
@@ -13497,6 +13704,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13497
13704
  if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
13498
13705
  flags |= 32 /* DisallowParamSpec */;
13499
13706
  }
13707
+ if (options === null || options === void 0 ? void 0 : options.enforceTypeAnnotationRules) {
13708
+ flags |= 256 /* ExpectingTypeAnnotation */;
13709
+ }
13500
13710
  return getTypeOfExpression(node, flags);
13501
13711
  }
13502
13712
  function getBuiltInType(node, name) {
@@ -13627,11 +13837,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13627
13837
  // types, under the assumption that we're performing speculative evaluations.
13628
13838
  // If speculativeNode is undefined, speculative mode is not used. This is
13629
13839
  // useful in cases where we conditionally want to use speculative mode.
13630
- function useSpeculativeMode(speculativeNode, callback, dependentType) {
13840
+ function useSpeculativeMode(speculativeNode, callback, options) {
13631
13841
  if (!speculativeNode) {
13632
13842
  return callback();
13633
13843
  }
13634
- speculativeTypeTracker.enterSpeculativeContext(speculativeNode, dependentType);
13844
+ speculativeTypeTracker.enterSpeculativeContext(speculativeNode, options);
13635
13845
  try {
13636
13846
  const result = callback();
13637
13847
  speculativeTypeTracker.leaveSpeculativeContext();
@@ -14601,6 +14811,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14601
14811
  }
14602
14812
  let typedDecls = symbol.getTypedDeclarations();
14603
14813
  if (typedDecls.length === 0) {
14814
+ // If the symbol has no type declaration but is assigned many times,
14815
+ // treat it as though it has an explicit type annotation of "Unknown".
14816
+ // This will avoid a pathological performance condition for unannotated
14817
+ // code that reassigns the same variable hundreds of times. If the symbol
14818
+ // effectively has an "Any" annotation, it won't be narrowed.
14819
+ if (symbol.getDeclarations().length > maxDeclarationsToUseForInference) {
14820
+ return { type: types_1.UnknownType.create() };
14821
+ }
14604
14822
  // There was no declaration with a defined type.
14605
14823
  return { type: undefined };
14606
14824
  }
@@ -15080,6 +15298,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15080
15298
  }
15081
15299
  }
15082
15300
  });
15301
+ if (!isAssignable) {
15302
+ return false;
15303
+ }
15083
15304
  // Now handle generic base classes.
15084
15305
  destType.details.baseClasses.forEach((baseClass) => {
15085
15306
  if ((0, types_1.isInstantiableClass)(baseClass) &&
@@ -15325,63 +15546,50 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15325
15546
  srcTypeArgs = srcType.typeArguments;
15326
15547
  }
15327
15548
  let isCompatible = true;
15328
- if (srcTypeArgs) {
15329
- for (let srcArgIndex = 0; srcArgIndex < srcTypeArgs.length; srcArgIndex++) {
15330
- const srcTypeArg = srcTypeArgs[srcArgIndex];
15331
- // In most cases, the number of type args should match the number
15332
- // of type arguments, but there are a few special cases where this
15333
- // isn't true (e.g. assigning a Tuple[X, Y, Z] to a tuple[W]).
15334
- const destArgIndex = srcArgIndex >= destTypeArgs.length ? destTypeArgs.length - 1 : srcArgIndex;
15335
- const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
15336
- const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
15337
- const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
15338
- if (!destTypeParam || types_1.TypeVarType.getVariance(destTypeParam) === 3 /* Covariant */) {
15339
- if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15340
- if (diag) {
15341
- if (destTypeParam) {
15342
- const childDiag = diag.createAddendum();
15343
- childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant().format({
15344
- name: types_1.TypeVarType.getReadableName(destTypeParam),
15345
- }));
15346
- childDiag.addAddendum(assignmentDiag);
15347
- }
15348
- else {
15349
- diag.addAddendum(assignmentDiag);
15350
- }
15351
- }
15352
- isCompatible = false;
15353
- }
15354
- }
15355
- else if (types_1.TypeVarType.getVariance(destTypeParam) === 4 /* Contravariant */) {
15356
- if (!assignType(srcTypeArg, destTypeArg, assignmentDiag, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15357
- 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) {
15358
15579
  const childDiag = diag.createAddendum();
15359
- childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsContravariant().format({
15580
+ childDiag.addMessage(errorSource().format({
15360
15581
  name: types_1.TypeVarType.getReadableName(destTypeParam),
15582
+ ...printSrcDestTypes(srcTypeArg, destTypeArg),
15361
15583
  }));
15362
- childDiag.addAddendum(assignmentDiag);
15363
15584
  }
15364
- isCompatible = false;
15365
- }
15366
- }
15367
- else {
15368
- if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
15369
- // Don't report errors with type variables in "pseudo-random"
15370
- // classes since these type variables are not real.
15371
- if (!types_1.ClassType.isPseudoGenericClass(destType)) {
15372
- if (diag) {
15373
- const childDiag = diag.createAddendum();
15374
- childDiag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant().format({
15375
- name: types_1.TypeVarType.getReadableName(destTypeParam),
15376
- }));
15377
- childDiag.addAddendum(assignmentDiag);
15378
- }
15379
- isCompatible = false;
15585
+ else {
15586
+ diag.addAddendum(assignmentDiag);
15380
15587
  }
15381
15588
  }
15589
+ isCompatible = false;
15382
15590
  }
15383
15591
  }
15384
- }
15592
+ });
15385
15593
  return isCompatible;
15386
15594
  }
15387
15595
  // Determines if the source type can be assigned to the dest type.
@@ -15571,11 +15779,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15571
15779
  destType.details.parameters.length <= 2) {
15572
15780
  return true;
15573
15781
  }
15574
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15575
- sourceType: printType(srcType),
15576
- destType: printType(destType),
15577
- }));
15578
- 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
+ }
15579
15786
  }
15580
15787
  }
15581
15788
  if ((0, types_1.isAnyOrUnknown)(destType)) {
@@ -15605,25 +15812,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15605
15812
  return true;
15606
15813
  }
15607
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.
15608
15817
  if ((0, types_1.isUnion)(srcType)) {
15609
- if (assignFromUnionType(destType, srcType,
15610
- /* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount)) {
15611
- return true;
15612
- }
15818
+ return assignFromUnionType(destType, srcType,
15819
+ /* diag */ undefined, destTypeVarContext, srcTypeVarContext, originalFlags, recursionCount);
15613
15820
  }
15614
- else {
15615
- const clonedDestTypeVarContext = destTypeVarContext === null || destTypeVarContext === void 0 ? void 0 : destTypeVarContext.clone();
15616
- const clonedSrcTypeVarContext = srcTypeVarContext === null || srcTypeVarContext === void 0 ? void 0 : srcTypeVarContext.clone();
15617
- if (assignToUnionType(destType, srcType,
15618
- /* diag */ undefined, clonedDestTypeVarContext, clonedSrcTypeVarContext, originalFlags, recursionCount)) {
15619
- if (destTypeVarContext && clonedDestTypeVarContext) {
15620
- destTypeVarContext.copyFromClone(clonedDestTypeVarContext);
15621
- }
15622
- if (srcTypeVarContext && clonedSrcTypeVarContext) {
15623
- srcTypeVarContext.copyFromClone(clonedSrcTypeVarContext);
15624
- }
15625
- 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);
15626
15830
  }
15831
+ return true;
15627
15832
  }
15628
15833
  }
15629
15834
  const expandedSrcType = makeTopLevelTypeVarsConcrete(srcType);
@@ -15673,10 +15878,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15673
15878
  if (assignType(destType, instantiableType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
15674
15879
  return true;
15675
15880
  }
15676
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15677
- sourceType: printType(srcType),
15678
- destType: printType(destType),
15679
- }));
15881
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
15680
15882
  return false;
15681
15883
  }
15682
15884
  }
@@ -15700,10 +15902,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15700
15902
  /* reportErrorsUsingObjType */ false)) {
15701
15903
  return true;
15702
15904
  }
15703
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15704
- sourceType: printType(srcType),
15705
- destType: printType(destType),
15706
- }));
15905
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
15707
15906
  return false;
15708
15907
  }
15709
15908
  }
@@ -15933,10 +16132,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15933
16132
  diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.assignToNone());
15934
16133
  return false;
15935
16134
  }
15936
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
15937
- sourceType: printType(srcType),
15938
- destType: printType(destType),
15939
- }));
16135
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
15940
16136
  return false;
15941
16137
  }
15942
16138
  function assignFromUnionType(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
@@ -15983,6 +16179,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
15983
16179
  // whose primary type matches.
15984
16180
  remainingSrcSubtypes.forEach((srcSubtype) => {
15985
16181
  const destTypeIndex = remainingDestSubtypes.findIndex((destSubtype) => {
16182
+ if ((0, types_1.isTypeSame)(destSubtype, srcSubtype)) {
16183
+ return true;
16184
+ }
15986
16185
  if ((0, types_1.isClass)(srcSubtype) &&
15987
16186
  (0, types_1.isClass)(destSubtype) &&
15988
16187
  types_1.TypeBase.isInstance(srcSubtype) === types_1.TypeBase.isInstance(destSubtype) &&
@@ -16007,6 +16206,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16007
16206
  // If there is are remaining dest subtypes and they're all type variables,
16008
16207
  // attempt to assign the remaining source subtypes to them.
16009
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
+ }
16010
16217
  const isReversed = (flags & 2 /* ReverseTypeVarMatching */) !== 0;
16011
16218
  const effectiveDestSubtypes = isReversed ? remainingSrcSubtypes : remainingDestSubtypes;
16012
16219
  if (effectiveDestSubtypes.length === 0 || effectiveDestSubtypes.some((t) => !(0, types_1.isTypeVar)(t))) {
@@ -16058,34 +16265,42 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16058
16265
  }
16059
16266
  if (!assignType(destType, subtype,
16060
16267
  /* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
16061
- const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
16062
16268
  // Determine if the current subtype is subsumed by another subtype
16063
16269
  // in the same union. If so, we can ignore this.
16064
- let isSubtypeSubsumed = false;
16065
- srcType.subtypes.forEach((innerSubtype) => {
16066
- if (!isSubtypeSubsumed &&
16067
- !(0, types_1.isTypeSame)(innerSubtype, subtype) &&
16068
- !(0, types_1.isAnyOrUnknown)(innerSubtype) &&
16069
- isProperSubtype(innerSubtype, concreteSubtype, recursionCount)) {
16070
- isSubtypeSubsumed = true;
16071
- }
16072
- });
16270
+ const isSubtypeSubsumed = isTypeSubsumedByOtherType(subtype, srcType.subtypes,
16271
+ /* allowAnyToSubsume */ false, recursionCount);
16073
16272
  // Try again with a concrete version of the subtype.
16074
16273
  if (!isSubtypeSubsumed &&
16075
- !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)) {
16076
16275
  isIncompatible = true;
16077
16276
  }
16078
16277
  }
16079
16278
  }, /* sortSubtypes */ true);
16080
16279
  if (isIncompatible) {
16081
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
16082
- sourceType: printType(srcType),
16083
- destType: printType(destType),
16084
- }));
16280
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
16085
16281
  return false;
16086
16282
  }
16087
16283
  return true;
16088
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
+ }
16089
16304
  // Determines whether the srcType is a subtype of destType but the converse
16090
16305
  // is not true. It's important that we check both directions to avoid
16091
16306
  // matches for types like `tuple[Any]` and `tuple[int]` from being considered
@@ -16146,10 +16361,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16146
16361
  }
16147
16362
  });
16148
16363
  if (isIncompatible) {
16149
- diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
16150
- sourceType: printType(srcType),
16151
- destType: printType(destType),
16152
- }));
16364
+ diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
16153
16365
  return false;
16154
16366
  }
16155
16367
  return true;
@@ -16229,10 +16441,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16229
16441
  }
16230
16442
  if (!foundMatch) {
16231
16443
  if (diag && diagAddendum) {
16232
- diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format({
16233
- sourceType: printType(srcType),
16234
- destType: printType(destType),
16235
- }));
16444
+ diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeAssignmentMismatch().format(printSrcDestTypes(srcType, destType)));
16236
16445
  diag.addAddendum(diagAddendum);
16237
16446
  }
16238
16447
  return false;
@@ -17663,6 +17872,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17663
17872
  const flags = extraFlags ? evaluatorOptions.printTypeFlags | extraFlags : evaluatorOptions.printTypeFlags;
17664
17873
  return TypePrinter.printFunctionParts(type, flags, getFunctionEffectiveReturnType);
17665
17874
  }
17875
+ // Prints two types and determines whether they need to be output in
17876
+ // fully-qualified form for disambiguation.
17877
+ function printSrcDestTypes(srcType, destType) {
17878
+ const simpleSrcType = printType(srcType);
17879
+ const simpleDestType = printType(destType);
17880
+ if (simpleSrcType !== simpleDestType) {
17881
+ return { sourceType: simpleSrcType, destType: simpleDestType };
17882
+ }
17883
+ const fullSrcType = printType(srcType, { useFullyQualifiedNames: true });
17884
+ const fullDestType = printType(destType, { useFullyQualifiedNames: true });
17885
+ if (fullSrcType !== fullDestType) {
17886
+ return { sourceType: fullSrcType, destType: fullDestType };
17887
+ }
17888
+ return { sourceType: simpleSrcType, destType: simpleDestType };
17889
+ }
17666
17890
  function printType(type, options) {
17667
17891
  let flags = evaluatorOptions.printTypeFlags;
17668
17892
  if (options === null || options === void 0 ? void 0 : options.expandTypeAlias) {
@@ -17683,6 +17907,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17683
17907
  if (options === null || options === void 0 ? void 0 : options.omitTypeArgumentsIfUnknown) {
17684
17908
  flags |= 2 /* OmitTypeArgumentsIfUnknown */;
17685
17909
  }
17910
+ if (options === null || options === void 0 ? void 0 : options.useFullyQualifiedNames) {
17911
+ flags |= 4096 /* UseFullyQualifiedNames */;
17912
+ }
17686
17913
  return TypePrinter.printType(type, flags, getFunctionEffectiveReturnType);
17687
17914
  }
17688
17915
  // Calls back into the parser to parse the contents of a string literal.
@@ -17838,6 +18065,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
17838
18065
  addDiagnostic,
17839
18066
  addDiagnosticForTextRange,
17840
18067
  printType,
18068
+ printSrcDestTypes,
17841
18069
  printFunctionParts,
17842
18070
  getTypeCacheEntryCount,
17843
18071
  disposeEvaluator,