@zzzen/pyright-internal 1.2.0-dev.2022-07-02 → 1.2.0-dev.20220703

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 (80) hide show
  1. package/dist/analyzer/aliasDeclarationUtils.js +2 -2
  2. package/dist/analyzer/analyzerNodeInfo.d.ts +4 -1
  3. package/dist/analyzer/analyzerNodeInfo.js +12 -1
  4. package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
  5. package/dist/analyzer/binder.d.ts +6 -1
  6. package/dist/analyzer/binder.js +133 -30
  7. package/dist/analyzer/binder.js.map +1 -1
  8. package/dist/analyzer/checker.d.ts +4 -1
  9. package/dist/analyzer/checker.js +125 -47
  10. package/dist/analyzer/checker.js.map +1 -1
  11. package/dist/analyzer/constraintSolver.js +6 -3
  12. package/dist/analyzer/constraintSolver.js.map +1 -1
  13. package/dist/analyzer/declaration.d.ts +18 -6
  14. package/dist/analyzer/declaration.js +19 -9
  15. package/dist/analyzer/declaration.js.map +1 -1
  16. package/dist/analyzer/declarationUtils.d.ts +1 -1
  17. package/dist/analyzer/declarationUtils.js +19 -16
  18. package/dist/analyzer/declarationUtils.js.map +1 -1
  19. package/dist/analyzer/packageTypeVerifier.js +6 -6
  20. package/dist/analyzer/parseTreeUtils.d.ts +3 -3
  21. package/dist/analyzer/parseTreeUtils.js +16 -11
  22. package/dist/analyzer/parseTreeUtils.js.map +1 -1
  23. package/dist/analyzer/parseTreeWalker.d.ts +4 -1
  24. package/dist/analyzer/parseTreeWalker.js +19 -1
  25. package/dist/analyzer/parseTreeWalker.js.map +1 -1
  26. package/dist/analyzer/properties.js +2 -0
  27. package/dist/analyzer/properties.js.map +1 -1
  28. package/dist/analyzer/protocols.d.ts +0 -1
  29. package/dist/analyzer/protocols.js +1 -63
  30. package/dist/analyzer/protocols.js.map +1 -1
  31. package/dist/analyzer/tracePrinter.js +8 -4
  32. package/dist/analyzer/tracePrinter.js.map +1 -1
  33. package/dist/analyzer/typeDocStringUtils.js +1 -1
  34. package/dist/analyzer/typeEvaluator.js +524 -176
  35. package/dist/analyzer/typeEvaluator.js.map +1 -1
  36. package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -0
  37. package/dist/analyzer/typeEvaluatorWithTracker.js +2 -0
  38. package/dist/analyzer/typeEvaluatorWithTracker.js.map +1 -1
  39. package/dist/analyzer/typePrinter.js +4 -1
  40. package/dist/analyzer/typePrinter.js.map +1 -1
  41. package/dist/analyzer/typeStubWriter.d.ts +4 -1
  42. package/dist/analyzer/typeStubWriter.js +36 -0
  43. package/dist/analyzer/typeStubWriter.js.map +1 -1
  44. package/dist/analyzer/typeUtils.js +10 -5
  45. package/dist/analyzer/typeUtils.js.map +1 -1
  46. package/dist/analyzer/types.d.ts +11 -4
  47. package/dist/analyzer/types.js +23 -8
  48. package/dist/analyzer/types.js.map +1 -1
  49. package/dist/languageService/autoImporter.js +1 -1
  50. package/dist/languageService/callHierarchyProvider.js +9 -9
  51. package/dist/languageService/completionProvider.js +19 -13
  52. package/dist/languageService/completionProvider.js.map +1 -1
  53. package/dist/languageService/definitionProvider.js +3 -3
  54. package/dist/languageService/documentSymbolCollector.js +1 -1
  55. package/dist/languageService/documentSymbolProvider.js +10 -7
  56. package/dist/languageService/documentSymbolProvider.js.map +1 -1
  57. package/dist/languageService/hoverProvider.js +19 -5
  58. package/dist/languageService/hoverProvider.js.map +1 -1
  59. package/dist/languageService/referencesProvider.js +8 -5
  60. package/dist/languageService/referencesProvider.js.map +1 -1
  61. package/dist/languageService/tooltipUtils.js +1 -1
  62. package/dist/localization/localize.d.ts +27 -0
  63. package/dist/localization/localize.js +16 -0
  64. package/dist/localization/localize.js.map +1 -1
  65. package/dist/localization/package.nls.en-us.json +18 -2
  66. package/dist/parser/parseNodes.d.ts +41 -5
  67. package/dist/parser/parseNodes.js +83 -4
  68. package/dist/parser/parseNodes.js.map +1 -1
  69. package/dist/parser/parser.d.ts +3 -0
  70. package/dist/parser/parser.js +129 -12
  71. package/dist/parser/parser.js.map +1 -1
  72. package/dist/parser/tokenizer.js +4 -3
  73. package/dist/parser/tokenizer.js.map +1 -1
  74. package/dist/parser/tokenizerTypes.d.ts +5 -3
  75. package/dist/parser/tokenizerTypes.js +6 -4
  76. package/dist/parser/tokenizerTypes.js.map +1 -1
  77. package/dist/tests/typeEvaluator5.test.d.ts +1 -0
  78. package/dist/tests/typeEvaluator5.test.js +112 -0
  79. package/dist/tests/typeEvaluator5.test.js.map +1 -0
  80. package/package.json +1 -1
@@ -660,15 +660,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
660
660
  typeResult.type.details.illegalRecursionDetected = true;
661
661
  }
662
662
  }
663
- // Don't update the type cache with an unbound type that results from
664
- // a resolution cycle. The cache will be updated when the stack unwinds
665
- // and the type is fully evaluated.
666
- if (!(0, typeUtils_1.isTypeAliasPlaceholder)(typeResult.type)) {
667
- writeTypeCache(node, typeResult.type, flags, !!typeResult.isIncomplete, expectedType,
668
- /* allowSpeculativeCaching */ true);
669
- if (expectedType && !(0, types_1.isAnyOrUnknown)(expectedType) && !(0, types_1.isNever)(expectedType)) {
670
- expectedTypeCache.set(node.id, expectedType);
671
- }
663
+ writeTypeCache(node, typeResult.type, flags, !!typeResult.isIncomplete, expectedType,
664
+ /* allowSpeculativeCaching */ true);
665
+ if (expectedType && !(0, types_1.isAnyOrUnknown)(expectedType) && !(0, types_1.isNever)(expectedType)) {
666
+ expectedTypeCache.set(node.id, expectedType);
672
667
  }
673
668
  if (printExpressionTypes) {
674
669
  printExpressionSpaceCount--;
@@ -1368,7 +1363,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1368
1363
  // Handle the case where the symbol is a class-level variable
1369
1364
  // where the type isn't declared in this class but is in
1370
1365
  // a parent class.
1371
- if (getDeclaredTypeOfSymbol(symbol) === undefined &&
1366
+ if (getDeclaredTypeOfSymbol(symbol, expression) === undefined &&
1372
1367
  symbolWithScope.scope.type === 2 /* Class */) {
1373
1368
  const enclosingClass = ParseTreeUtils.getEnclosingClassOrFunction(expression);
1374
1369
  if (enclosingClass && enclosingClass.nodeType === 10 /* Class */) {
@@ -1386,7 +1381,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
1386
1381
  break;
1387
1382
  }
1388
1383
  case 54 /* TypeAnnotation */: {
1389
- return getDeclaredTypeForExpression(expression.valueExpression);
1384
+ return getDeclaredTypeForExpression(expression.valueExpression, usage);
1390
1385
  }
1391
1386
  case 35 /* MemberAccess */: {
1392
1387
  const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.leftExpression, 2 /* DoNotSpecialize */).type);
@@ -2540,9 +2535,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2540
2535
  return undefined;
2541
2536
  }
2542
2537
  function getTypeOfName(node, flags) {
2543
- var _a;
2538
+ var _a, _b;
2544
2539
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
2545
2540
  const name = node.value;
2541
+ let symbol;
2546
2542
  let type;
2547
2543
  let isIncomplete = false;
2548
2544
  const allowForwardReferences = (flags & 4 /* AllowForwardReferences */) !== 0 || fileInfo.isStubFile;
@@ -2556,96 +2552,104 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2556
2552
  };
2557
2553
  }
2558
2554
  }
