@zzzen/pyright-internal 1.2.0-beta → 1.2.0-dev.20220710
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.
- package/README.md +82 -1
- package/dist/analyzer/aliasDeclarationUtils.js +2 -2
- package/dist/analyzer/analyzerFileInfo.d.ts +2 -1
- package/dist/analyzer/analyzerFileInfo.js.map +1 -1
- package/dist/analyzer/analyzerNodeInfo.d.ts +4 -1
- package/dist/analyzer/analyzerNodeInfo.js +12 -1
- package/dist/analyzer/analyzerNodeInfo.js.map +1 -1
- package/dist/analyzer/binder.d.ts +6 -1
- package/dist/analyzer/binder.js +134 -31
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +4 -1
- package/dist/analyzer/checker.js +129 -48
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +6 -1
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +8 -5
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/declaration.d.ts +18 -6
- package/dist/analyzer/declaration.js +19 -9
- package/dist/analyzer/declaration.js.map +1 -1
- package/dist/analyzer/declarationUtils.d.ts +1 -1
- package/dist/analyzer/declarationUtils.js +19 -16
- package/dist/analyzer/declarationUtils.js.map +1 -1
- package/dist/analyzer/functionTransform.js +2 -1
- package/dist/analyzer/functionTransform.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +6 -6
- package/dist/analyzer/parseTreeUtils.d.ts +3 -3
- package/dist/analyzer/parseTreeUtils.js +28 -18
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/parseTreeWalker.d.ts +4 -1
- package/dist/analyzer/parseTreeWalker.js +19 -1
- package/dist/analyzer/parseTreeWalker.js.map +1 -1
- package/dist/analyzer/patternMatching.js +1 -1
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.d.ts +2 -2
- package/dist/analyzer/program.js +1 -1
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.js +2 -0
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +0 -1
- package/dist/analyzer/protocols.js +1 -63
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -2
- package/dist/analyzer/service.js +3 -2
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +6 -1
- package/dist/analyzer/sourceFile.js +17 -5
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/tracePrinter.js +8 -4
- package/dist/analyzer/tracePrinter.js.map +1 -1
- package/dist/analyzer/typeDocStringUtils.js +1 -1
- package/dist/analyzer/typeEvaluator.js +692 -293
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +5 -3
- package/dist/analyzer/typeEvaluatorWithTracker.js +2 -0
- package/dist/analyzer/typeEvaluatorWithTracker.js.map +1 -1
- package/dist/analyzer/typeGuards.js +5 -0
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +4 -1
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeStubWriter.d.ts +4 -1
- package/dist/analyzer/typeStubWriter.js +36 -0
- package/dist/analyzer/typeStubWriter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +1 -1
- package/dist/analyzer/typeUtils.js +14 -9
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.js +3 -1
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +13 -5
- package/dist/analyzer/types.js +34 -11
- package/dist/analyzer/types.js.map +1 -1
- package/dist/languageServerBase.d.ts +3 -2
- package/dist/languageServerBase.js +3 -2
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/autoImporter.js +1 -1
- package/dist/languageService/callHierarchyProvider.js +9 -9
- package/dist/languageService/completionProvider.js +19 -13
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/definitionProvider.js +3 -3
- package/dist/languageService/documentSymbolCollector.js +1 -1
- package/dist/languageService/documentSymbolProvider.js +10 -7
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.js +19 -5
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/indentationUtils.js +3 -2
- package/dist/languageService/indentationUtils.js.map +1 -1
- package/dist/languageService/insertionPointUtils.d.ts +9 -0
- package/dist/languageService/insertionPointUtils.js +110 -0
- package/dist/languageService/insertionPointUtils.js.map +1 -0
- package/dist/languageService/referencesProvider.js +8 -5
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/signatureHelpProvider.js +4 -2
- package/dist/languageService/signatureHelpProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +1 -1
- package/dist/localization/localize.d.ts +27 -0
- package/dist/localization/localize.js +16 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +18 -2
- package/dist/parser/parseNodes.d.ts +41 -5
- package/dist/parser/parseNodes.js +83 -4
- package/dist/parser/parseNodes.js.map +1 -1
- package/dist/parser/parser.d.ts +5 -1
- package/dist/parser/parser.js +131 -13
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +2 -1
- package/dist/parser/tokenizer.js +7 -5
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/parser/tokenizerTypes.d.ts +5 -3
- package/dist/parser/tokenizerTypes.js +6 -4
- package/dist/parser/tokenizerTypes.js.map +1 -1
- package/dist/tests/chainedSourceFiles.test.js +2 -1
- package/dist/tests/chainedSourceFiles.test.js.map +1 -1
- package/dist/tests/fourslash/import.multipart.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/import.multipart.fourslash.js +18 -0
- package/dist/tests/fourslash/import.multipart.fourslash.js.map +1 -0
- package/dist/tests/fourslash/signature.simple.fourslash.js +16 -0
- package/dist/tests/fourslash/signature.simple.fourslash.js.map +1 -1
- package/dist/tests/insertionPointUtils.test.d.ts +1 -0
- package/dist/tests/insertionPointUtils.test.js +74 -0
- package/dist/tests/insertionPointUtils.test.js.map +1 -0
- package/dist/tests/testUtils.js +2 -1
- package/dist/tests/testUtils.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +8 -0
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +10 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.d.ts +1 -0
- package/dist/tests/typeEvaluator5.test.js +118 -0
- package/dist/tests/typeEvaluator5.test.js.map +1 -0
- package/package.json +3 -2
@@ -660,15 +660,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
660
660
|
typeResult.type.details.illegalRecursionDetected = true;
|
661
661
|
}
|
662
662
|
}
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
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--;
|
@@ -920,7 +915,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
920
915
|
const argList = [
|
921
916
|
{
|
922
917
|
argumentCategory: 0 /* Simple */,
|
923
|
-
type: functionOrClassType,
|
918
|
+
typeResult: { type: functionOrClassType },
|
924
919
|
},
|
925
920
|
];
|
926
921
|
const returnType = validateCallArguments(node.expression, argList, decoratorTypeResult,
|
@@ -1235,7 +1230,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1235
1230
|
function addFakeArg() {
|
1236
1231
|
argList.push({
|
1237
1232
|
argumentCategory: previousCategory,
|
1238
|
-
type: types_1.UnknownType.create(),
|
1233
|
+
typeResult: { type: types_1.UnknownType.create() },
|
1239
1234
|
active: true,
|
1240
1235
|
});
|
1241
1236
|
}
|
@@ -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
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
|
2569
|
-
|
2570
|
-
|
2571
|
-
|
2572
|
-
|
2573
|
-
|
2574
|
-
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2578
|
-
|
2579
|
-
|
2580
|
-
|
2581
|
-
|
2582
|
-
|
2583
|
-
|
2584
|
-
|
2585
|
-
|
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 (
|
2604
|
-
|
2605
|
-
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
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
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
2623
|
-
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
2627
|
-
|
2628
|
-
|
2629
|
-
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2633
|
-
|
2634
|
-
|
2635
|
-
|
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
|
-
|
2648
|
-
|
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 = ((
|
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
|
-
|
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
|
2903
|
+
let typeParametersForScope;
|
2904
|
+
let scopeUsesTypeParameterSyntax = false;
|
2883
2905
|
if (curNode.nodeType === 10 /* Class */) {
|
2884
2906
|
const classTypeInfo = getTypeOfClass(curNode);
|
2885
|
-
if (classTypeInfo) {
|
2886
|
-
|
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
|
-
|
2916
|
+
typeParametersForScope = [];
|
2894
2917
|
functionTypeInfo.functionType.details.parameters.forEach((param) => {
|
2895
2918
|
if (param.hasDeclaredType) {
|
2896
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(
|
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)(
|
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 ===
|
2905
|
-
|
2928
|
+
else if (curNode.nodeType === 77 /* TypeAlias */) {
|
2929
|
+
scopeUsesTypeParameterSyntax = !!curNode.typeParameters;
|
2906
2930
|
}
|
2907
|
-
if (
|
2908
|
-
const match =
|
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
|
-
|
2921
|
-
|
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,
|
@@ -3530,25 +3569,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3530
3569
|
{
|
3531
3570
|
// Provide "obj" argument.
|
3532
3571
|
argumentCategory: 0 /* Simple */,
|
3533
|
-
|
3534
|
-
|
3535
|
-
|
3536
|
-
|
3537
|
-
|
3572
|
+
typeResult: {
|
3573
|
+
type: types_1.ClassType.isClassProperty(lookupClass)
|
3574
|
+
? baseTypeClass
|
3575
|
+
: isAccessedThroughObject
|
3576
|
+
? bindToType || types_1.ClassType.cloneAsInstance(baseTypeClass)
|
3577
|
+
: types_1.NoneType.createInstance(),
|
3578
|
+
},
|
3538
3579
|
},
|
3539
3580
|
];
|
3540
3581
|
if (usage.method === 'get') {
|
3541
3582
|
// Provide "objtype" argument.
|
3542
3583
|
argList.push({
|
3543
3584
|
argumentCategory: 0 /* Simple */,
|
3544
|
-
type: baseTypeClass,
|
3585
|
+
typeResult: { type: baseTypeClass },
|
3545
3586
|
});
|
3546
3587
|
}
|
3547
3588
|
else if (usage.method === 'set') {
|
3548
3589
|
// Provide "value" argument.
|
3549
3590
|
argList.push({
|
3550
3591
|
argumentCategory: 0 /* Simple */,
|
3551
|
-
type: (_a = usage.setType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create(),
|
3592
|
+
typeResult: { type: (_a = usage.setType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create() },
|
3552
3593
|
});
|
3553
3594
|
}
|
3554
3595
|
if (types_1.ClassType.isPropertyClass(lookupClass) &&
|
@@ -3782,55 +3823,57 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3782
3823
|
}
|
3783
3824
|
// Applies the __getattr__, __setattr__ or __delattr__ method if present.
|
3784
3825
|
function applyAttributeAccessOverride(classType, errorNode, usage, memberName) {
|
3785
|
-
var _a, _b, _c
|
3786
|
-
|
3826
|
+
var _a, _b, _c;
|
3827
|
+
const getAttributeAccessMember = (name) => {
|
3828
|
+
var _a;
|
3787
3829
|
// See if the class has a "__getattribute__" or "__getattr__" method.
|
3788
3830
|
// If so, arbitrary members are supported.
|
3789
|
-
|
3831
|
+
return (_a = getTypeOfClassMember(errorNode, classType, name, { method: 'get' },
|
3790
3832
|
/* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
3791
|
-
|
3792
|
-
|
3793
|
-
|
3794
|
-
|
3795
|
-
// If it's an overload, it might be based on the member name. Create
|
3796
|
-
// a literal str type based on the member name and find the best overload.
|
3797
|
-
if (getAttrType && (0, types_1.isOverloadedFunction)(getAttrType)) {
|
3798
|
-
let nameLiteralType = types_1.AnyType.create();
|
3799
|
-
if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
|
3800
|
-
nameLiteralType = types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName);
|
3801
|
-
}
|
3802
|
-
getAttrType = getBestOverloadForArguments(errorNode, getAttrType, [
|
3803
|
-
{
|
3804
|
-
argumentCategory: 0 /* Simple */,
|
3805
|
-
type: types_1.AnyType.create(),
|
3806
|
-
},
|
3807
|
-
{
|
3808
|
-
argumentCategory: 0 /* Simple */,
|
3809
|
-
type: nameLiteralType,
|
3810
|
-
},
|
3811
|
-
]);
|
3812
|
-
}
|
3813
|
-
if (getAttrType && (0, types_1.isFunction)(getAttrType)) {
|
3814
|
-
return getFunctionEffectiveReturnType(getAttrType);
|
3815
|
-
}
|
3833
|
+
};
|
3834
|
+
let accessMemberType;
|
3835
|
+
if (usage.method === 'get') {
|
3836
|
+
accessMemberType = (_a = getAttributeAccessMember('__getattribute__')) !== null && _a !== void 0 ? _a : getAttributeAccessMember('__getattr__');
|
3816
3837
|
}
|
3817
3838
|
else if (usage.method === 'set') {
|
3818
|
-
|
3819
|
-
/* diag */ undefined, 4 /* SkipObjectBaseClass */ | 64 /* SkipAttributeAccessOverride */)) === null || _c === void 0 ? void 0 : _c.type;
|
3820
|
-
if (setAttrType) {
|
3821
|
-
// The type doesn't matter for a set usage. We just need
|
3822
|
-
// to return a defined type.
|
3823
|
-
return types_1.AnyType.create();
|
3824
|
-
}
|
3839
|
+
accessMemberType = getAttributeAccessMember('__setattr__');
|
3825
3840
|
}
|
3826
3841
|
else {
|
3827
3842
|
(0, debug_1.assert)(usage.method === 'del');
|
3828
|
-
|
3829
|
-
|
3830
|
-
|
3831
|
-
|
3832
|
-
|
3833
|
-
|
3843
|
+
accessMemberType = getAttributeAccessMember('__delattr__');
|
3844
|
+
}
|
3845
|
+
if (accessMemberType) {
|
3846
|
+
let nameLiteralType = types_1.AnyType.create();
|
3847
|
+
if (strClassType && (0, types_1.isInstantiableClass)(strClassType)) {
|
3848
|
+
nameLiteralType = types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName);
|
3849
|
+
}
|
3850
|
+
const argList = [
|
3851
|
+
{
|
3852
|
+
// Provide "self" argument.
|
3853
|
+
argumentCategory: 0 /* Simple */,
|
3854
|
+
typeResult: { type: types_1.ClassType.cloneAsInstance(classType) },
|
3855
|
+
},
|
3856
|
+
{
|
3857
|
+
// Provide "name" argument.
|
3858
|
+
argumentCategory: 0 /* Simple */,
|
3859
|
+
typeResult: { type: nameLiteralType },
|
3860
|
+
},
|
3861
|
+
];
|
3862
|
+
if (usage.method === 'set') {
|
3863
|
+
argList.push({
|
3864
|
+
// Provide "value" argument.
|
3865
|
+
argumentCategory: 0 /* Simple */,
|
3866
|
+
typeResult: { type: (_b = usage.setType) !== null && _b !== void 0 ? _b : types_1.UnknownType.create() },
|
3867
|
+
});
|
3868
|
+
}
|
3869
|
+
if ((0, types_1.isFunction)(accessMemberType) || (0, types_1.isOverloadedFunction)(accessMemberType)) {
|
3870
|
+
const boundMethodType = bindFunctionToClassOrObject(classType, accessMemberType, classType, errorNode);
|
3871
|
+
if (boundMethodType && ((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
|
3872
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
|
3873
|
+
const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
|
3874
|
+
/* skipUnknownArgCheck */ true);
|
3875
|
+
return (_c = callResult.returnType) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
|
3876
|
+
}
|
3834
3877
|
}
|
3835
3878
|
}
|
3836
3879
|
return undefined;
|
@@ -4130,7 +4173,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4130
4173
|
}
|
4131
4174
|
if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
|
4132
4175
|
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,
|
4176
|
+
const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
|
4134
4177
|
return { type, node };
|
4135
4178
|
}
|
4136
4179
|
let isIncomplete = false;
|
@@ -4369,9 +4412,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4369
4412
|
const keywordArgs = node.items.filter((item) => item.argumentCategory === 0 /* Simple */ && !!item.name);
|
4370
4413
|
const unpackedDictArgs = node.items.filter((item) => item.argumentCategory === 2 /* UnpackedDictionary */);
|
4371
4414
|
let positionalIndexType;
|
4415
|
+
let isPositionalIndexTypeIncomplete = false;
|
4372
4416
|
if (positionalArgs.length === 1 && unpackedListArgs.length === 0 && !node.trailingComma) {
|
4373
4417
|
// Handle the common case where there is a single positional argument.
|
4374
|
-
|
4418
|
+
const typeResult = getTypeOfExpression(positionalArgs[0].valueExpression);
|
4419
|
+
positionalIndexType = typeResult.type;
|
4420
|
+
if (typeResult.isIncomplete) {
|
4421
|
+
isPositionalIndexTypeIncomplete = true;
|
4422
|
+
}
|
4375
4423
|
}
|
4376
4424
|
else if (positionalArgs.length === 0 && unpackedListArgs.length === 0) {
|
4377
4425
|
// Handle the case where there are no positionals provided but there are keywords.
|
@@ -4384,10 +4432,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4384
4432
|
// Package up all of the positionals into a tuple.
|
4385
4433
|
const tupleEntries = [];
|
4386
4434
|
positionalArgs.forEach((arg) => {
|
4387
|
-
|
4435
|
+
const typeResult = getTypeOfExpression(arg.valueExpression);
|
4436
|
+
tupleEntries.push(typeResult.type);
|
4437
|
+
if (typeResult.isIncomplete) {
|
4438
|
+
isPositionalIndexTypeIncomplete = true;
|
4439
|
+
}
|
4388
4440
|
});
|
4389
4441
|
unpackedListArgs.forEach((arg) => {
|
4390
|
-
const
|
4442
|
+
const typeResult = getTypeOfExpression(arg.valueExpression);
|
4443
|
+
const exprType = typeResult.type;
|
4444
|
+
if (typeResult.isIncomplete) {
|
4445
|
+
isPositionalIndexTypeIncomplete = true;
|
4446
|
+
}
|
4391
4447
|
const iterableType = getTypeOfIterator(exprType, /* isAsync */ false, arg) || types_1.UnknownType.create();
|
4392
4448
|
tupleEntries.push(iterableType);
|
4393
4449
|
});
|
@@ -4396,7 +4452,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4396
4452
|
let argList = [
|
4397
4453
|
{
|
4398
4454
|
argumentCategory: 0 /* Simple */,
|
4399
|
-
type: positionalIndexType,
|
4455
|
+
typeResult: { type: positionalIndexType, isIncomplete: isPositionalIndexTypeIncomplete },
|
4400
4456
|
},
|
4401
4457
|
];
|
4402
4458
|
if (usage.method === 'set') {
|
@@ -4408,7 +4464,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4408
4464
|
}
|
4409
4465
|
argList.push({
|
4410
4466
|
argumentCategory: 0 /* Simple */,
|
4411
|
-
type: setType,
|
4467
|
+
typeResult: { type: setType, isIncomplete: isPositionalIndexTypeIncomplete },
|
4412
4468
|
});
|
4413
4469
|
}
|
4414
4470
|
keywordArgs.forEach((arg) => {
|
@@ -4430,29 +4486,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4430
4486
|
// Speculatively attempt the call. We may need to replace the index
|
4431
4487
|
// type with 'int', and we don't want to emit errors before we know
|
4432
4488
|
// which type to use.
|
4433
|
-
|
4434
|
-
|
4435
|
-
|
4436
|
-
|
4437
|
-
|
4438
|
-
|
4439
|
-
|
4440
|
-
|
4441
|
-
|
4442
|
-
|
4443
|
-
|
4444
|
-
|
4445
|
-
|
4489
|
+
if (keywordArgs.length === 0 && unpackedDictArgs.length === 0 && positionalArgs.length === 1) {
|
4490
|
+
useSpeculativeMode(node, () => {
|
4491
|
+
callResult = validateCallArguments(node, argList, { type: itemMethodType });
|
4492
|
+
if (callResult.argumentErrors) {
|
4493
|
+
// If the object supports "__index__" magic method, convert
|
4494
|
+
// the index to an int and try again.
|
4495
|
+
if ((0, types_1.isClassInstance)(positionalIndexType)) {
|
4496
|
+
const altArgList = [...argList];
|
4497
|
+
altArgList[0] = { ...altArgList[0] };
|
4498
|
+
const indexMethod = getTypeOfObjectMember(node, positionalIndexType, '__index__');
|
4499
|
+
if (indexMethod) {
|
4500
|
+
const intType = getBuiltInObject(node, 'int');
|
4501
|
+
if ((0, types_1.isClassInstance)(intType)) {
|
4502
|
+
altArgList[0].typeResult = { type: intType };
|
4503
|
+
}
|
4504
|
+
}
|
4505
|
+
callResult = validateCallArguments(node, altArgList, { type: itemMethodType });
|
4506
|
+
// We were successful, so replace the arg list.
|
4507
|
+
if (!callResult.argumentErrors) {
|
4508
|
+
argList = altArgList;
|
4446
4509
|
}
|
4447
|
-
}
|
4448
|
-
callResult = validateCallArguments(node, altArgList, { type: itemMethodType });
|
4449
|
-
// We were successful, so replace the arg list.
|
4450
|
-
if (!callResult.argumentErrors) {
|
4451
|
-
argList = altArgList;
|
4452
4510
|
}
|
4453
4511
|
}
|
4454
|
-
}
|
4455
|
-
}
|
4512
|
+
});
|
4513
|
+
}
|
4456
4514
|
callResult = validateCallArguments(node, argList, { type: itemMethodType });
|
4457
4515
|
return {
|
4458
4516
|
node,
|
@@ -5262,8 +5320,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5262
5320
|
// the expectedType. We'll use this to determine whether we need to do
|
5263
5321
|
// union expansion.
|
5264
5322
|
contextFreeArgTypes = argList.map((arg) => {
|
5265
|
-
if (arg.
|
5266
|
-
return arg.type;
|
5323
|
+
if (arg.typeResult) {
|
5324
|
+
return arg.typeResult.type;
|
5267
5325
|
}
|
5268
5326
|
if (arg.valueExpression) {
|
5269
5327
|
const valueExpressionNode = arg.valueExpression;
|
@@ -5673,6 +5731,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5673
5731
|
return (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList,
|
5674
5732
|
/* includesTypes */ false);
|
5675
5733
|
}
|
5734
|
+
// Handle the NewType specially, replacing the normal return type.
|
5735
|
+
if (expandedSubtype.details.builtInName === 'NewType') {
|
5736
|
+
return createNewType(errorNode, argList);
|
5737
|
+
}
|
5676
5738
|
let effectiveTypeVarContext = typeVarContext;
|
5677
5739
|
if (!effectiveTypeVarContext) {
|
5678
5740
|
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
@@ -5709,10 +5771,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5709
5771
|
argumentErrors = true;
|
5710
5772
|
}
|
5711
5773
|
}
|
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
5774
|
if (expandedSubtype.details.builtInName === '__import__') {
|
5717
5775
|
// For the special __import__ type, we'll override the return type to be "Any".
|
5718
5776
|
// This is required because we don't know what module was imported, and we don't
|
@@ -6165,7 +6223,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6165
6223
|
const funcArg = listElementType
|
6166
6224
|
? {
|
6167
6225
|
argumentCategory: 0 /* Simple */,
|
6168
|
-
type: listElementType,
|
6226
|
+
typeResult: { type: listElementType, isIncomplete: argTypeResult.isIncomplete },
|
6169
6227
|
}
|
6170
6228
|
: undefined;
|
6171
6229
|
if (funcArg && argTypeResult.isIncomplete) {
|
@@ -6330,7 +6388,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6330
6388
|
requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
|
6331
6389
|
argument: {
|
6332
6390
|
argumentCategory: 0 /* Simple */,
|
6333
|
-
type: entry.valueType,
|
6391
|
+
typeResult: { type: entry.valueType },
|
6334
6392
|
},
|
6335
6393
|
errorNode: argList[argIndex].valueExpression || errorNode,
|
6336
6394
|
paramName: name,
|
@@ -6345,7 +6403,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6345
6403
|
requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
|
6346
6404
|
argument: {
|
6347
6405
|
argumentCategory: 0 /* Simple */,
|
6348
|
-
type: entry.valueType,
|
6406
|
+
typeResult: { type: entry.valueType },
|
6349
6407
|
},
|
6350
6408
|
errorNode: argList[argIndex].valueExpression || errorNode,
|
6351
6409
|
paramName: name,
|
@@ -6535,7 +6593,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6535
6593
|
requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
|
6536
6594
|
argument: {
|
6537
6595
|
argumentCategory: 0 /* Simple */,
|
6538
|
-
type: unpackedDictionaryArgType,
|
6596
|
+
typeResult: { type: unpackedDictionaryArgType },
|
6539
6597
|
},
|
6540
6598
|
errorNode: (_b = (_a = argList.find((arg) => arg.argumentCategory === 2 /* UnpackedDictionary */)) === null || _a === void 0 ? void 0 : _a.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
|
6541
6599
|
paramName: param.name,
|
@@ -6582,7 +6640,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6582
6640
|
requiresTypeVarMatching: true,
|
6583
6641
|
argument: {
|
6584
6642
|
argumentCategory: 0 /* Simple */,
|
6585
|
-
type: defaultArgType,
|
6643
|
+
typeResult: { type: defaultArgType },
|
6586
6644
|
},
|
6587
6645
|
errorNode: errorNode,
|
6588
6646
|
paramName: param.name,
|
@@ -6636,7 +6694,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6636
6694
|
paramCategory: 1 /* VarArgList */,
|
6637
6695
|
paramType,
|
6638
6696
|
requiresTypeVarMatching: true,
|
6639
|
-
argument: {
|
6697
|
+
argument: {
|
6698
|
+
argumentCategory: 0 /* Simple */,
|
6699
|
+
typeResult: { type: specializedTuple },
|
6700
|
+
},
|
6640
6701
|
errorNode,
|
6641
6702
|
paramName: paramDetails.params[paramDetails.argsIndex].param.name,
|
6642
6703
|
isParamNameSynthesized: paramDetails.params[paramDetails.argsIndex].param.isNameSynthesized,
|
@@ -6881,7 +6942,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6881
6942
|
// scope.
|
6882
6943
|
let eliminateUnsolvedInUnions = true;
|
6883
6944
|
let curNode = errorNode;
|
6884
|
-
while (
|
6945
|
+
while (curNode) {
|
6885
6946
|
const typeVarScopeNode = ParseTreeUtils.getTypeVarScopeNode(curNode);
|
6886
6947
|
if (!typeVarScopeNode) {
|
6887
6948
|
break;
|
@@ -6890,7 +6951,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6890
6951
|
if (typeVarContext.hasSolveForScope(typeVarScopeId)) {
|
6891
6952
|
eliminateUnsolvedInUnions = false;
|
6892
6953
|
}
|
6893
|
-
curNode = typeVarScopeNode;
|
6954
|
+
curNode = typeVarScopeNode.parent;
|
6894
6955
|
}
|
6895
6956
|
// If the function is returning a callable, don't eliminate unsolved
|
6896
6957
|
// type vars within a union. There are legit uses for unsolved type vars
|
@@ -7138,7 +7199,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7138
7199
|
if (argParam.argType) {
|
7139
7200
|
argType = argParam.argType;
|
7140
7201
|
}
|
7141
|
-
else if (argParam.expectingType && !argParam.argument.
|
7202
|
+
else if (argParam.expectingType && !argParam.argument.typeResult && argParam.argument.valueExpression) {
|
7142
7203
|
const argTypeResult = getTypeOfExpression(argParam.argument.valueExpression, 8 /* EvaluateStringLiteralAsType */ |
|
7143
7204
|
32 /* ParamSpecDisallowed */ |
|
7144
7205
|
128 /* TypeVarTupleDisallowed */);
|
@@ -7317,7 +7378,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7317
7378
|
return { isCompatible, argType, isTypeIncomplete, condition };
|
7318
7379
|
}
|
7319
7380
|
function createTypeVarType(errorNode, argList) {
|
7320
|
-
var _a, _b, _c;
|
7381
|
+
var _a, _b, _c, _d, _e;
|
7321
7382
|
let typeVarName = '';
|
7322
7383
|
let firstConstraintArg;
|
7323
7384
|
if (argList.length === 0) {
|
@@ -7346,7 +7407,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7346
7407
|
addError(localize_1.Localizer.Diagnostic.typeVarBoundAndConstrained(), argList[i].valueExpression || errorNode);
|
7347
7408
|
}
|
7348
7409
|
else {
|
7349
|
-
const argType = (_a = argList[i].type) !== null &&
|
7410
|
+
const argType = (_b = (_a = argList[i].typeResult) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : getTypeOfExpressionExpectingType(argList[i].valueExpression,
|
7350
7411
|
/* allowFinal */ undefined,
|
7351
7412
|
/* allowRequired */ undefined).type;
|
7352
7413
|
if ((0, typeUtils_1.requiresSpecialization)(argType, /* ignorePseudoGeneric */ true)) {
|
@@ -7357,26 +7418,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7357
7418
|
}
|
7358
7419
|
else if (paramName === 'covariant') {
|
7359
7420
|
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
7360
|
-
if (typeVar.details.
|
7421
|
+
if (typeVar.details.declaredVariance === 4 /* Contravariant */) {
|
7361
7422
|
addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
|
7362
7423
|
}
|
7363
7424
|
else {
|
7364
|
-
typeVar.details.
|
7425
|
+
typeVar.details.declaredVariance = 3 /* Covariant */;
|
7365
7426
|
}
|
7366
7427
|
}
|
7367
7428
|
}
|
7368
7429
|
else if (paramName === 'contravariant') {
|
7369
7430
|
if (argList[i].valueExpression && getBooleanValue(argList[i].valueExpression)) {
|
7370
|
-
if (typeVar.details.
|
7431
|
+
if (typeVar.details.declaredVariance === 3 /* Covariant */) {
|
7371
7432
|
addError(localize_1.Localizer.Diagnostic.typeVarVariance(), argList[i].valueExpression);
|
7372
7433
|
}
|
7373
7434
|
else {
|
7374
|
-
typeVar.details.
|
7435
|
+
typeVar.details.declaredVariance = 4 /* Contravariant */;
|
7375
7436
|
}
|
7376
7437
|
}
|
7377
7438
|
}
|
7378
7439
|
else {
|
7379
|
-
addError(localize_1.Localizer.Diagnostic.typeVarUnknownParam().format({ name: paramName }), ((
|
7440
|
+
addError(localize_1.Localizer.Diagnostic.typeVarUnknownParam().format({ name: paramName }), ((_c = argList[i].node) === null || _c === void 0 ? void 0 : _c.name) || argList[i].valueExpression || errorNode);
|
7380
7441
|
}
|
7381
7442
|
paramNameMap.set(paramName, paramName);
|
7382
7443
|
}
|
@@ -7385,7 +7446,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7385
7446
|
addError(localize_1.Localizer.Diagnostic.typeVarBoundAndConstrained(), argList[i].valueExpression || errorNode);
|
7386
7447
|
}
|
7387
7448
|
else {
|
7388
|
-
const argType = (
|
7449
|
+
const argType = (_e = (_d = argList[i].typeResult) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : getTypeOfExpressionExpectingType(argList[i].valueExpression,
|
7389
7450
|
/* allowFinal */ undefined,
|
7390
7451
|
/* allowRequired */ undefined).type;
|
7391
7452
|
if ((0, typeUtils_1.requiresSpecialization)(argType, /* ignorePseudoGeneric */ true)) {
|
@@ -7880,7 +7941,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7880
7941
|
// incomplete because we may be evaluating types within a loop,
|
7881
7942
|
// so the literal values may change each time.
|
7882
7943
|
const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node);
|
7883
|
-
let type = validateBinaryOperation(node.operator, leftType, rightType, node, expectedType, diag, isLiteralMathAllowed);
|
7944
|
+
let type = validateBinaryOperation(node.operator, { type: leftType, isIncomplete: leftTypeResult.isIncomplete }, { type: rightType, isIncomplete: rightTypeResult.isIncomplete }, node, expectedType, diag, isLiteralMathAllowed);
|
7884
7945
|
if (!diag.isEmpty() || !type) {
|
7885
7946
|
if (!isIncomplete) {
|
7886
7947
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
@@ -7966,14 +8027,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7966
8027
|
return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
|
7967
8028
|
}
|
7968
8029
|
const magicMethodName = operatorMap[node.operator][0];
|
7969
|
-
let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [rightSubtypeUnexpanded], magicMethodName, node, expectedType);
|
8030
|
+
let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, expectedType);
|
7970
8031
|
if (!returnType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
7971
8032
|
// Try with the expanded left type.
|
7972
|
-
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [rightSubtypeUnexpanded], magicMethodName, node, expectedType);
|
8033
|
+
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, expectedType);
|
7973
8034
|
}
|
7974
8035
|
if (!returnType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
7975
8036
|
// Try with the expanded left and right type.
|
7976
|
-
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [rightSubtypeExpanded], magicMethodName, node, expectedType);
|
8037
|
+
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, expectedType);
|
7977
8038
|
}
|
7978
8039
|
if (!returnType) {
|
7979
8040
|
// If the LHS class didn't support the magic method for augmented
|
@@ -7986,7 +8047,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7986
8047
|
!rightTypeResult.isIncomplete &&
|
7987
8048
|
(0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) <
|
7988
8049
|
maxLiteralMathSubtypeCount;
|
7989
|
-
returnType = validateBinaryOperation(binaryOperator, leftSubtypeUnexpanded, rightSubtypeUnexpanded, node, expectedType, diag, isLiteralMathAllowed);
|
8050
|
+
returnType = validateBinaryOperation(binaryOperator, { type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }, { type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }, node, expectedType, diag, isLiteralMathAllowed);
|
7990
8051
|
}
|
7991
8052
|
return returnType;
|
7992
8053
|
});
|
@@ -8009,7 +8070,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8009
8070
|
assignTypeToExpression(node.destExpression, typeResult.type, !!typeResult.isIncomplete, node.rightExpression);
|
8010
8071
|
return typeResult;
|
8011
8072
|
}
|
8012
|
-
function validateBinaryOperation(operator,
|
8073
|
+
function validateBinaryOperation(operator, leftTypeResult, rightTypeResult, errorNode, expectedType, diag, isLiteralMathAllowed) {
|
8074
|
+
const leftType = leftTypeResult.type;
|
8075
|
+
const rightType = rightTypeResult.type;
|
8013
8076
|
let type;
|
8014
8077
|
let concreteLeftType = makeTopLevelTypeVarsConcrete(leftType);
|
8015
8078
|
if (booleanOperatorMap[operator] !== undefined) {
|
@@ -8059,7 +8122,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8059
8122
|
if ((0, types_1.isAnyOrUnknown)(leftSubtype) || (0, types_1.isAnyOrUnknown)(rightSubtypeUnexpanded)) {
|
8060
8123
|
return (0, typeUtils_1.preserveUnknown)(leftSubtype, rightSubtypeExpanded);
|
8061
8124
|
}
|
8062
|
-
let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [leftSubtype], '__contains__', errorNode,
|
8125
|
+
let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], '__contains__', errorNode,
|
8063
8126
|
/* expectedType */ undefined);
|
8064
8127
|
if (!returnType) {
|
8065
8128
|
// If __contains__ was not supported, fall back
|
@@ -8216,26 +8279,31 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8216
8279
|
]));
|
8217
8280
|
}
|
8218
8281
|
const magicMethodName = binaryOperatorMap[operator][0];
|
8219
|
-
let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [rightSubtypeUnexpanded], magicMethodName, errorNode, expectedType);
|
8282
|
+
let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, expectedType);
|
8220
8283
|
if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
8221
8284
|
// Try the expanded left type.
|
8222
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [rightSubtypeUnexpanded], magicMethodName, errorNode, expectedType);
|
8285
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, expectedType);
|
8223
8286
|
}
|
8224
8287
|
if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
8225
8288
|
// Try the expanded left and right type.
|
8226
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [rightSubtypeExpanded], magicMethodName, errorNode, expectedType);
|
8289
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, expectedType);
|
8227
8290
|
}
|
8228
8291
|
if (!resultType) {
|
8229
8292
|
// Try the alternate form (swapping right and left).
|
8230
8293
|
const altMagicMethodName = binaryOperatorMap[operator][1];
|
8231
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [leftSubtypeUnexpanded], altMagicMethodName, errorNode, expectedType);
|
8294
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, expectedType);
|
8232
8295
|
if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
8233
8296
|
// Try the expanded right type.
|
8234
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [
|
8297
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [
|
8298
|
+
{
|
8299
|
+
type: leftSubtypeUnexpanded,
|
8300
|
+
isIncomplete: leftTypeResult.isIncomplete,
|
8301
|
+
},
|
8302
|
+
], altMagicMethodName, errorNode, expectedType);
|
8235
8303
|
}
|
8236
8304
|
if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
8237
8305
|
// Try the expanded right and left type.
|
8238
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [leftSubtypeExpanded], altMagicMethodName, errorNode, expectedType);
|
8306
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, expectedType);
|
8239
8307
|
}
|
8240
8308
|
}
|
8241
8309
|
if (!resultType) {
|
@@ -8283,7 +8351,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8283
8351
|
const functionArgs = args.map((arg) => {
|
8284
8352
|
return {
|
8285
8353
|
argumentCategory: 0 /* Simple */,
|
8286
|
-
|
8354
|
+
typeResult: arg,
|
8287
8355
|
};
|
8288
8356
|
});
|
8289
8357
|
let callResult;
|
@@ -9079,15 +9147,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9079
9147
|
return { type, node, isIncomplete };
|
9080
9148
|
}
|
9081
9149
|
function getTypeOfSlice(node) {
|
9082
|
-
// Evaluate the expressions to report errors and record symbol
|
9083
|
-
if
|
9084
|
-
|
9085
|
-
|
9086
|
-
|
9087
|
-
|
9088
|
-
|
9089
|
-
|
9090
|
-
|
9150
|
+
// Evaluate the expressions to report errors and record symbol
|
9151
|
+
// references. We can skip this if we're executing speculatively.
|
9152
|
+
if (!speculativeTypeTracker.isSpeculative(node)) {
|
9153
|
+
if (node.startValue) {
|
9154
|
+
getTypeOfExpression(node.startValue);
|
9155
|
+
}
|
9156
|
+
if (node.endValue) {
|
9157
|
+
getTypeOfExpression(node.endValue);
|
9158
|
+
}
|
9159
|
+
if (node.stepValue) {
|
9160
|
+
getTypeOfExpression(node.stepValue);
|
9161
|
+
}
|
9091
9162
|
}
|
9092
9163
|
return { type: getBuiltInObject(node, 'slice'), node };
|
9093
9164
|
}
|
@@ -9832,7 +9903,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9832
9903
|
}
|
9833
9904
|
return undefined;
|
9834
9905
|
}
|
9835
|
-
function transformTypeForTypeAlias(type, name, errorNode) {
|
9906
|
+
function transformTypeForTypeAlias(type, name, errorNode, typeParameters) {
|
9836
9907
|
if (!types_1.TypeBase.isInstantiable(type)) {
|
9837
9908
|
return type;
|
9838
9909
|
}
|
@@ -9841,17 +9912,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9841
9912
|
if ((0, typeUtils_1.isTypeAliasPlaceholder)(type)) {
|
9842
9913
|
return type;
|
9843
9914
|
}
|
9844
|
-
|
9845
|
-
|
9846
|
-
|
9847
|
-
|
9848
|
-
|
9849
|
-
(0,
|
9850
|
-
(0, typeUtils_1.
|
9851
|
-
|
9915
|
+
if (!typeParameters) {
|
9916
|
+
// Determine if there are any generic type parameters associated
|
9917
|
+
// with this type alias.
|
9918
|
+
typeParameters = [];
|
9919
|
+
// Skip this for a simple TypeVar (one that's not part of a union).
|
9920
|
+
if (!(0, types_1.isTypeVar)(type) || types_1.TypeBase.isAnnotated(type)) {
|
9921
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
9922
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
9923
|
+
});
|
9924
|
+
}
|
9925
|
+
// Don't include any synthesized type variables.
|
9926
|
+
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
9852
9927
|
}
|
9853
|
-
// Don't include any synthesized type variables.
|
9854
|
-
typeParameters = typeParameters.filter((typeVar) => !typeVar.details.isSynthesized);
|
9855
9928
|
// Convert all type variables to instances.
|
9856
9929
|
typeParameters = typeParameters.map((typeVar) => {
|
9857
9930
|
if (types_1.TypeBase.isInstance(typeVar)) {
|
@@ -10052,7 +10125,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10052
10125
|
}
|
10053
10126
|
if (!rightHandType) {
|
10054
10127
|
// Determine whether there is a declared type.
|
10055
|
-
const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
|
10128
|
+
const declaredType = getDeclaredTypeForExpression(node.leftExpression, {
|
10129
|
+
method: 'set',
|
10130
|
+
});
|
10056
10131
|
let typeAliasNameNode;
|
10057
10132
|
let isSpeculativeTypeAlias = false;
|
10058
10133
|
if (isDeclaredTypeAlias(node.leftExpression)) {
|
@@ -10158,6 +10233,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10158
10233
|
/* allowAssignmentToFinalVar */ true, expectedTypeDiagAddendum);
|
10159
10234
|
writeTypeCache(node, rightHandType, 0 /* None */, isIncomplete);
|
10160
10235
|
}
|
10236
|
+
// Evaluates the type of a type alias (i.e. "type") statement. This code
|
10237
|
+
// path does not handle traditional type aliases, which are treated as
|
10238
|
+
// variables since they use normal variable assignment syntax.
|
10239
|
+
function getTypeOfTypeAlias(node) {
|
10240
|
+
const cachedType = readTypeCache(node.name, 0 /* None */);
|
10241
|
+
if (cachedType) {
|
10242
|
+
return cachedType;
|
10243
|
+
}
|
10244
|
+
// Synthesize a type variable that represents the type alias while we're
|
10245
|
+
// evaluating it. This allows us to handle recursive definitions.
|
10246
|
+
const typeAliasTypeVar = types_1.TypeVarType.createInstantiable(`__type_alias_${node.name.value}`);
|
10247
|
+
typeAliasTypeVar.details.isSynthesized = true;
|
10248
|
+
typeAliasTypeVar.details.recursiveTypeAliasName = node.name.value;
|
10249
|
+
const scopeId = getScopeIdForNode(node.name);
|
10250
|
+
typeAliasTypeVar.details.recursiveTypeAliasScopeId = scopeId;
|
10251
|
+
typeAliasTypeVar.scopeId = scopeId;
|
10252
|
+
// Write the type to the type cache. It will be replaced below.
|
10253
|
+
writeTypeCache(node.name, typeAliasTypeVar, /* flags */ undefined, /* isIncomplete */ false);
|
10254
|
+
// Set a partial type to handle recursive (self-referential) type aliases.
|
10255
|
+
const scope = ScopeUtils.getScopeForNode(node);
|
10256
|
+
const typeAliasSymbol = scope === null || scope === void 0 ? void 0 : scope.lookUpSymbolRecursive(node.name.value);
|
10257
|
+
const typeAliasDecl = AnalyzerNodeInfo.getDeclaration(node);
|
10258
|
+
if (typeAliasDecl && typeAliasSymbol) {
|
10259
|
+
setSymbolResolutionPartialType(typeAliasSymbol.symbol, typeAliasDecl, typeAliasTypeVar);
|
10260
|
+
}
|
10261
|
+
let typeParameters = [];
|
10262
|
+
if (node.typeParameters) {
|
10263
|
+
typeParameters = evaluateTypeParameterList(node.typeParameters);
|
10264
|
+
typeAliasTypeVar.details.recursiveTypeParameters = typeParameters;
|
10265
|
+
}
|
10266
|
+
const aliasTypeResult = getTypeOfExpressionExpectingType(node.expression);
|
10267
|
+
let isIncomplete = false;
|
10268
|
+
let aliasType = aliasTypeResult.type;
|
10269
|
+
if (aliasTypeResult.isIncomplete) {
|
10270
|
+
isIncomplete = true;
|
10271
|
+
}
|
10272
|
+
// Clear the temporary type we wrote above.
|
10273
|
+
deleteTypeCacheEntry(node.name);
|
10274
|
+
aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters);
|
10275
|
+
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
|
10276
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
10277
|
+
name: node.name.value,
|
10278
|
+
}), node.expression);
|
10279
|
+
aliasType = types_1.UnknownType.create();
|
10280
|
+
}
|
10281
|
+
// Set the resulting type to the boundType of the original type alias
|
10282
|
+
// to support recursive type aliases.
|
10283
|
+
typeAliasTypeVar.details.boundType = aliasType;
|
10284
|
+
if (typeAliasTypeVar.details.illegalRecursionDetected) {
|
10285
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveIndirect().format({
|
10286
|
+
name: node.name.value,
|
10287
|
+
}), node.name);
|
10288
|
+
}
|
10289
|
+
writeTypeCache(node.name, aliasType, 0 /* None */, isIncomplete);
|
10290
|
+
return aliasType;
|
10291
|
+
}
|
10161
10292
|
function evaluateTypesForAugmentedAssignment(node) {
|
10162
10293
|
if (readTypeCache(node, 0 /* None */)) {
|
10163
10294
|
return;
|
@@ -10223,7 +10354,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10223
10354
|
writeTypeCache(node.name, classType, /* flags */ undefined, /* isIncomplete */ false);
|
10224
10355
|
// Keep a list of unique type parameters that are used in the
|
10225
10356
|
// base class arguments.
|
10226
|
-
|
10357
|
+
let typeParameters = [];
|
10358
|
+
if (node.typeParameters) {
|
10359
|
+
typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
|
10360
|
+
}
|
10227
10361
|
// If the class derives from "Generic" directly, it will provide
|
10228
10362
|
// all of the type parameters in the specified order.
|
10229
10363
|
let genericTypeParameters;
|
@@ -10344,12 +10478,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10344
10478
|
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10345
10479
|
if ((0, types_1.isInstantiableClass)(argType)) {
|
10346
10480
|
if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
|
10347
|
-
if
|
10348
|
-
|
10349
|
-
|
10481
|
+
// 'Generic' is implicitly added if type parameter syntax is used.
|
10482
|
+
if (node.typeParameters) {
|
10483
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
|
10484
|
+
}
|
10485
|
+
else {
|
10486
|
+
if (!genericTypeParameters) {
|
10487
|
+
if (protocolTypeParameters) {
|
10488
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
|
10489
|
+
}
|
10490
|
+
genericTypeParameters = [];
|
10491
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10350
10492
|
}
|
10351
|
-
genericTypeParameters = [];
|
10352
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10353
10493
|
}
|
10354
10494
|
}
|
10355
10495
|
else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
|
@@ -10361,6 +10501,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10361
10501
|
}
|
10362
10502
|
protocolTypeParameters = [];
|
10363
10503
|
(0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
10504
|
+
if (node.typeParameters && protocolTypeParameters.length > 0) {
|
10505
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
|
10506
|
+
protocolTypeParameters = [];
|
10507
|
+
}
|
10364
10508
|
}
|
10365
10509
|
}
|
10366
10510
|
}
|
@@ -10423,10 +10567,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10423
10567
|
// If genericTypeParameters or protocolTypeParameters are provided,
|
10424
10568
|
// make sure that typeParameters is a proper subset.
|
10425
10569
|
genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
|
10426
|
-
if (genericTypeParameters) {
|
10570
|
+
if (genericTypeParameters && !node.typeParameters) {
|
10427
10571
|
verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
|
10428
10572
|
}
|
10429
|
-
classType.details.typeParameters = genericTypeParameters
|
10573
|
+
classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
|
10574
|
+
// Determine if one or more type parameters is autovariance.
|
10575
|
+
if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
|
10576
|
+
classType.details.requiresVarianceInference = true;
|
10577
|
+
}
|
10430
10578
|
// Make sure there's at most one variadic type parameter.
|
10431
10579
|
const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
10432
10580
|
if (variadics.length > 1) {
|
@@ -10456,7 +10604,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10456
10604
|
const initMethod = classType.details.fields.get('__init__');
|
10457
10605
|
if (initMethod) {
|
10458
10606
|
const initDecls = initMethod.getTypedDeclarations();
|
10459
|
-
if (initDecls.length === 1 && initDecls[0].type ===
|
10607
|
+
if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
|
10460
10608
|
const initDeclNode = initDecls[0].node;
|
10461
10609
|
const initParams = initDeclNode.parameters;
|
10462
10610
|
if (initParams.length > 1 &&
|
@@ -10506,6 +10654,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10506
10654
|
}
|
10507
10655
|
}
|
10508
10656
|
const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
|
10657
|
+
// Clear the "partially constructed" flag.
|
10658
|
+
classType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
10509
10659
|
// Now determine the decorated type of the class.
|
10510
10660
|
let decoratedType = classType;
|
10511
10661
|
let foundUnknown = false;
|
@@ -10542,8 +10692,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10542
10692
|
(0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
|
10543
10693
|
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, classType, initSubclassArgs);
|
10544
10694
|
}
|
10545
|
-
// Clear the "partially constructed" flag.
|
10546
|
-
classType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
10547
10695
|
// Run any class hooks that depend on this class.
|
10548
10696
|
runClassTypeHooks(classType);
|
10549
10697
|
// Synthesize TypedDict methods.
|
@@ -10619,6 +10767,87 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10619
10767
|
}
|
10620
10768
|
return { classType, decoratedType };
|
10621
10769
|
}
|
10770
|
+
function inferTypeParameterVarianceForClass(classType) {
|
10771
|
+
if (!classType.details.requiresVarianceInference) {
|
10772
|
+
return;
|
10773
|
+
}
|
10774
|
+
if (!objectType || !(0, types_1.isClassInstance)(objectType)) {
|
10775
|
+
return;
|
10776
|
+
}
|
10777
|
+
// Presumptively mark the variance inference as complete. This
|
10778
|
+
// prevents potential recursion.
|
10779
|
+
classType.details.requiresVarianceInference = false;
|
10780
|
+
// Presumptively mark the computed variance to "in progress". We'll
|
10781
|
+
// replace this below once the variance has been inferred.
|
10782
|
+
classType.details.typeParameters.forEach((param) => {
|
10783
|
+
if (param.details.declaredVariance === 0 /* Auto */) {
|
10784
|
+
param.computedVariance = 1 /* Unknown */;
|
10785
|
+
}
|
10786
|
+
});
|
10787
|
+
// Replace all of the type parameters with invariant TypeVars.
|
10788
|
+
const updatedTypeParams = classType.details.typeParameters.map((typeParam) => types_1.TypeVarType.cloneAsInvariant(typeParam));
|
10789
|
+
const updatedClassType = types_1.ClassType.cloneWithNewTypeParameters(classType, updatedTypeParams);
|
10790
|
+
const dummyTypeObject = types_1.ClassType.createInstantiable('__varianceDummy', '', '', '', 0, 0, undefined, undefined);
|
10791
|
+
updatedTypeParams.forEach((param, paramIndex) => {
|
10792
|
+
// Skip variadics and ParamSpecs.
|
10793
|
+
if (param.details.isVariadic || param.details.isParamSpec) {
|
10794
|
+
return;
|
10795
|
+
}
|
10796
|
+
// Skip type variables without auto-variance.
|
10797
|
+
if (param.details.declaredVariance !== 0 /* Auto */) {
|
10798
|
+
return;
|
10799
|
+
}
|
10800
|
+
// Replace all type arguments with a dummy type except for the
|
10801
|
+
// TypeVar of interest, which is replaced with an object instance.
|
10802
|
+
const srcTypeArgs = updatedTypeParams.map((p, i) => {
|
10803
|
+
if (p.details.isVariadic) {
|
10804
|
+
return p;
|
10805
|
+
}
|
10806
|
+
return i === paramIndex ? objectType : dummyTypeObject;
|
10807
|
+
});
|
10808
|
+
// Replace all type arguments with a dummy type except for the
|
10809
|
+
// TypeVar of interest, which is replaced with itself.
|
10810
|
+
const destTypeArgs = updatedTypeParams.map((p, i) => {
|
10811
|
+
return i === paramIndex || p.details.isVariadic ? p : dummyTypeObject;
|
10812
|
+
});
|
10813
|
+
const srcType = types_1.ClassType.cloneForSpecialization(updatedClassType, srcTypeArgs,
|
10814
|
+
/* isTypeArgumentExplicit */ true);
|
10815
|
+
const destType = types_1.ClassType.cloneForSpecialization(updatedClassType, destTypeArgs,
|
10816
|
+
/* isTypeArgumentExplicit */ true);
|
10817
|
+
const isDestSubtypeOfSrc = assignClassToSelf(srcType, destType);
|
10818
|
+
let inferredVariance;
|
10819
|
+
if (isDestSubtypeOfSrc) {
|
10820
|
+
inferredVariance = 3 /* Covariant */;
|
10821
|
+
}
|
10822
|
+
else {
|
10823
|
+
const isSrcSubtypeOfDest = assignClassToSelf(destType, srcType);
|
10824
|
+
if (isSrcSubtypeOfDest) {
|
10825
|
+
inferredVariance = 4 /* Contravariant */;
|
10826
|
+
}
|
10827
|
+
else {
|
10828
|
+
inferredVariance = 2 /* Invariant */;
|
10829
|
+
}
|
10830
|
+
}
|
10831
|
+
// We assume here that we don't need to clone the type var object
|
10832
|
+
// because it was already cloned when it was associated with this
|
10833
|
+
// class scope.
|
10834
|
+
classType.details.typeParameters[paramIndex].computedVariance = inferredVariance;
|
10835
|
+
});
|
10836
|
+
}
|
10837
|
+
function evaluateTypeParameterList(node) {
|
10838
|
+
const paramTypes = [];
|
10839
|
+
node.parameters.forEach((param) => {
|
10840
|
+
const paramSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(param.name);
|
10841
|
+
(0, debug_1.assert)(paramSymbol);
|
10842
|
+
const typeOfParam = getDeclaredTypeOfSymbol(paramSymbol, param.name);
|
10843
|
+
if (!typeOfParam || !(0, types_1.isTypeVar)(typeOfParam)) {
|
10844
|
+
return;
|
10845
|
+
}
|
10846
|
+
writeTypeCache(param.name, typeOfParam, 0 /* None */, /* isIncomplete */ false);
|
10847
|
+
paramTypes.push(typeOfParam);
|
10848
|
+
});
|
10849
|
+
return paramTypes;
|
10850
|
+
}
|
10622
10851
|
function computeEffectiveMetaclass(classType, errorNode) {
|
10623
10852
|
let effectiveMetaclass = classType.details.declaredMetaclass;
|
10624
10853
|
let reportedMetaclassConflict = false;
|
@@ -10944,6 +11173,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10944
11173
|
}), node.functionAnnotationComment);
|
10945
11174
|
}
|
10946
11175
|
}
|
11176
|
+
if (node.typeParameters) {
|
11177
|
+
evaluateTypeParameterList(node.typeParameters);
|
11178
|
+
}
|
10947
11179
|
const markParamAccessed = (param) => {
|
10948
11180
|
if (param.name) {
|
10949
11181
|
const symbolWithScope = lookUpSymbolRecursive(param.name, param.name.value, /* honorCodeFlow */ false);
|
@@ -11252,7 +11484,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11252
11484
|
const baseClassMemberInfo = (0, typeUtils_1.lookUpClassMember)(containingClassType, methodName, 1 /* SkipOriginalClass */);
|
11253
11485
|
if (baseClassMemberInfo) {
|
11254
11486
|
const memberDecls = baseClassMemberInfo.symbol.getDeclarations();
|
11255
|
-
if (memberDecls.length === 1 && memberDecls[0].type ===
|
11487
|
+
if (memberDecls.length === 1 && memberDecls[0].type === 5 /* Function */) {
|
11256
11488
|
const baseClassMethodNode = memberDecls[0].node;
|
11257
11489
|
// Does the signature match exactly with the exception of annotations?
|
11258
11490
|
if (baseClassMethodNode.parameters.length === functionNode.parameters.length &&
|
@@ -11529,14 +11761,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11529
11761
|
// to recursion if there is a large number (1000's) of overloads.
|
11530
11762
|
for (let i = 0; i < declIndex; i++) {
|
11531
11763
|
const decl = decls[i];
|
11532
|
-
if (decl.type ===
|
11764
|
+
if (decl.type === 5 /* Function */) {
|
11533
11765
|
getTypeOfFunction(decl.node);
|
11534
11766
|
}
|
11535
11767
|
}
|
11536
11768
|
const overloadedTypes = [];
|
11537
11769
|
// Look at the previous declaration's type.
|
11538
11770
|
const prevDecl = decls[declIndex - 1];
|
11539
|
-
if (prevDecl.type ===
|
11771
|
+
if (prevDecl.type === 5 /* Function */) {
|
11540
11772
|
const prevDeclDeclTypeInfo = getTypeOfFunction(prevDecl.node);
|
11541
11773
|
if (prevDeclDeclTypeInfo) {
|
11542
11774
|
if ((0, types_1.isFunction)(prevDeclDeclTypeInfo.decoratedType)) {
|
@@ -12086,19 +12318,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12086
12318
|
// case, we want to choose the last declaration.
|
12087
12319
|
const filteredDecls = symbolWithScope.symbol
|
12088
12320
|
.getDeclarations()
|
12089
|
-
.filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type ===
|
12321
|
+
.filter((decl) => ParseTreeUtils.isNodeContainedWithin(node, decl.node) && decl.type === 8 /* Alias */);
|
12090
12322
|
let aliasDecl = filteredDecls.length > 0 ? filteredDecls[filteredDecls.length - 1] : undefined;
|
12091
12323
|
// If we didn't find an exact match, look for any alias associated with
|
12092
12324
|
// this symbol. In cases where we have multiple ImportAs nodes that share
|
12093
12325
|
// the same first-part name (e.g. "import asyncio" and "import asyncio.tasks"),
|
12094
12326
|
// we may not find the declaration associated with this node.
|
12095
12327
|
if (!aliasDecl) {
|
12096
|
-
aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type ===
|
12328
|
+
aliasDecl = symbolWithScope.symbol.getDeclarations().find((decl) => decl.type === 8 /* Alias */);
|
12097
12329
|
}
|
12098
12330
|
if (!aliasDecl) {
|
12099
12331
|
return undefined;
|
12100
12332
|
}
|
12101
|
-
(0, debug_1.assert)(aliasDecl.type ===
|
12333
|
+
(0, debug_1.assert)(aliasDecl.type === 8 /* Alias */);
|
12102
12334
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
12103
12335
|
// Try to resolve the alias while honoring external visibility.
|
12104
12336
|
const resolvedAliasInfo = resolveAliasDeclarationWithInfo(aliasDecl,
|
@@ -12135,7 +12367,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12135
12367
|
// expression or statement that contains it. This contextual evaluation
|
12136
12368
|
// allows for bidirectional type evaluation.
|
12137
12369
|
function evaluateTypesForExpressionInContext(node) {
|
12138
|
-
var _a, _b, _c;
|
12370
|
+
var _a, _b, _c, _d, _e;
|
12139
12371
|
let lastContextualExpression = node;
|
12140
12372
|
let curNode = node;
|
12141
12373
|
function isContextual(node) {
|
@@ -12204,6 +12436,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12204
12436
|
getTypeOfClass(node.parent);
|
12205
12437
|
return;
|
12206
12438
|
}
|
12439
|
+
else if (node.parent.nodeType === 77 /* TypeAlias */ && node.parent.name === node) {
|
12440
|
+
getTypeOfTypeAlias(node.parent);
|
12441
|
+
return;
|
12442
|
+
}
|
12207
12443
|
else if (node.parent.nodeType === 29 /* Global */ ||
|
12208
12444
|
node.parent.nodeType === 39 /* Nonlocal */) {
|
12209
12445
|
// For global and nonlocal statements, allow forward references so
|
@@ -12242,15 +12478,32 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12242
12478
|
verifyDeleteExpression(lastContextualExpression);
|
12243
12479
|
return;
|
12244
12480
|
}
|
12481
|
+
// If this is the name node within a type parameter list, see if it's a type alias
|
12482
|
+
// definition. If so, we need to evaluate the type alias contextually.
|
12483
|
+
if (parent.nodeType === 75 /* TypeParameter */ && lastContextualExpression === parent.name) {
|
12484
|
+
if (((_a = parent.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 76 /* TypeParameterList */ &&
|
12485
|
+
((_b = parent.parent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 77 /* TypeAlias */) {
|
12486
|
+
getTypeOfTypeAlias(parent.parent.parent);
|
12487
|
+
return;
|
12488
|
+
}
|
12489
|
+
}
|
12490
|
+
if (parent.nodeType === 75 /* TypeParameter */) {
|
12491
|
+
getTypeOfExpression(parent.name);
|
12492
|
+
return;
|
12493
|
+
}
|
12494
|
+
if (parent.nodeType === 77 /* TypeAlias */) {
|
12495
|
+
getTypeOfTypeAlias(parent);
|
12496
|
+
return;
|
12497
|
+
}
|
12245
12498
|
if (parent.nodeType === 5 /* AugmentedAssignment */) {
|
12246
12499
|
evaluateTypesForAugmentedAssignment(parent);
|
12247
12500
|
return;
|
12248
12501
|
}
|
12249
12502
|
if (parent.nodeType === 13 /* Decorator */) {
|
12250
|
-
if (((
|
12503
|
+
if (((_c = parent.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
|
12251
12504
|
getTypeOfClass(parent.parent);
|
12252
12505
|
}
|
12253
|
-
else if (((
|
12506
|
+
else if (((_d = parent.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 28 /* Function */) {
|
12254
12507
|
getTypeOfFunction(parent.parent);
|
12255
12508
|
}
|
12256
12509
|
return;
|
@@ -12301,7 +12554,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12301
12554
|
return;
|
12302
12555
|
}
|
12303
12556
|
// A class argument must be evaluated in the context of the class declaration.
|
12304
|
-
if (parent.nodeType === 1 /* Argument */ && ((
|
12557
|
+
if (parent.nodeType === 1 /* Argument */ && ((_e = parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 10 /* Class */) {
|
12305
12558
|
getTypeOfClass(parent.parent);
|
12306
12559
|
return;
|
12307
12560
|
}
|
@@ -12397,6 +12650,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12397
12650
|
}
|
12398
12651
|
break;
|
12399
12652
|
}
|
12653
|
+
case 77 /* TypeAlias */: {
|
12654
|
+
getTypeOfTypeAlias(curNode);
|
12655
|
+
return;
|
12656
|
+
}
|
12400
12657
|
case 4 /* AssignmentExpression */: {
|
12401
12658
|
getTypeOfExpression(curNode);
|
12402
12659
|
return;
|
@@ -12844,8 +13101,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12844
13101
|
return specializedClass;
|
12845
13102
|
}
|
12846
13103
|
function getTypeOfArgument(arg) {
|
12847
|
-
if (arg.
|
12848
|
-
return { type: arg.type };
|
13104
|
+
if (arg.typeResult) {
|
13105
|
+
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
12849
13106
|
}
|
12850
13107
|
if (!arg.valueExpression) {
|
12851
13108
|
// We shouldn't ever get here, but just in case.
|
@@ -12860,8 +13117,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12860
13117
|
// and therefore follows the normal rules of types (e.g. they
|
12861
13118
|
// can be forward-declared in stubs, etc.).
|
12862
13119
|
function getTypeOfArgumentExpectingType(arg) {
|
12863
|
-
if (arg.
|
12864
|
-
return { type: arg.type };
|
13120
|
+
if (arg.typeResult) {
|
13121
|
+
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
12865
13122
|
}
|
12866
13123
|
// If there was no defined type provided, there should always
|
12867
13124
|
// be a value expression from which we can retrieve the type.
|
@@ -12923,10 +13180,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12923
13180
|
if (symbolWithScope && honorCodeFlow && scopeTypeHonorsCodeFlow) {
|
12924
13181
|
// Filter the declarations based on flow reachability.
|
12925
13182
|
const reachableDecls = symbolWithScope.symbol.getDeclarations().filter((decl) => {
|
12926
|
-
if (decl.type !==
|
13183
|
+
if (decl.type !== 8 /* Alias */ && decl.type !== 0 /* Intrinsic */) {
|
12927
13184
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
12928
13185
|
const usageScope = ParseTreeUtils.getExecutionScopeNode(node);
|
12929
|
-
const declNode = decl.type ===
|
13186
|
+
const declNode = decl.type === 6 /* Class */ ||
|
13187
|
+
decl.type === 5 /* Function */ ||
|
13188
|
+
decl.type === 4 /* TypeAlias */
|
12930
13189
|
? decl.node.name
|
12931
13190
|
: decl.node;
|
12932
13191
|
const declScope = ParseTreeUtils.getExecutionScopeNode(declNode);
|
@@ -13044,7 +13303,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13044
13303
|
if ((0, types_1.isFunction)(type)) {
|
13045
13304
|
if (type.details.declaration) {
|
13046
13305
|
const functionDecl = type.details.declaration;
|
13047
|
-
if (functionDecl.type ===
|
13306
|
+
if (functionDecl.type === 5 /* Function */) {
|
13048
13307
|
const functionNode = functionDecl.node;
|
13049
13308
|
const functionScope = AnalyzerNodeInfo.getScope(functionNode);
|
13050
13309
|
if (functionScope) {
|
@@ -13108,7 +13367,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13108
13367
|
// The alias could have more decls that don't refer to this import. Filter
|
13109
13368
|
// out the one(s) that specifically associated with this import statement.
|
13110
13369
|
const declsForThisImport = symbolInScope.symbol.getDeclarations().filter((decl) => {
|
13111
|
-
return decl.type ===
|
13370
|
+
return decl.type === 8 /* Alias */ && decl.node === node.parent;
|
13112
13371
|
});
|
13113
13372
|
(0, collectionUtils_1.appendArray)(declarations, (0, declarationUtils_1.getDeclarationsWithUsesLocalNameRemoved)(declsForThisImport));
|
13114
13373
|
}
|
@@ -13232,9 +13491,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13232
13491
|
// Determine if this node is within a quoted type annotation.
|
13233
13492
|
const isWithinTypeAnnotation = ParseTreeUtils.isWithinTypeAnnotation(node, !(0, analyzerFileInfo_1.isAnnotationEvaluationPostponed)(AnalyzerNodeInfo.getFileInfo(node)));
|
13234
13493
|
const allowForwardReferences = isWithinTypeAnnotation || fileInfo.isStubFile;
|
13235
|
-
|
13236
|
-
|
13237
|
-
|
13494
|
+
let symbol;
|
13495
|
+
const typeParamSymbol = AnalyzerNodeInfo.getTypeParameterSymbol(node);
|
13496
|
+
if (typeParamSymbol) {
|
13497
|
+
symbol = typeParamSymbol;
|
13498
|
+
}
|
13499
|
+
else {
|
13500
|
+
const symbolWithScope = lookUpSymbolRecursive(node, node.value, !allowForwardReferences, isWithinTypeAnnotation);
|
13501
|
+
symbol = symbolWithScope === null || symbolWithScope === void 0 ? void 0 : symbolWithScope.symbol;
|
13502
|
+
}
|
13503
|
+
if (symbol) {
|
13504
|
+
(0, collectionUtils_1.appendArray)(declarations, symbol.getDeclarations());
|
13238
13505
|
}
|
13239
13506
|
}
|
13240
13507
|
return declarations;
|
@@ -13280,17 +13547,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13280
13547
|
}
|
13281
13548
|
return types_1.UnknownType.create();
|
13282
13549
|
}
|
13283
|
-
case
|
13550
|
+
case 6 /* Class */: {
|
13284
13551
|
const classTypeInfo = getTypeOfClass(declaration.node);
|
13285
13552
|
return classTypeInfo === null || classTypeInfo === void 0 ? void 0 : classTypeInfo.decoratedType;
|
13286
13553
|
}
|
13287
|
-
case
|
13554
|
+
case 7 /* SpecialBuiltInClass */: {
|
13288
13555
|
return getTypeOfAnnotation(declaration.node.typeAnnotation);
|
13289
13556
|
}
|
13290
|
-
case
|
13557
|
+
case 5 /* Function */: {
|
13291
13558
|
const functionTypeInfo = getTypeOfFunction(declaration.node);
|
13292
13559
|
return functionTypeInfo === null || functionTypeInfo === void 0 ? void 0 : functionTypeInfo.decoratedType;
|
13293
13560
|
}
|
13561
|
+
case 4 /* TypeAlias */: {
|
13562
|
+
return getTypeOfTypeAlias(declaration.node);
|
13563
|
+
}
|
13294
13564
|
case 2 /* Parameter */: {
|
13295
13565
|
let typeAnnotationNode = declaration.node.typeAnnotation || declaration.node.typeAnnotationComment;
|
13296
13566
|
// If there wasn't an annotation, see if the parent function
|
@@ -13312,6 +13582,62 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13312
13582
|
}
|
13313
13583
|
return undefined;
|
13314
13584
|
}
|
13585
|
+
case 3 /* TypeParameter */: {
|
13586
|
+
let typeVar = types_1.TypeVarType.createInstantiable(declaration.node.name.value);
|
13587
|
+
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVarTuple) {
|
13588
|
+
typeVar.details.isVariadic = true;
|
13589
|
+
}
|
13590
|
+
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.ParamSpec) {
|
13591
|
+
typeVar.details.isParamSpec = true;
|
13592
|
+
}
|
13593
|
+
if (declaration.node.boundExpression) {
|
13594
|
+
if (declaration.node.boundExpression.nodeType === 52 /* Tuple */) {
|
13595
|
+
const constraints = declaration.node.boundExpression.expressions.map((constraint) => {
|
13596
|
+
const constraintType = getTypeOfExpressionExpectingType(constraint).type;
|
13597
|
+
if ((0, typeUtils_1.requiresSpecialization)(constraintType, /* ignorePseudoGeneric */ true)) {
|
13598
|
+
addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), constraint);
|
13599
|
+
}
|
13600
|
+
return (0, typeUtils_1.convertToInstance)(constraintType);
|
13601
|
+
});
|
13602
|
+
if (constraints.length < 2) {
|
13603
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(declaration.node.boundExpression).diagnosticRuleSet
|
13604
|
+
.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarSingleConstraint(), declaration.node.boundExpression);
|
13605
|
+
}
|
13606
|
+
else if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
13607
|
+
typeVar.details.constraints = constraints;
|
13608
|
+
}
|
13609
|
+
}
|
13610
|
+
else {
|
13611
|
+
const boundType = getTypeOfExpressionExpectingType(declaration.node.boundExpression).type;
|
13612
|
+
if ((0, typeUtils_1.requiresSpecialization)(boundType, /* ignorePseudoGeneric */ true)) {
|
13613
|
+
addError(localize_1.Localizer.Diagnostic.typeVarGeneric(), declaration.node.boundExpression);
|
13614
|
+
}
|
13615
|
+
if (declaration.node.typeParamCategory === parseNodes_1.TypeParameterCategory.TypeVar) {
|
13616
|
+
typeVar.details.boundType = (0, typeUtils_1.convertToInstance)(boundType);
|
13617
|
+
}
|
13618
|
+
}
|
13619
|
+
}
|
13620
|
+
typeVar.details.isTypeParamSyntax = true;
|
13621
|
+
// Associate the type variable with the owning scope.
|
13622
|
+
const scopeNode = ParseTreeUtils.getTypeVarScopeNode(declaration.node);
|
13623
|
+
if (scopeNode) {
|
13624
|
+
let scopeType;
|
13625
|
+
if (scopeNode.nodeType === 10 /* Class */) {
|
13626
|
+
scopeType = 0 /* Class */;
|
13627
|
+
// Set the variance to "auto" for class-scoped TypeVars.
|
13628
|
+
typeVar.details.declaredVariance = 0 /* Auto */;
|
13629
|
+
}
|
13630
|
+
else if (scopeNode.nodeType === 28 /* Function */) {
|
13631
|
+
scopeType = 1 /* Function */;
|
13632
|
+
}
|
13633
|
+
else {
|
13634
|
+
(0, debug_1.assert)(scopeNode.nodeType === 77 /* TypeAlias */);
|
13635
|
+
scopeType = 2 /* TypeAlias */;
|
13636
|
+
}
|
13637
|
+
typeVar = types_1.TypeVarType.cloneForScopeId(typeVar, getScopeIdForNode(scopeNode.nodeType === 77 /* TypeAlias */ ? scopeNode.name : scopeNode), scopeNode.name.value, scopeType);
|
13638
|
+
}
|
13639
|
+
return typeVar;
|
13640
|
+
}
|
13315
13641
|
case 1 /* Variable */: {
|
13316
13642
|
const typeAnnotationNode = declaration.typeAnnotationNode;
|
13317
13643
|
if (typeAnnotationNode) {
|
@@ -13349,7 +13675,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13349
13675
|
}
|
13350
13676
|
return undefined;
|
13351
13677
|
}
|
13352
|
-
case
|
13678
|
+
case 8 /* Alias */: {
|
13353
13679
|
return undefined;
|
13354
13680
|
}
|
13355
13681
|
}
|
@@ -13396,11 +13722,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13396
13722
|
// If the resolved declaration is still an alias, the alias
|
13397
13723
|
// is pointing at a module, and we need to synthesize a
|
13398
13724
|
// module type.
|
13399
|
-
if (resolvedDecl.type ===
|
13725
|
+
if (resolvedDecl.type === 8 /* Alias */) {
|
13400
13726
|
// Build a module type that corresponds to the declaration and
|
13401
13727
|
// its associated loader actions.
|
13402
13728
|
let moduleName = resolvedDecl.moduleName;
|
13403
|
-
if (decl.type ===
|
13729
|
+
if (decl.type === 8 /* Alias */) {
|
13404
13730
|
if (decl.symbolName) {
|
13405
13731
|
moduleName += '.' + decl.symbolName;
|
13406
13732
|
}
|
@@ -13651,7 +13977,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13651
13977
|
considerDecl = false;
|
13652
13978
|
}
|
13653
13979
|
if (usageNode !== undefined) {
|
13654
|
-
if (decl.type !==
|
13980
|
+
if (decl.type !== 8 /* Alias */) {
|
13655
13981
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
13656
13982
|
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
|
13657
13983
|
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
|
@@ -13764,9 +14090,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13764
14090
|
// reachable from the usage node (if specified). This can happen in
|
13765
14091
|
// cases where a property symbol is redefined to add a setter, deleter,
|
13766
14092
|
// etc.
|
13767
|
-
if (typedDecls.length > 1
|
14093
|
+
if (usageNode && typedDecls.length > 1) {
|
13768
14094
|
const filteredTypedDecls = typedDecls.filter((decl) => {
|
13769
|
-
if (decl.type !==
|
14095
|
+
if (decl.type !== 8 /* Alias */) {
|
13770
14096
|
// Is the declaration in the same execution scope as the "usageNode" node?
|
13771
14097
|
const usageScope = ParseTreeUtils.getExecutionScopeNode(usageNode);
|
13772
14098
|
const declScope = ParseTreeUtils.getExecutionScopeNode(decl.node);
|
@@ -13778,9 +14104,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13778
14104
|
}
|
13779
14105
|
return true;
|
13780
14106
|
});
|
13781
|
-
if (filteredTypedDecls.length
|
13782
|
-
|
14107
|
+
if (filteredTypedDecls.length === 0) {
|
14108
|
+
return types_1.UnboundType.create();
|
13783
14109
|
}
|
14110
|
+
typedDecls = filteredTypedDecls;
|
13784
14111
|
}
|
13785
14112
|
// Start with the last decl. If that's already being resolved,
|
13786
14113
|
// use the next-to-last decl, etc. This can happen when resolving
|
@@ -13806,7 +14133,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13806
14133
|
// in the type cache. This exception is required to handle the
|
13807
14134
|
// circular dependency between the "type" and "object" classes in
|
13808
14135
|
// builtins.pyi (since "object" is a "type" and "type" is an "object").
|
13809
|
-
if (popSymbolResolution(symbol) || decl.type ===
|
14136
|
+
if (popSymbolResolution(symbol) || decl.type === 6 /* Class */) {
|
13810
14137
|
return type;
|
13811
14138
|
}
|
13812
14139
|
}
|
@@ -14157,6 +14484,63 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14157
14484
|
}));
|
14158
14485
|
return false;
|
14159
14486
|
}
|
14487
|
+
// This function is used to validate or infer the variance of type
|
14488
|
+
// parameters within a class.
|
14489
|
+
function assignClassToSelf(destType, srcType, recursionCount = 0) {
|
14490
|
+
(0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
|
14491
|
+
(0, debug_1.assert)(destType.details.typeParameters.length > 0);
|
14492
|
+
const diag = new diagnostic_1.DiagnosticAddendum();
|
14493
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
14494
|
+
let isAssignable = true;
|
14495
|
+
destType.details.fields.forEach((symbol, name) => {
|
14496
|
+
if (isAssignable && symbol.isClassMember() && !symbol.isIgnoredForProtocolMatch()) {
|
14497
|
+
const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
|
14498
|
+
(0, debug_1.assert)(memberInfo !== undefined);
|
14499
|
+
let destMemberType = getDeclaredTypeOfSymbol(symbol);
|
14500
|
+
if (destMemberType) {
|
14501
|
+
const srcMemberType = getTypeOfMember(memberInfo);
|
14502
|
+
destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType);
|
14503
|
+
// Properties require special processing.
|
14504
|
+
if ((0, types_1.isClassInstance)(destMemberType) &&
|
14505
|
+
types_1.ClassType.isPropertyClass(destMemberType) &&
|
14506
|
+
(0, types_1.isClassInstance)(srcMemberType) &&
|
14507
|
+
types_1.ClassType.isPropertyClass(srcMemberType)) {
|
14508
|
+
if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType, diag, typeVarContext,
|
14509
|
+
/* selfTypeVarContext */ undefined, recursionCount)) {
|
14510
|
+
isAssignable = false;
|
14511
|
+
}
|
14512
|
+
}
|
14513
|
+
else {
|
14514
|
+
const primaryDecl = symbol.getDeclarations()[0];
|
14515
|
+
// Class and instance variables that are mutable need to
|
14516
|
+
// enforce invariance.
|
14517
|
+
const flags = (primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* Variable */ && !primaryDecl.isFinal
|
14518
|
+
? 1 /* EnforceInvariance */
|
14519
|
+
: 0 /* Default */;
|
14520
|
+
if (!assignType(destMemberType, srcMemberType, diag, typeVarContext,
|
14521
|
+
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
14522
|
+
isAssignable = false;
|
14523
|
+
}
|
14524
|
+
}
|
14525
|
+
}
|
14526
|
+
}
|
14527
|
+
});
|
14528
|
+
// Now handle generic base classes.
|
14529
|
+
destType.details.baseClasses.forEach((baseClass) => {
|
14530
|
+
if ((0, types_1.isInstantiableClass)(baseClass) &&
|
14531
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
|
14532
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Protocol') &&
|
14533
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Generic') &&
|
14534
|
+
baseClass.details.typeParameters.length > 0) {
|
14535
|
+
const specializedDestBaseClass = (0, typeUtils_1.specializeForBaseClass)(destType, baseClass);
|
14536
|
+
const specializedSrcBaseClass = (0, typeUtils_1.specializeForBaseClass)(srcType, baseClass);
|
14537
|
+
if (!assignClassToSelf(specializedDestBaseClass, specializedSrcBaseClass, recursionCount)) {
|
14538
|
+
isAssignable = false;
|
14539
|
+
}
|
14540
|
+
}
|
14541
|
+
});
|
14542
|
+
return isAssignable;
|
14543
|
+
}
|
14160
14544
|
function assignTupleTypeArgs(destType, srcType, diag, typeVarContext, flags, recursionCount) {
|
14161
14545
|
var _a, _b;
|
14162
14546
|
const destTypeArgs = [...((_a = destType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [])];
|
@@ -14250,6 +14634,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14250
14634
|
let curSrcType = srcType;
|
14251
14635
|
let curTypeVarContext = destTypeVarContext !== null && destTypeVarContext !== void 0 ? destTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(destType));
|
14252
14636
|
let effectiveFlags = flags;
|
14637
|
+
inferTypeParameterVarianceForClass(destType);
|
14253
14638
|
// If we're using a private typeVarContext, don't skip solving type vars.
|
14254
14639
|
if (!destTypeVarContext) {
|
14255
14640
|
effectiveFlags &= ~8 /* SkipSolveTypeVars */;
|
@@ -14330,6 +14715,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14330
14715
|
function verifyTypeArgumentsAssignable(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
|
14331
14716
|
var _a, _b, _c;
|
14332
14717
|
(0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
|
14718
|
+
inferTypeParameterVarianceForClass(destType);
|
14333
14719
|
const destTypeParams = types_1.ClassType.getTypeParameters(destType);
|
14334
14720
|
let destTypeArgs;
|
14335
14721
|
let srcTypeArgs;
|
@@ -14356,7 +14742,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14356
14742
|
const destTypeArg = destArgIndex >= 0 ? destTypeArgs[destArgIndex] : types_1.UnknownType.create();
|
14357
14743
|
const destTypeParam = destArgIndex < destTypeParams.length ? destTypeParams[destArgIndex] : undefined;
|
14358
14744
|
const assignmentDiag = new diagnostic_1.DiagnosticAddendum();
|
14359
|
-
if (!destTypeParam ||
|
14745
|
+
if (!destTypeParam || types_1.TypeVarType.getVariance(destTypeParam) === 3 /* Covariant */) {
|
14360
14746
|
if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
14361
14747
|
if (diag) {
|
14362
14748
|
if (destTypeParam) {
|
@@ -14373,7 +14759,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14373
14759
|
return false;
|
14374
14760
|
}
|
14375
14761
|
}
|
14376
|
-
else if (
|
14762
|
+
else if (types_1.TypeVarType.getVariance(destTypeParam) === 4 /* Contravariant */) {
|
14377
14763
|
if (!assignType(srcTypeArg, destTypeArg, assignmentDiag, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
14378
14764
|
if (diag) {
|
14379
14765
|
const childDiag = diag.createAddendum();
|
@@ -15056,6 +15442,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15056
15442
|
// matches for types like `tuple[Any]` and `tuple[int]` from being considered
|
15057
15443
|
// proper subtypes of each other.
|
15058
15444
|
function isProperSubtype(destType, srcType, recursionCount) {
|
15445
|
+
// Shortcut the check if either type is Any or Unknown.
|
15446
|
+
if ((0, types_1.isAnyOrUnknown)(destType) || (0, types_1.isAnyOrUnknown)(srcType)) {
|
15447
|
+
return true;
|
15448
|
+
}
|
15449
|
+
// Shortcut the check if either type is a class whose hierarchy contains an unknown type.
|
15450
|
+
if ((0, types_1.isClass)(destType) && destType.details.mro.some((mro) => (0, types_1.isAnyOrUnknown)(mro))) {
|
15451
|
+
return true;
|
15452
|
+
}
|
15453
|
+
if ((0, types_1.isClass)(srcType) && srcType.details.mro.some((mro) => (0, types_1.isAnyOrUnknown)(mro))) {
|
15454
|
+
return true;
|
15455
|
+
}
|
15059
15456
|
return (assignType(destType, srcType,
|
15060
15457
|
/* diag */ undefined,
|
15061
15458
|
/* destTypeVarContext */ undefined,
|
@@ -16347,7 +16744,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16347
16744
|
if (symbol.isClassMember() || symbol.isNamedTupleMemberMember()) {
|
16348
16745
|
let isAbstract;
|
16349
16746
|
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
16350
|
-
if (decl && decl.type ===
|
16747
|
+
if (decl && decl.type === 5 /* Function */) {
|
16351
16748
|
const functionFlags = getFunctionFlagsFromDecorators(decl.node, true);
|
16352
16749
|
isAbstract = !!(functionFlags & 8 /* AbstractMethod */);
|
16353
16750
|
}
|
@@ -16623,6 +17020,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16623
17020
|
assignType,
|
16624
17021
|
validateOverrideMethod,
|
16625
17022
|
assignTypeToExpression,
|
17023
|
+
assignClassToSelf,
|
16626
17024
|
getTypedDictClassType,
|
16627
17025
|
getTupleClassType,
|
16628
17026
|
getObjectType,
|
@@ -16630,6 +17028,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16630
17028
|
getTypingType,
|
16631
17029
|
verifyTypeArgumentsAssignable,
|
16632
17030
|
inferReturnTypeIfNecessary,
|
17031
|
+
inferTypeParameterVarianceForClass,
|
16633
17032
|
addError,
|
16634
17033
|
addWarning,
|
16635
17034
|
addInformation,
|