2559
- // Look for the scope that contains the value definition and
2560
- // see if it has a declared type.
2561
- const symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags & 1024 /* ExpectingTypeAnnotation */) !== 0);
2562
- if (symbolWithScope) {
2563
- let useCodeFlowAnalysis = !allowForwardReferences;
2564
- // If the symbol is implicitly imported from the builtin
2565
- // scope, there's no need to use code flow analysis.
2566
- if (symbolWithScope.scope.type === 4 /* Builtin */) {
2567
- useCodeFlowAnalysis = false;
2568
- }
2569
- const symbol = symbolWithScope.symbol;
2570
- // Get the effective type (either the declared type or the inferred type).
2571
- // If we're using code flow analysis, pass the usage node so we consider
2572
- // only the assignment nodes that are reachable from this usage.
2573
- const effectiveTypeInfo = getEffectiveTypeOfSymbolForUsage(symbol, useCodeFlowAnalysis ? node : undefined);
2574
- let effectiveType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(effectiveTypeInfo.type);
2575
- if (effectiveTypeInfo.isIncomplete) {
2576
- if ((0, types_1.isUnbound)(effectiveType)) {
2577
- effectiveType = types_1.UnknownType.create(/* isIncomplete */ true);
2578
- }
2579
- isIncomplete = true;
2580
- }
2581
- if (effectiveTypeInfo.isRecursiveDefinition && isNodeReachable(node)) {
2582
- addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.recursiveDefinition().format({ name }), node);
2583
- }
2584
- const isSpecialBuiltIn = !!effectiveType && (0, types_1.isInstantiableClass)(effectiveType) && types_1.ClassType.isSpecialBuiltIn(effectiveType);
2585
- type = effectiveType;
2586
- if (useCodeFlowAnalysis && !isSpecialBuiltIn) {
2587
- // See if code flow analysis can tell us anything more about the type.
2588
- // If the symbol is declared outside of our execution scope, use its effective
2589
- // type. If it's declared inside our execution scope, it generally starts
2590
- // as unbound at the start of the code flow.
2591
- const typeAtStart = symbolWithScope.isBeyondExecutionScope || !symbol.isInitiallyUnbound()
2592
- ? effectiveType
2593
- : types_1.UnboundType.create();
2594
- const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
2595
- /* isInitialTypeIncomplete */ false,
2596
- /* startNode */ undefined);
2597
- if (codeFlowTypeResult.type) {
2598
- type = codeFlowTypeResult.type;
2599
- }
2600
- if (codeFlowTypeResult.isIncomplete) {
2555
+ const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
2556
+ if (typeParamSymbol) {
2557
+ symbol = typeParamSymbol;
2558
+ type = (_a = getDeclaredTypeOfSymbol(typeParamSymbol)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
2559
+ setSymbolAccessed(fileInfo, symbol, node);
2560
+ }
2561
+ else {
2562
+ // Look for the scope that contains the value definition and
2563
+ // see if it has a declared type.
2564
+ const symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags & 1024 /* ExpectingTypeAnnotation */) !== 0);
2565
+ if (symbolWithScope) {
2566
+ let useCodeFlowAnalysis = !allowForwardReferences;
2567
+ // If the symbol is implicitly imported from the builtin
2568
+ // scope, there's no need to use code flow analysis.
2569
+ if (symbolWithScope.scope.type === 4 /* Builtin */) {
2570
+ useCodeFlowAnalysis = false;
2571
+ }
2572
+ symbol = symbolWithScope.symbol;
2573
+ // Get the effective type (either the declared type or the inferred type).
2574
+ // If we're using code flow analysis, pass the usage node so we consider
2575
+ // only the assignment nodes that are reachable from this usage.
2576
+ const effectiveTypeInfo = getEffectiveTypeOfSymbolForUsage(symbol, useCodeFlowAnalysis ? node : undefined);
2577
+ let effectiveType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(effectiveTypeInfo.type);
2578
+ if (effectiveTypeInfo.isIncomplete) {
2579
+ if ((0, types_1.isUnbound)(effectiveType)) {
2580
+ effectiveType = types_1.UnknownType.create(/* isIncomplete */ true);
2581
+ }
2601
2582
  isIncomplete = true;
2602
2583
  }
2603
- if (!codeFlowTypeResult.type && symbolWithScope.isBeyondExecutionScope) {
2604
- const outerScopeTypeResult = getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType);
2605
- if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.type) {
2606
- type = outerScopeTypeResult.type;
2607
- }
2608
- if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.isIncomplete) {
2584
+ if (effectiveTypeInfo.isRecursiveDefinition && isNodeReachable(node)) {
2585
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.recursiveDefinition().format({ name }), node);
2586
+ }
2587
+ const isSpecialBuiltIn = !!effectiveType && (0, types_1.isInstantiableClass)(effectiveType) && types_1.ClassType.isSpecialBuiltIn(effectiveType);
2588
+ type = effectiveType;
2589
+ if (useCodeFlowAnalysis && !isSpecialBuiltIn) {
2590
+ // See if code flow analysis can tell us anything more about the type.
2591
+ // If the symbol is declared outside of our execution scope, use its effective
2592
+ // type. If it's declared inside our execution scope, it generally starts
2593
+ // as unbound at the start of the code flow.
2594
+ const typeAtStart = symbolWithScope.isBeyondExecutionScope || !symbol.isInitiallyUnbound()
2595
+ ? effectiveType
2596
+ : types_1.UnboundType.create();
2597
+ const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
2598
+ /* isInitialTypeIncomplete */ false,
2599
+ /* startNode */ undefined);
2600
+ if (codeFlowTypeResult.type) {
2601
+ type = codeFlowTypeResult.type;
2602
+ }
2603
+ if (codeFlowTypeResult.isIncomplete) {
2609
2604
  isIncomplete = true;
2610
2605
  }
2606
+ if (!codeFlowTypeResult.type && symbolWithScope.isBeyondExecutionScope) {
2607
+ const outerScopeTypeResult = getCodeFlowTypeForCapturedVariable(node, symbolWithScope, effectiveType);
2608
+ if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.type) {
2609
+ type = outerScopeTypeResult.type;
2610
+ }
2611
+ if (outerScopeTypeResult === null || outerScopeTypeResult === void 0 ? void 0 : outerScopeTypeResult.isIncomplete) {
2612
+ isIncomplete = true;
2613
+ }
2614
+ }
2611
2615
  }
2612
- }
2613
- // Detect, report, and fill in missing type arguments if appropriate.
2614
- type = reportMissingTypeArguments(node, type, flags);
2615
- setSymbolAccessed(fileInfo, symbol, node);
2616
- if ((flags & 1024 /* ExpectingTypeAnnotation */) !== 0) {
2617
- // Verify that the name does not refer to a (non type alias) variable.
2618
- if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
2619
- let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
2620
- if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
2621
- // This check exempts class types that are created by calling
2622
- // NewType, NamedTuple, and by invoking a metaclass directly.
2623
- isAllowedTypeForVariable = true;
2624
- }
2625
- // Disable for assignments in the typings.pyi file, since it defines special forms.
2626
- if (!isAllowedTypeForVariable && !fileInfo.isTypingStubFile) {
2627
- // This might be a union that was previously a type alias
2628
- // but was reconstituted in such a way that we lost the
2629
- // typeAliasInfo. Avoid the false positive error by suppressing
2630
- // the error when it looks like a plausible type alias type.
2631
- if (effectiveTypeInfo.includesIllegalTypeAliasDecl ||
2632
- !types_1.TypeBase.isInstantiable(type) ||
2633
- (flags & 2 /* DoNotSpecialize */) !== 0) {
2634
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationVariable(), node);
2635
- type = types_1.UnknownType.create();
2616
+ // Detect, report, and fill in missing type arguments if appropriate.
2617
+ type = reportMissingTypeArguments(node, type, flags);
2618
+ setSymbolAccessed(fileInfo, symbol, node);
2619
+ if ((flags & 1024 /* ExpectingTypeAnnotation */) !== 0) {
2620
+ // Verify that the name does not refer to a (non type alias) variable.
2621
+ if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
2622
+ let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
2623
+ if ((0, types_1.isClass)(type) && !type.includeSubclasses) {
2624
+ // This check exempts class types that are created by calling
2625
+ // NewType, NamedTuple, and by invoking a metaclass directly.
2626
+ isAllowedTypeForVariable = true;
2627
+ }
2628
+ // Disable for assignments in the typings.pyi file, since it defines special forms.
2629
+ if (!isAllowedTypeForVariable && !fileInfo.isTypingStubFile) {
2630
+ // This might be a union that was previously a type alias
2631
+ // but was reconstituted in such a way that we lost the
2632
+ // typeAliasInfo. Avoid the false positive error by suppressing
2633
+ // the error when it looks like a plausible type alias type.
2634
+ if (effectiveTypeInfo.includesIllegalTypeAliasDecl ||
2635
+ !types_1.TypeBase.isInstantiable(type) ||
2636
+ (flags & 2 /* DoNotSpecialize */) !== 0) {
2637
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationVariable(), node);
2638
+ type = types_1.UnknownType.create();
2639
+ }
2636
2640
  }
2637
2641
  }
2638
2642
  }
2639
2643
  }
2640
- }
2641
- else {
2642
- // Handle the special case of "reveal_type" and "reveal_locals".
2643
- if (name === 'reveal_type' || name === 'reveal_locals') {
2644
- type = types_1.AnyType.create();
2645
- }
2646
2644
  else {
2647
- addDiagnostic(fileInfo.diagnosticRuleSet.reportUndefinedVariable, diagnosticRules_1.DiagnosticRule.reportUndefinedVariable, localize_1.Localizer.Diagnostic.symbolIsUndefined().format({ name }), node);
2648
- type = types_1.UnknownType.create();
2645
+ // Handle the special case of "reveal_type" and "reveal_locals".
2646
+ if (name === 'reveal_type' || name === 'reveal_locals') {
2647
+ type = types_1.AnyType.create();
2648
+ }
2649
+ else {
2650
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportUndefinedVariable, diagnosticRules_1.DiagnosticRule.reportUndefinedVariable, localize_1.Localizer.Diagnostic.symbolIsUndefined().format({ name }), node);
2651
+ type = types_1.UnknownType.create();
2652
+ }
2649
2653
  }
2650
2654
  }
2651
2655
  if ((0, types_1.isParamSpec)(type)) {
@@ -2660,7 +2664,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2660
2664
  type.details.name === name) {
2661
2665
  // Handle the special case of a PEP 604 union. These can appear within
2662
2666
  // an implied type alias where we are not expecting a type.
2663
- const isPep604Union = ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 7 /* BinaryOperation */ &&
2667
+ const isPep604Union = ((_b = node.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 7 /* BinaryOperation */ &&
2664
2668
  node.parent.operator === 6 /* BitwiseOr */;
2665
2669
  if (!isPep604Union) {
2666
2670
  // A TypeVar in contexts where we're not expecting a type is
@@ -2748,6 +2752,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2748
2752
  type = scopedTypeVarInfo.type;
2749
2753
  if ((flags & 2048 /* DisallowTypeVarsWithScopeId */) !== 0 && type.scopeId !== undefined) {
2750
2754
  if (!type.details.isSynthesized && !type.details.isParamSpec) {
2755
+ // This TypeVar already has a scope ID assigned to it. See if it
2756
+ // originates from type parameter syntax. If so, allow it.
2757
+ if (type.details.isTypeParamSyntax) {
2758
+ return type;
2759
+ }
2760
+ // If this type variable expression is used within a generic class,
2761
+ // function, or type alias that uses type parameter syntax, there is
2762
+ // no need to report an error here.
2763
+ const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(node);
2764
+ if (typeVarScopeNode &&
2765
+ typeVarScopeNode.typeParameters &&
2766
+ !typeVarScopeNode.typeParameters.parameters.some((t) => t.name === node)) {
2767
+ return type;
2768
+ }
2751
2769
  addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarUsedByOuterScope().format({ name: type.details.name }), node);
2752
2770
  }
2753
2771
  }
@@ -2773,6 +2791,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2773
2791
  }
2774
2792
  }
2775
2793
  if (enclosingScope) {
2794
+ // If the enclosing scope is using type parameter syntax, traditional
2795
+ // type variables can't be used in this context.
2796
+ if (enclosingScope.typeParameters) {
2797
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeParameterNotDeclared().format({
2798
+ name: type.details.name,
2799
+ container: enclosingScope.name.value,
2800
+ }), node);
2801
+ }
2776
2802
  type = types_1.TypeVarType.cloneForScopeId(type, getScopeIdForNode(enclosingScope), enclosingScope.name.value, enclosingScope.nodeType === 28 /* Function */
2777
2803
  ? 1 /* Function */
2778
2804
  : 0 /* Class */);
@@ -2866,50 +2892,48 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2866
2892
  // Walks up the parse tree to find a function, class, or type alias
2867
2893
  // assignment that provides the context for a type variable.
2868
2894
  function findScopedTypeVar(node, type) {
2869
- var _a;
2870
2895
  let curNode = node;
2871
2896
  let nestedClassCount = 0;
2872
2897
  (0, debug_1.assert)(types_1.TypeBase.isInstantiable(type));
2873
2898
  while (curNode) {
2874
- // Generally, getTypeVarScopeNode should not include the function
2875
- // that contains the TypeVar in its signature, but we make an exception
2876
- // for TypeVars that are used in a member access expression to accommodate
2877
- // ParamSpecs (P.args and P.kwargs).
2878
- curNode = ParseTreeUtils.getTypeVarScopeNode(curNode, ((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 35 /* MemberAccess */);
2899
+ curNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
2879
2900
  if (!curNode) {
2880
2901
  break;
2881
2902
  }
2882
- let typeVarsForScope;
2903
+ let typeParametersForScope;
2904
+ let scopeUsesTypeParameterSyntax = false;
2883
2905
  if (curNode.nodeType === 10 /* Class */) {
2884
2906
  const classTypeInfo = getTypeOfClass(curNode);
2885
- if (classTypeInfo) {
2886
- typeVarsForScope = classTypeInfo.classType.details.typeParameters;
2907
+ if (classTypeInfo && !types_1.ClassType.isPartiallyEvaluated(classTypeInfo.classType)) {
2908
+ typeParametersForScope = classTypeInfo.classType.details.typeParameters;
2887
2909
  }
2910
+ scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
2888
2911
  nestedClassCount++;
2889
2912
  }
2890
2913
  else if (curNode.nodeType === 28 /* Function */) {
2891
2914
  const functionTypeInfo = getTypeOfFunction(curNode);
2892
2915
  if (functionTypeInfo) {
2893
- typeVarsForScope = [];
2916
+ typeParametersForScope = [];
2894
2917
  functionTypeInfo.functionType.details.parameters.forEach((param) => {
2895
2918
  if (param.hasDeclaredType) {
2896
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeVarsForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
2919
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(param.type));
2897
2920
  }
2898
2921
  });
2899
2922
  if (functionTypeInfo.functionType.details.declaredReturnType) {
2900
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeVarsForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
2923
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParametersForScope, (0, typeUtils_1.getTypeVarArgumentsRecursive)(functionTypeInfo.functionType.details.declaredReturnType));
2901
2924
  }
2902
2925
  }
2926
+ scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
2903
2927
  }
2904
- else if (curNode.nodeType === 36 /* Module */) {
2905
- break;
2928
+ else if (curNode.nodeType === 77 /* TypeAlias */) {
2929
+ scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
2906
2930
  }
2907
- if (typeVarsForScope) {
2908
- const match = typeVarsForScope.find((typeVar) => typeVar.details.name === type.details.name);
2931
+ if (typeParametersForScope) {
2932
+ const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
2909
2933
  if (match === null || match === void 0 ? void 0 : match.scopeId) {
2910
2934
  // Use the scoped version of the TypeVar rather than the (unscoped) original type.
2911
2935
  type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
2912
- return { type, foundInterveningClass: nestedClassCount > 1 };
2936
+ return { type, foundInterveningClass: nestedClassCount > 1 && !scopeUsesTypeParameterSyntax };
2913
2937
  }
2914
2938
  }
2915
2939
  curNode = curNode.parent;
@@ -2917,14 +2941,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
2917
2941
  // See if this is part of an assignment statement that is defining a type alias.
2918
2942
  curNode = node;
2919
2943
  while (curNode) {
2920
- if (curNode.nodeType === 3 /* Assignment */) {
2921
- const leftType = readTypeCache(curNode.leftExpression, 0 /* None */);
2944
+ let leftType;
2945
+ let typeAliasNode = undefined;
2946
+ if (curNode.nodeType === 77 /* TypeAlias */) {
2947
+ leftType = readTypeCache(curNode.name, 0 /* None */);
2948
+ typeAliasNode = curNode;
2949
+ }
2950
+ else if (curNode.nodeType === 3 /* Assignment */) {
2951
+ leftType = readTypeCache(curNode.leftExpression, 0 /* None */);
2952
+ }
2953
+ if (leftType) {
2922
2954
  // Is this a placeholder that was temporarily written to the cache for
2923
2955
  // purposes of resolving type aliases?
2924
2956
  if (leftType &&
2925
2957
  (0, types_1.isTypeVar)(leftType) &&
2926
2958
  leftType.details.recursiveTypeAliasScopeId &&
2927
2959
  leftType.details.recursiveTypeAliasName) {
2960
+ // Type alias statements cannot be used with old-style type variables.
2961
+ if (typeAliasNode && !type.details.isTypeParamSyntax) {
2962
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeParameterNotDeclared().format({
2963
+ name: type.details.name,
2964
+ container: typeAliasNode.name.value,
2965
+ }), node);
2966
+ }
2928
2967
  return {
2929
2968
  type: types_1.TypeVarType.cloneForScopeId(type, leftType.details.recursiveTypeAliasScopeId, leftType.details.recursiveTypeAliasName, 2 /* TypeAlias */),
2930
2969
  foundInterveningClass: false,
@@ -4130,7 +4169,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
4130
4169
  }
4131
4170
  if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
4132
4171
  const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
4133
- const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, undefined, typeArgTypes);
4172
+ const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
4134
4173
  return { type, node };
4135
4174
  }
4136
4175
  let isIncomplete = false;
@@ -5673,6 +5712,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5673
5712
  return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
5674
5713
  /* includesTypes */ false);
5675
5714
  }
5715
+ // Handle the NewType specially, replacing the normal return type.
5716
+ if (expandedSubtype.details.builtInName === 'NewType') {
5717
+ return createNewType(errorNode, argList);
5718
+ }
5676
5719
  let effectiveTypeVarContext = typeVarContext;
5677
5720
  if (!effectiveTypeVarContext) {
5678
5721
  // If a typeVarContext wasn't provided by the caller, allocate one here.
@@ -5709,10 +5752,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
5709
5752
  argumentErrors = true;
5710
5753
  }
5711
5754
  }
5712
- // Handle the NewType specially, replacing the normal return type.
5713
- if (!functionResult.argumentErrors && expandedSubtype.details.builtInName === 'NewType') {
5714
- return createNewType(errorNode, argList);
5715
- }
5716
5755
  if (expandedSubtype.details.builtInName === '__import__') {
5717
5756
  // For the special __import__ type, we'll override the return type to be "Any".
5718
5757
  // This is required because we don't know what module was imported, and we don't
@@ -6881,7 +6920,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6881
6920
  // scope.
6882
6921
  let eliminateUnsolvedInUnions = true;
6883
6922
  let curNode = errorNode;
6884
- while (true) {
6923
+ while (curNode) {
6885
6924
  const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
6886
6925
  if (!typeVarScopeNode) {
6887
6926
  break;
@@ -6890,7 +6929,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
6890
6929
  if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
6891
6930
  eliminateUnsolvedInUnions = false;
6892
6931
  }
6893
- curNode = typeVarScopeNode;
6932
+ curNode = typeVarScopeNode.parent;
6894
6933
  }
6895
6934
  // If the function is returning a callable, don't eliminate unsolved
6896
6935
  // type vars within a union. There are legit uses for unsolved type vars
@@ -7357,21 +7396,21 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
7357
7396
  }
7358
7397
  else if (paramName === 'covariant') {
7359
7398
  if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
7360
- if (typeVar.details.variance === 2 /* Contravariant */) {
7399
+ if (typeVar.details.declaredVariance === 3 /* Contravariant */) {
7361
7400
  addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
7362
7401
  }
7363
7402
  else {
7364
- typeVar.details.variance = 1 /* Covariant */;
7403
+ typeVar.details.declaredVariance = 2 /* Covariant */;
7365
7404
  }
7366
7405
  }
7367
7406
  }
7368
7407
  else if (paramName === 'contravariant') {
7369
7408
  if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
7370
- if (typeVar.details.variance === 1 /* Covariant */) {
7409
+ if (typeVar.details.declaredVariance === 2 /* Covariant */) {
7371
7410
  addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
7372
7411
  }
7373
7412
  else {
7374
- typeVar.details.variance = 2 /* Contravariant */;
7413
+ typeVar.details.declaredVariance = 3 /* Contravariant */;
7375
7414
  }
7376
7415
  }
7377
7416
  }
@@ -9832,7 +9871,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9832
9871
  }
9833
9872
  return undefined;
9834
9873
  }
9835
- function transformTypeForTypeAlias(type, name, errorNode) {
9874
+ function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
9836
9875
  if (!types_1.TypeBase.isInstantiable(type)) {
9837
9876
  return type;
9838
9877
  }
@@ -9841,17 +9880,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
9841
9880
  if ((0, typeUtils_1.isTypeAliasPlaceholder)(type)) {
9842
9881
  return type;
9843
9882
  }
9844
- // Determine if there are any generic type parameters associated
9845
- // with this type alias.
9846
- let typeParameters = [];
9847
- // Skip this for a simple TypeVar (one that's not part of a union).
9848
- if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
9849
- (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
9850
- (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
9851
- });
9883
+ if (!typeParameters) {
9884
+ // Determine if there are any generic type parameters associated
9885
+ // with this type alias.
9886
+ typeParameters = [];
9887
+ // Skip this for a simple TypeVar (one that's not part of a union).
9888
+ if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
9889
+ (0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
9890
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
9891
+ });
9892
+ }
9893
+ // Don't include any synthesized type variables.
9894
+ typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
9852
9895
  }
9853
- // Don't include any synthesized type variables.
9854
- typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
9855
9896
  // Convert all type variables to instances.
9856
9897
  typeParameters = typeParameters.map((typeVar) => {
9857
9898
  if (types_1.TypeBase.isInstance(typeVar)) {
@@ -10052,7 +10093,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10052
10093
  }
10053
10094
  if (!rightHandType) {
10054
10095
  // Determine whether there is a declared type.
10055
- const declaredType = getDeclaredTypeForExpression(node.leftExpression, { method: 'set' });
10096
+ const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
10097
+ method: 'set',
10098
+ });
10056
10099
  let typeAliasNameNode;
10057
10100
  let isSpeculativeTypeAlias = false;
10058
10101
  if (isDeclaredTypeAlias(node.leftExpression)) {
@@ -10158,6 +10201,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10158
10201
  /* allowAssignmentToFinalVar */ true, expectedTypeDiagAddendum);
10159
10202
  writeTypeCache(node, rightHandType, 0 /* None */, isIncomplete);
10160
10203
  }
10204
+ // Evaluates the type of a type alias (i.e. "type") statement. This code
10205
+ // path does not handle traditional type aliases, which are treated as
10206
+ // variables since they use normal variable assignment syntax.
10207
+ function getTypeOfTypeAlias(node) {
10208
+ const cachedType = readTypeCache(node.name, 0 /* None */);
10209
+ if (cachedType) {
10210
+ return cachedType;
10211
+ }
10212
+ // Synthesize a type variable that represents the type alias while we're
10213
+ // evaluating it. This allows us to handle recursive definitions.
10214
+ const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${node.name.value}`);
10215
+ typeAliasTypeVar.details.isSynthesized = true;
10216
+ typeAliasTypeVar.details.recursiveTypeAliasName = node.name.value;
10217
+ const scopeId = getScopeIdForNode(node.name);
10218
+ typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
10219
+ typeAliasTypeVar.scopeId = scopeId;
10220
+ // Write the type to the type cache. It will be replaced below.
10221
+ writeTypeCache(node.name, typeAliasTypeVar, /* flags */ undefined, /* isIncomplete */ false);
10222
+ // Set a partial type to handle recursive (self-referential) type aliases.
10223
+ const scope = ScopeUtils.getScopeForNode(node);
10224
+ const typeAliasSymbol = scope === null || scope === void 0 ? void 0 : scope.lookUpSymbolRecursive(node.name.value);
10225
+ const typeAliasDecl = AnalyzerNodeInfo.getDeclaration(node);
10226
+ if (typeAliasDecl && typeAliasSymbol) {
10227
+ setSymbolResolutionPartialType(typeAliasSymbol.symbol, typeAliasDecl, typeAliasTypeVar);
10228
+ }
10229
+ let typeParameters = [];
10230
+ if (node.typeParameters) {
10231
+ typeParameters = evaluateTypeParameterList(node.typeParameters);
10232
+ typeAliasTypeVar.details.recursiveTypeParameters = typeParameters;
10233
+ }
10234
+ const aliasTypeResult = getTypeOfExpressionExpectingType(node.expression);
10235
+ let isIncomplete = false;
10236
+ let aliasType = aliasTypeResult.type;
10237
+ if (aliasTypeResult.isIncomplete) {
10238
+ isIncomplete = true;
10239
+ }
10240
+ // Clear the temporary type we wrote above.
10241
+ deleteTypeCacheEntry(node.name);
10242
+ aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters);
10243
+ if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
10244
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
10245
+ name: node.name.value,
10246
+ }), node.expression);
10247
+ aliasType = types_1.UnknownType.create();
10248
+ }
10249
+ // Set the resulting type to the boundType of the original type alias
10250
+ // to support recursive type aliases.
10251
+ typeAliasTypeVar.details.boundType = aliasType;
10252
+ if (typeAliasTypeVar.details.illegalRecursionDetected) {
10253
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveIndirect().format({
10254
+ name: node.name.value,
10255
+ }), node.name);
10256
+ }
10257
+ writeTypeCache(node.name, aliasType, 0 /* None */, isIncomplete);
10258
+ return aliasType;
10259
+ }
10161
10260
  function evaluateTypesForAugmentedAssignment(node) {
10162
10261
  if (readTypeCache(node, 0 /* None */)) {
10163
10262
  return;
@@ -10223,7 +10322,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10223
10322
  writeTypeCache(node.name, classType, /* flags */ undefined, /* isIncomplete */ false);
10224
10323
  // Keep a list of unique type parameters that are used in the
10225
10324
  // base class arguments.
10226
- const typeParameters = [];
10325
+ let typeParameters = [];
10326
+ if (node.typeParameters) {
10327
+ typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
10328
+ }
10227
10329
  // If the class derives from "Generic" directly, it will provide
10228
10330
  // all of the type parameters in the specified order.
10229
10331
  let genericTypeParameters;
@@ -10344,12 +10446,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10344
10446
  (0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10345
10447
  if ((0, types_1.isInstantiableClass)(argType)) {
10346
10448
  if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
10347
- if (!genericTypeParameters) {
10348
- if (protocolTypeParameters) {
10349
- addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
10449
+ // 'Generic' is implicitly added if type parameter syntax is used.
10450
+ if (node.typeParameters) {
10451
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
10452
+ }
10453
+ else {
10454
+ if (!genericTypeParameters) {
10455
+ if (protocolTypeParameters) {
10456
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
10457
+ }
10458
+ genericTypeParameters = [];
10459
+ (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10350
10460
  }
10351
- genericTypeParameters = [];
10352
- (0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10353
10461
  }
10354
10462
  }
10355
10463
  else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
@@ -10361,6 +10469,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10361
10469
  }
10362
10470
  protocolTypeParameters = [];
10363
10471
  (0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
10472
+ if (node.typeParameters && protocolTypeParameters.length > 0) {
10473
+ addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
10474
+ protocolTypeParameters = [];
10475
+ }
10364
10476
  }
10365
10477
  }
10366
10478
  }
@@ -10423,10 +10535,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10423
10535
  // If genericTypeParameters or protocolTypeParameters are provided,
10424
10536
  // make sure that typeParameters is a proper subset.
10425
10537
  genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
10426
- if (genericTypeParameters) {
10538
+ if (genericTypeParameters && !node.typeParameters) {
10427
10539
  verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
10428
10540
  }
10429
- classType.details.typeParameters = genericTypeParameters || typeParameters;
10541
+ classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
10542
+ // Determine if one or more type parameters is autovariance.
10543
+ if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
10544
+ classType.details.requiresVarianceInference = true;
10545
+ }
10430
10546
  // Make sure there's at most one variadic type parameter.
10431
10547
  const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
10432
10548
  if (variadics.length > 1) {
@@ -10456,7 +10572,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10456
10572
  const initMethod = classType.details.fields.get('__init__');
10457
10573
  if (initMethod) {
10458
10574
  const initDecls = initMethod.getTypedDeclarations();
10459
- if (initDecls.length === 1 && initDecls[0].type === 3 /* Function */) {
10575
+ if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
10460
10576
  const initDeclNode = initDecls[0].node;
10461
10577
  const initParams = initDeclNode.parameters;
10462
10578
  if (initParams.length > 1 &&
@@ -10619,6 +10735,79 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10619
10735
  }
10620
10736
  return { classType, decoratedType };
10621
10737
  }
10738
+ function inferTypeParameterVarianceForClass(classType) {
10739
+ if (!classType.details.requiresVarianceInference) {
10740
+ return;
10741
+ }
10742
+ if (!objectType || !(0, types_1.isClassInstance)(objectType)) {
10743
+ return;
10744
+ }
10745
+ // Replace all of the type parameters with invariant TypeVars.
10746
+ const updatedTypeParams = classType.details.typeParameters.map((typeParam) => types_1.TypeVarType.cloneAsInvariant(typeParam));
10747
+ const updatedClassType = types_1.ClassType.cloneWithNewTypeParameters(classType, updatedTypeParams);
10748
+ const dummyTypeObject = types_1.ClassType.createInstantiable('__varianceDummy', '', '', '', 0, 0, undefined, undefined);
10749
+ updatedTypeParams.forEach((param, paramIndex) => {
10750
+ // Skip variadics and ParamSpecs.
10751
+ if (param.details.isVariadic || param.details.isParamSpec) {
10752
+ return;
10753
+ }
10754
+ // Skip type variables without auto-variance.
10755
+ if (param.details.declaredVariance !== 0 /* Auto */) {
10756
+ return;
10757
+ }
10758
+ // Replace all type arguments with a dummy type except for the
10759
+ // TypeVar of interest, which is replaced with an object instance.
10760
+ const srcTypeArgs = updatedTypeParams.map((p, i) => {
10761
+ if (p.details.isVariadic) {
10762
+ return p;
10763
+ }
10764
+ return i === paramIndex ? objectType : dummyTypeObject;
10765
+ });
10766
+ // Replace all type arguments with a dummy type except for the
10767
+ // TypeVar of interest, which is replaced with itself.
10768
+ const destTypeArgs = updatedTypeParams.map((p, i) => {
10769
+ return i === paramIndex || p.details.isVariadic ? p : dummyTypeObject;
10770
+ });
10771
+ const srcType = types_1.ClassType.cloneForSpecialization(updatedClassType, srcTypeArgs,
10772
+ /* isTypeArgumentExplicit */ true);
10773
+ const destType = types_1.ClassType.cloneForSpecialization(updatedClassType, destTypeArgs,
10774
+ /* isTypeArgumentExplicit */ true);
10775
+ const isDestSubtypeOfSrc = assignClassToSelf(srcType, destType);
10776
+ let inferredVariance;
10777
+ if (isDestSubtypeOfSrc) {
10778
+ inferredVariance = 2 /* Covariant */;
10779
+ }
10780
+ else {
10781
+ const isSrcSubtypeOfDest = assignClassToSelf(destType, srcType);
10782
+ if (isSrcSubtypeOfDest) {
10783
+ inferredVariance = 3 /* Contravariant */;
10784
+ }
10785
+ else {
10786
+ inferredVariance = 1 /* Invariant */;
10787
+ }
10788
+ }
10789
+ // We assume here that we don't need to clone the type var object
10790
+ // because it was already cloned when it was associated with this
10791
+ // class scope.
10792
+ classType.details.typeParameters[paramIndex].computedVariance = inferredVariance;
10793
+ });
10794
+ // Note that variance inference is complete.
10795
+ classType.details.requiresVarianceInference = false;
10796
+ }
10797
+ function evaluateTypeParameterList(node) {
10798
+ const paramTypes = [];
10799
+ node.parameters.forEach((param) => {
10800
+ const paramSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name);
10801
+ (0, debug_1.assert)(paramSymbol);
10802
+ const typeOfParam = getDeclaredTypeOfSymbol(paramSymbol, param.name);
10803
+ if (!typeOfParam || !(0, types_1.isTypeVar)(typeOfParam)) {
10804
+ return;
10805
+ }
10806
+ writeTypeCache(param.name, typeOfParam, 0 /* None */, /* isIncomplete */ false);
10807
+ paramTypes.push(typeOfParam);
10808
+ });
10809
+ return paramTypes;
10810
+ }
10622
10811
  function computeEffectiveMetaclass(classType, errorNode) {
10623
10812
  let effectiveMetaclass = classType.details.declaredMetaclass;
10624
10813
  let reportedMetaclassConflict = false;
@@ -10944,6 +11133,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
10944
11133
  }), node.functionAnnotationComment);
10945
11134
  }
10946
11135
  }
11136
+ if (node.typeParameters) {
11137
+ evaluateTypeParameterList(node.typeParameters);
11138
+ }
10947
11139
  const markParamAccessed = (param) => {
10948
11140
  if (param.name) {
10949
11141
  const symbolWithScope = lookUpSymbolRecursive(param.name, param.name.value, /* honorCodeFlow */ false);
@@ -11252,7 +11444,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11252
11444
  const baseClassMemberInfo = (0, typeUtils_1.lookUpClassMember)(containingClassType, methodName, 1 /* SkipOriginalClass */);
11253
11445
  if (baseClassMemberInfo) {
11254
11446
  const memberDecls = baseClassMemberInfo.symbol.getDeclarations();
11255
- if (memberDecls.length === 1 && memberDecls[0].type === 3 /* Function */) {
11447
+ if (memberDecls.length === 1 && memberDecls[0].type === 5 /* Function */) {
11256
11448
  const baseClassMethodNode = memberDecls[0].node;
11257
11449
  // Does the signature match exactly with the exception of annotations?
11258
11450
  if (baseClassMethodNode.parameters.length === functionNode.parameters.length &&
@@ -11529,14 +11721,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
11529
11721
  // to recursion if there is a large number (1000's) of overloads.
11530
11722
  for (let i = 0; i < declIndex; i++) {
11531
11723
  const decl = decls[i];
11532
- if (decl.type === 3 /* Function */) {
11724
+ if (decl.type === 5 /* Function */) {
11533
11725
  getTypeOfFunction(decl.node);
11534
11726
  }
11535
11727
  }
11536
11728
  const overloadedTypes = [];
11537
11729
  // Look at the previous declaration's type.
11538
11730
  const prevDecl = decls[declIndex - 1];
11539
- if (prevDecl.type === 3 /* Function */) {
11731
+ if (prevDecl.type === 5 /* Function */) {
11540
11732
  const prevDeclDeclTypeInfo = getTypeOfFunction(prevDecl.node);
11541
11733
  if (prevDeclDeclTypeInfo) {
11542
11734
  if ((0, types_1.isFunction)(prevDeclDeclTypeInfo.decoratedType)) {
@@ -12086,19 +12278,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12086
12278
  // case, we want to choose the last declaration.
12087
12279
  const filteredDecls = symbolWithScope.symbol
12088
12280
  .getDeclarations()
12089
- .filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 6 /* Alias */);
12281
+ .filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 8 /* Alias */);
12090
12282
  let aliasDecl = filteredDecls.length > 0 ? filteredDecls[filteredDecls.length - 1] : undefined;
12091
12283
  // If we didn't find an exact match, look for any alias associated with
12092
12284
  // this symbol. In cases where we have multiple ImportAs nodes that share
12093
12285
  // the same first-part name (e.g. "import asyncio" and "import asyncio.tasks"),
12094
12286
  // we may not find the declaration associated with this node.
12095
12287
  if (!aliasDecl) {
12096
- aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 6 /* Alias */);
12288
+ aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 8 /* Alias */);
12097
12289
  }
12098
12290
  if (!aliasDecl) {
12099
12291
  return undefined;
12100
12292
  }
12101
- (0, debug_1.assert)(aliasDecl.type === 6 /* Alias */);
12293
+ (0, debug_1.assert)(aliasDecl.type === 8 /* Alias */);
12102
12294
  const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
12103
12295
  // Try to resolve the alias while honoring external visibility.
12104
12296
  const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl,
@@ -12135,7 +12327,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12135
12327
  // expression or statement that contains it. This contextual evaluation
12136
12328
  // allows for bidirectional type evaluation.
12137
12329
  function evaluateTypesForExpressionInContext(node) {
12138
- var _a, _b, _c;
12330
+ var _a, _b, _c, _d, _e;
12139
12331
  let lastContextualExpression = node;
12140
12332
  let curNode = node;
12141
12333
  function isContextual(node) {
@@ -12204,6 +12396,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12204
12396
  getTypeOfClass(node.parent);
12205
12397
  return;
12206
12398
  }
12399
+ else if (node.parent.nodeType === 77 /* TypeAlias */ && node.parent.name === node) {
12400
+ getTypeOfTypeAlias(node.parent);
12401
+ return;
12402
+ }
12207
12403
  else if (node.parent.nodeType === 29 /* Global */ ||
12208
12404
  node.parent.nodeType === 39 /* Nonlocal */) {
12209
12405
  // For global and nonlocal statements, allow forward references so
@@ -12242,15 +12438,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12242
12438
  verifyDeleteExpression(lastContextualExpression);
12243
12439
  return;
12244
12440
  }
12441
+ // If this is the name node within a type parameter list, see if it's a type alias
12442
+ // definition. If so, we need to evaluate the type alias contextually.
12443
+ if (parent.nodeType === 75 /* TypeParameter */ && lastContextualExpression === parent.name) {
12444
+ if (((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 76 /* TypeParameterList */ &&
12445
+ ((_b = parent.parent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 77 /* TypeAlias */) {
12446
+ getTypeOfTypeAlias(parent.parent.parent);
12447
+ return;
12448
+ }
12449
+ }
12450
+ if (parent.nodeType === 75 /* TypeParameter */) {
12451
+ getTypeOfExpression(parent.name);
12452
+ return;
12453
+ }
12454
+ if (parent.nodeType === 77 /* TypeAlias */) {
12455
+ getTypeOfTypeAlias(parent);
12456
+ return;
12457
+ }
12245
12458
  if (parent.nodeType === 5 /* AugmentedAssignment */) {
12246
12459
  evaluateTypesForAugmentedAssignment(parent);
12247
12460
  return;
12248
12461
  }
12249
12462
  if (parent.nodeType === 13 /* Decorator */) {
12250
- if (((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 10 /* Class */) {
12463
+ if (((_c = parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
12251
12464
  getTypeOfClass(parent.parent);
12252
12465
  }
12253
- else if (((_b = parent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 28 /* Function */) {
12466
+ else if (((_d = parent.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 28 /* Function */) {
12254
12467
  getTypeOfFunction(parent.parent);
12255
12468
  }
12256
12469
  return;
@@ -12301,7 +12514,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12301
12514
  return;
12302
12515
  }
12303
12516
  // A class argument must be evaluated in the context of the class declaration.
12304
- if (parent.nodeType === 1 /* Argument */ && ((_c = parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
12517
+ if (parent.nodeType === 1 /* Argument */ && ((_e = parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 10 /* Class */) {
12305
12518
  getTypeOfClass(parent.parent);
12306
12519
  return;
12307
12520
  }
@@ -12397,6 +12610,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12397
12610
  }
12398
12611
  break;
12399
12612
  }
12613
+ case 77 /* TypeAlias */: {
12614
+ getTypeOfTypeAlias(curNode);
12615
+ return;
12616
+ }
12400
12617
  case 4 /* AssignmentExpression */: {
12401
12618
  getTypeOfExpression(curNode);
12402
12619
  return;
@@ -12923,10 +13140,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
12923
13140
  if (symbolWithScope && honorCodeFlow && scopeTypeHonorsCodeFlow) {
12924
13141
  // Filter the declarations based on flow reachability.
12925
13142
  const reachableDecls = symbolWithScope.symbol.getDeclarations().filter((decl) => {
12926
- if (decl.type !== 6 /* Alias */ && decl.type !== 0 /* Intrinsic */) {
13143
+ if (decl.type !== 8 /* Alias */ && decl.type !== 0 /* Intrinsic */) {
12927
13144
  // Is the declaration in the same execution scope as the "usageNode" node?
12928
13145
  const usageScope = ParseTreeUtils.getExecutionScopeNode(node);
12929
- const declNode = decl.type === 4 /* Class */ || decl.type === 3 /* Function */
13146
+ const declNode = decl.type === 6 /* Class */ ||
13147
+ decl.type === 5 /* Function */ ||
13148
+ decl.type === 4 /* TypeAlias */
12930
13149
  ? decl.node.name
12931
13150
  : decl.node;
12932
13151
  const declScope = ParseTreeUtils.getExecutionScopeNode(declNode);
@@ -13044,7 +13263,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13044
13263
  if ((0, types_1.isFunction)(type)) {
13045
13264
  if (type.details.declaration) {
13046
13265
  const functionDecl = type.details.declaration;
13047
- if (functionDecl.type === 3 /* Function */) {
13266
+ if (functionDecl.type === 5 /* Function */) {
13048
13267
  const functionNode = functionDecl.node;
13049
13268
  const functionScope = AnalyzerNodeInfo.getScope(functionNode);
13050
13269
  if (functionScope) {
@@ -13108,7 +13327,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13108
13327
  // The alias could have more decls that don't refer to this import. Filter
13109
13328
  // out the one(s) that specifically associated with this import statement.
13110
13329
  const declsForThisImport = symbolInScope.symbol.getDeclarations().filter((decl) => {
13111
- return decl.type === 6 /* Alias */ && decl.node === node.parent;
13330
+ return decl.type === 8 /* Alias */ && decl.node === node.parent;
13112
13331
  });
13113
13332
  (0, collectionUtils_1.appendArray)(declarations, (0, declarationUtils_1.getDeclarationsWithUsesLocalNameRemoved)(declsForThisImport));
13114
13333
  }
@@ -13232,9 +13451,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13232
13451
  // Determine if this node is within a quoted type annotation.
13233
13452
  const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(AnalyzerNodeInfo.getFileInfo(node)));
13234
13453
  const allowForwardReferences = isWithinTypeAnnotation || fileInfo.isStubFile;
13235
- const symbolWithScope = lookUpSymbolRecursive(node, node.value, !allowForwardReferences, isWithinTypeAnnotation);
13236
- if (symbolWithScope) {
13237
- (0, collectionUtils_1.appendArray)(declarations, symbolWithScope.symbol.getDeclarations());
13454
+ let symbol;
13455
+ const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
13456
+ if (typeParamSymbol) {
13457
+ symbol = typeParamSymbol;
13458
+ }
13459
+ else {
13460
+ const symbolWithScope = lookUpSymbolRecursive(node, node.value, !allowForwardReferences, isWithinTypeAnnotation);
13461
+ symbol = symbolWithScope === null || symbolWithScope === void 0 ? void 0 : symbolWithScope.symbol;
13462
+ }
13463
+ if (symbol) {
13464
+ (0, collectionUtils_1.appendArray)(declarations, symbol.getDeclarations());
13238
13465
  }
13239
13466
  }
13240
13467
  return declarations;
@@ -13280,17 +13507,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13280
13507
  }
13281
13508
  return types_1.UnknownType.create();
13282
13509
  }
13283
- case 4 /* Class */: {
13510
+ case 6 /* Class */: {
13284
13511
  const classTypeInfo = getTypeOfClass(declaration.node);
13285
13512
  return classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.decoratedType;
13286
13513
  }
13287
- case 5 /* SpecialBuiltInClass */: {
13514
+ case 7 /* SpecialBuiltInClass */: {
13288
13515
  return getTypeOfAnnotation(declaration.node.typeAnnotation);
13289
13516
  }
13290
- case 3 /* Function */: {
13517
+ case 5 /* Function */: {
13291
13518
  const functionTypeInfo = getTypeOfFunction(declaration.node);
13292
13519
  return functionTypeInfo === null || functionTypeInfo === void 0 ? void 0 : functionTypeInfo.decoratedType;
13293
13520
  }
13521
+ case 4 /* TypeAlias */: {
13522
+ return getTypeOfTypeAlias(declaration.node);
13523
+ }
13294
13524
  case 2 /* Parameter */: {
13295
13525
  let typeAnnotationNode = declaration.node.typeAnnotation || declaration.node.typeAnnotationComment;
13296
13526
  // If there wasn't an annotation, see if the parent function
@@ -13312,6 +13542,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13312
13542
  }
13313
13543
  return undefined;
13314
13544
  }
13545
+ case 3 /* TypeParameter */: {
13546
+ let typeVar = types_1.TypeVarType.createInstantiable(declaration.node.name.value);
13547
+ if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
13548
+ typeVar.details.isVariadic = true;
13549
+ }
13550
+ else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
13551
+ typeVar.details.isParamSpec = true;
13552
+ }
13553
+ if (declaration.node.boundExpression) {
13554
+ if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
13555
+ const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
13556
+ const constraintType = getTypeOfExpressionExpectingType(constraint).type;
13557
+ if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
13558
+ addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), constraint);
13559
+ }
13560
+ return (0, typeUtils_1.convertToInstance)(constraintType);
13561
+ });
13562
+ if (constraints.length < 2) {
13563
+ addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
13564
+ .reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
13565
+ }
13566
+ else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
13567
+ typeVar.details.constraints = constraints;
13568
+ }
13569
+ }
13570
+ else {
13571
+ const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
13572
+ if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
13573
+ addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), declaration.node.boundExpression);
13574
+ }
13575
+ if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
13576
+ typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
13577
+ }
13578
+ }
13579
+ }
13580
+ typeVar.details.isTypeParamSyntax = true;
13581
+ // Associate the type variable with the owning scope.
13582
+ const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
13583
+ if (scopeNode) {
13584
+ let scopeType;
13585
+ if (scopeNode.nodeType === 10 /* Class */) {
13586
+ scopeType = 0 /* Class */;
13587
+ // Set the variance to "auto" for class-scoped TypeVars.
13588
+ typeVar.details.declaredVariance = 0 /* Auto */;
13589
+ }
13590
+ else if (scopeNode.nodeType === 28 /* Function */) {
13591
+ scopeType = 1 /* Function */;
13592
+ }
13593
+ else {
13594
+ (0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
13595
+ scopeType = 2 /* TypeAlias */;
13596
+ }
13597
+ typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
13598
+ }
13599
+ return typeVar;
13600
+ }
13315
13601
  case 1 /* Variable */: {
13316
13602
  const typeAnnotationNode = declaration.typeAnnotationNode;
13317
13603
  if (typeAnnotationNode) {
@@ -13349,7 +13635,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13349
13635
  }
13350
13636
  return undefined;
13351
13637
  }
13352
- case 6 /* Alias */: {
13638
+ case 8 /* Alias */: {
13353
13639
  return undefined;
13354
13640
  }
13355
13641
  }
@@ -13396,11 +13682,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13396
13682
  // If the resolved declaration is still an alias, the alias
13397
13683
  // is pointing at a module, and we need to synthesize a
13398
13684
  // module type.
13399
- if (resolvedDecl.type === 6 /* Alias */) {
13685
+ if (resolvedDecl.type === 8 /* Alias */) {
13400
13686
  // Build a module type that corresponds to the declaration and
13401
13687
  // its associated loader actions.
13402
13688
  let moduleName = resolvedDecl.moduleName;
13403
- if (decl.type === 6 /* Alias */) {
13689
+ if (decl.type === 8 /* Alias */) {
13404
13690
  if (decl.symbolName) {
13405
13691
  moduleName += '.' + decl.symbolName;
13406
13692
  }
@@ -13651,7 +13937,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13651
13937
  considerDecl = false;
13652
13938
  }
13653
13939
  if (usageNode !== undefined) {
13654
- if (decl.type !== 6 /* Alias */) {
13940
+ if (decl.type !== 8 /* Alias */) {
13655
13941
  // Is the declaration in the same execution scope as the "usageNode" node?
13656
13942
  const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
13657
13943
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
@@ -13764,9 +14050,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13764
14050
  // reachable from the usage node (if specified). This can happen in
13765
14051
  // cases where a property symbol is redefined to add a setter, deleter,
13766
14052
  // etc.
13767
- if (typedDecls.length > 1 && usageNode) {
14053
+ if (usageNode && typedDecls.length > 1) {
13768
14054
  const filteredTypedDecls = typedDecls.filter((decl) => {
13769
- if (decl.type !== 6 /* Alias */) {
14055
+ if (decl.type !== 8 /* Alias */) {
13770
14056
  // Is the declaration in the same execution scope as the "usageNode" node?
13771
14057
  const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
13772
14058
  const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
@@ -13778,9 +14064,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13778
14064
  }
13779
14065
  return true;
13780
14066
  });
13781
- if (filteredTypedDecls.length > 0) {
13782
- typedDecls = filteredTypedDecls;
14067
+ if (filteredTypedDecls.length === 0) {
14068
+ return types_1.UnboundType.create();
13783
14069
  }
14070
+ typedDecls = filteredTypedDecls;
13784
14071
  }
13785
14072
  // Start with the last decl. If that's already being resolved,
13786
14073
  // use the next-to-last decl, etc. This can happen when resolving
@@ -13806,7 +14093,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
13806
14093
  // in the type cache. This exception is required to handle the
13807
14094
  // circular dependency between the "type" and "object" classes in
13808
14095
  // builtins.pyi (since "object" is a "type" and "type" is an "object").
13809
- if (popSymbolResolution(symbol) || decl.type === 4 /* Class */) {
14096
+ if (popSymbolResolution(symbol) || decl.type === 6 /* Class */) {
13810
14097
  return type;
13811
14098
  }
13812
14099
  }
@@ -14157,6 +14444,63 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14157
14444
  }));
14158
14445
  return false;
14159
14446
  }
14447
+ // This function is used to validate or infer the variance of type
14448
+ // parameters within a class.
14449
+ function assignClassToSelf(destType, srcType, recursionCount = 0) {
14450
+ (0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
14451
+ (0, debug_1.assert)(destType.details.typeParameters.length > 0);
14452
+ const diag = new diagnostic_1.DiagnosticAddendum();
14453
+ const typeVarContext = new typeVarContext_1.TypeVarContext();
14454
+ let isAssignable = true;
14455
+ destType.details.fields.forEach((symbol, name) => {
14456
+ if (isAssignable && symbol.isClassMember() && !symbol.isIgnoredForProtocolMatch()) {
14457
+ const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
14458
+ (0, debug_1.assert)(memberInfo !== undefined);
14459
+ let destMemberType = getDeclaredTypeOfSymbol(symbol);
14460
+ if (destMemberType) {
14461
+ const srcMemberType = getTypeOfMember(memberInfo);
14462
+ destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType);
14463
+ // Properties require special processing.
14464
+ if ((0, types_1.isClassInstance)(destMemberType) &&
14465
+ types_1.ClassType.isPropertyClass(destMemberType) &&
14466
+ (0, types_1.isClassInstance)(srcMemberType) &&
14467
+ types_1.ClassType.isPropertyClass(srcMemberType)) {
14468
+ if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType, diag, typeVarContext,
14469
+ /* selfTypeVarContext */ undefined, recursionCount)) {
14470
+ isAssignable = false;
14471
+ }
14472
+ }
14473
+ else {
14474
+ const primaryDecl = symbol.getDeclarations()[0];
14475
+ // Class and instance variables that are mutable need to
14476
+ // enforce invariance.
14477
+ const flags = (primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* Variable */ && !primaryDecl.isFinal
14478
+ ? 1 /* EnforceInvariance */
14479
+ : 0 /* Default */;
14480
+ if (!assignType(destMemberType, srcMemberType, diag, typeVarContext,
14481
+ /* srcTypeVarContext */ undefined, flags, recursionCount)) {
14482
+ isAssignable = false;
14483
+ }
14484
+ }
14485
+ }
14486
+ }
14487
+ });
14488
+ // Now handle generic base classes.
14489
+ destType.details.baseClasses.forEach((baseClass) => {
14490
+ if ((0, types_1.isInstantiableClass)(baseClass) &&
14491
+ !types_1.ClassType.isBuiltIn(baseClass, 'object') &&
14492
+ !types_1.ClassType.isBuiltIn(baseClass, 'Protocol') &&
14493
+ !types_1.ClassType.isBuiltIn(baseClass, 'Generic') &&
14494
+ baseClass.details.typeParameters.length > 0) {
14495
+ const specializedDestBaseClass = (0, typeUtils_1.specializeForBaseClass)(destType, baseClass);
14496
+ const specializedSrcBaseClass = (0, typeUtils_1.specializeForBaseClass)(srcType, baseClass);
14497
+ if (!assignClassToSelf(specializedDestBaseClass, specializedSrcBaseClass, recursionCount)) {
14498
+ isAssignable = false;
14499
+ }
14500
+ }
14501
+ });
14502
+ return isAssignable;
14503
+ }
14160
14504
  function assignTupleTypeArgs(destType, srcType, diag, typeVarContext, flags, recursionCount) {
14161
14505
  var _a, _b;
14162
14506
  const destTypeArgs = [...((_a = destType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [])];
@@ -14250,6 +14594,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14250
14594
  let curSrcType = srcType;
14251
14595
  let curTypeVarContext = destTypeVarContext !== null && destTypeVarContext !== void 0 ? destTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(destType));
14252
14596
  let effectiveFlags = flags;
14597
+ inferTypeParameterVarianceForClass(destType);
14253
14598
  // If we're using a private typeVarContext, don't skip solving type vars.
14254
14599
  if (!destTypeVarContext) {
14255
14600
  effectiveFlags &= ~8 /* SkipSolveTypeVars */;
@@ -14330,6 +14675,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14330
14675
  function verifyTypeArgumentsAssignable(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
14331
14676
  var _a, _b, _c;
14332
14677
  (0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
14678
+ inferTypeParameterVarianceForClass(destType);
14333
14679
  const destTypeParams = types_1.ClassType.getTypeParameters(destType);
14334
14680
  let destTypeArgs;
14335
14681
  let srcTypeArgs;
@@ -14356,7 +14702,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14356
14702
  const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
14357
14703
  const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
14358
14704
  const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
14359
- if (!destTypeParam || destTypeParam.details.variance === 1 /* Covariant */) {
14705
+ if (!destTypeParam || types_1.TypeVarType.getVariance(destTypeParam) === 2 /* Covariant */) {
14360
14706
  if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
14361
14707
  if (diag) {
14362
14708
  if (destTypeParam) {
@@ -14373,7 +14719,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
14373
14719
  return false;
14374
14720
  }
14375
14721
  }
14376
- else if (destTypeParam.details.variance === 2 /* Contravariant */) {
14722
+ else if (types_1.TypeVarType.getVariance(destTypeParam) === 3 /* Contravariant */) {
14377
14723
  if (!assignType(srcTypeArg, destTypeArg, assignmentDiag, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
14378
14724
  if (diag) {
14379
14725
  const childDiag = diag.createAddendum();
@@ -16347,7 +16693,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16347
16693
  if (symbol.isClassMember() || symbol.isNamedTupleMemberMember()) {
16348
16694
  let isAbstract;
16349
16695
  const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
16350
- if (decl && decl.type === 3 /* Function */) {
16696
+ if (decl && decl.type === 5 /* Function */) {
16351
16697
  const functionFlags = getFunctionFlagsFromDecorators(decl.node, true);
16352
16698
  isAbstract = !!(functionFlags & 8 /* AbstractMethod */);
16353
16699
  }
@@ -16623,6 +16969,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16623
16969
  assignType,
16624
16970
  validateOverrideMethod,
16625
16971
  assignTypeToExpression,
16972
+ assignClassToSelf,
16626
16973
  getTypedDictClassType,
16627
16974
  getTupleClassType,
16628
16975
  getObjectType,
@@ -16630,6 +16977,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
16630
16977
  getTypingType,
16631
16978
  verifyTypeArgumentsAssignable,
16632
16979
  inferReturnTypeIfNecessary,
16980
+ inferTypeParameterVarianceForClass,
16633
16981
  addError,
16634
16982
  addWarning,
16635
16983
  addInformation,