@zzzen/pyright-internal 1.2.0-dev.20230108 → 1.2.0-dev.20230122
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/dist/analyzer/analyzerFileInfo.js +14 -1
- package/dist/analyzer/analyzerFileInfo.js.map +1 -1
- package/dist/analyzer/backgroundAnalysisProgram.d.ts +3 -3
- package/dist/analyzer/backgroundAnalysisProgram.js +4 -4
- package/dist/analyzer/backgroundAnalysisProgram.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -2
- package/dist/analyzer/checker.js +123 -60
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +7 -7
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +10 -7
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/dataClasses.js +6 -1
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +2 -1
- package/dist/analyzer/importResolver.js +5 -1
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +1 -0
- package/dist/analyzer/parseTreeUtils.js +18 -2
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/program.d.ts +1 -1
- package/dist/analyzer/program.js +18 -13
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/regions.js +8 -12
- package/dist/analyzer/regions.js.map +1 -1
- package/dist/analyzer/service.d.ts +3 -2
- package/dist/analyzer/service.js +15 -13
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.d.ts +3 -2
- package/dist/analyzer/sourceFile.js +4 -4
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/typeCacheUtils.d.ts +2 -1
- package/dist/analyzer/typeCacheUtils.js +5 -1
- package/dist/analyzer/typeCacheUtils.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +477 -353
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +18 -13
- package/dist/analyzer/typeEvaluatorTypes.js +15 -15
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +27 -2
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +32 -12
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +8 -0
- package/dist/analyzer/typeUtils.js +31 -4
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -1
- package/dist/analyzer/types.js +13 -5
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +4 -1
- package/dist/backgroundAnalysisBase.js +1 -1
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.d.ts +5 -2
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/commands/createTypeStub.js +3 -0
- package/dist/commands/createTypeStub.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +4 -0
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/diagnosticRules.d.ts +1 -0
- package/dist/common/diagnosticRules.js +1 -0
- package/dist/common/diagnosticRules.js.map +1 -1
- package/dist/common/envVarUtils.js +30 -7
- package/dist/common/envVarUtils.js.map +1 -1
- package/dist/common/fileSystem.d.ts +1 -0
- package/dist/common/fileSystem.js.map +1 -1
- package/dist/languageServerBase.js +2 -2
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/documentSymbolCollector.d.ts +12 -4
- package/dist/languageService/documentSymbolCollector.js +103 -22
- package/dist/languageService/documentSymbolCollector.js.map +1 -1
- package/dist/languageService/documentSymbolProvider.js +6 -0
- package/dist/languageService/documentSymbolProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +1 -0
- package/dist/languageService/hoverProvider.js +24 -2
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/languageService/indentationUtils.d.ts +1 -1
- package/dist/languageService/indentationUtils.js +86 -30
- package/dist/languageService/indentationUtils.js.map +1 -1
- package/dist/languageService/referencesProvider.d.ts +5 -4
- package/dist/languageService/referencesProvider.js +15 -10
- package/dist/languageService/referencesProvider.js.map +1 -1
- package/dist/languageService/renameModuleProvider.js +11 -11
- package/dist/languageService/renameModuleProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +3 -0
- package/dist/localization/localize.js +3 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +4 -1
- package/dist/parser/stringTokenUtils.js +1 -1
- package/dist/parser/stringTokenUtils.js.map +1 -1
- package/dist/parser/tokenizer.js +6 -2
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/tests/checker.test.js +16 -0
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/documentSymbolCollector.test.js +86 -5
- package/dist/tests/documentSymbolCollector.test.js.map +1 -1
- package/dist/tests/fourslash/hover.overloadedFunction.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/hover.overloadedFunction.fourslash.js +23 -0
- package/dist/tests/fourslash/hover.overloadedFunction.fourslash.js.map +1 -0
- package/dist/tests/fourslash/rename.init.fourslash.d.ts +1 -0
- package/dist/tests/fourslash/rename.init.fourslash.js +23 -0
- package/dist/tests/fourslash/rename.init.fourslash.js.map +1 -0
- package/dist/tests/harness/fourslash/testState.d.ts +2 -2
- package/dist/tests/harness/fourslash/testState.js +9 -6
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/indentationUtils.ptvs.test.js +12 -12
- package/dist/tests/indentationUtils.ptvs.test.js.map +1 -1
- package/dist/tests/indentationUtils.test.js +116 -7
- package/dist/tests/indentationUtils.test.js.map +1 -1
- package/dist/tests/pathUtils.test.js +10 -0
- package/dist/tests/pathUtils.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +16 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +10 -2
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/package.json +3 -3
@@ -323,7 +323,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
323
323
|
}
|
324
324
|
return cacheEntry.typeResult.type;
|
325
325
|
}
|
326
|
-
function writeTypeCache(node, typeResult, flags,
|
326
|
+
function writeTypeCache(node, typeResult, flags, inferenceContext, allowSpeculativeCaching = false) {
|
327
327
|
// Should we use a temporary cache associated with a contextual
|
328
328
|
// analysis of a function, contextualized based on call-site argument types?
|
329
329
|
const typeCacheToUse = returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)
|
@@ -336,16 +336,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
336
336
|
if (speculativeTypeTracker.isSpeculative(node)) {
|
337
337
|
speculativeTypeTracker.trackEntry(typeCacheToUse, node.id);
|
338
338
|
if (allowSpeculativeCaching && !typeResult.isIncomplete) {
|
339
|
-
speculativeTypeTracker.addSpeculativeType(node, typeResult, expectedType);
|
339
|
+
speculativeTypeTracker.addSpeculativeType(node, typeResult, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType);
|
340
340
|
}
|
341
341
|
}
|
342
342
|
}
|
343
|
-
function deleteTypeCacheEntry(node) {
|
344
|
-
const typeCacheToUse = returnTypeInferenceTypeCache && isNodeInReturnTypeInferenceContext(node)
|
345
|
-
? returnTypeInferenceTypeCache
|
346
|
-
: typeCache;
|
347
|
-
typeCacheToUse.delete(node.id);
|
348
|
-
}
|
349
343
|
function setTypeForNode(node, type = types_1.UnknownType.create(), flags = 0 /* None */) {
|
350
344
|
writeTypeCache(node, { type }, flags);
|
351
345
|
}
|
@@ -492,8 +486,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
492
486
|
typedDictClassType = getTypingType(node, '_TypedDict');
|
493
487
|
}
|
494
488
|
}
|
495
|
-
function getTypeOfExpression(node, flags = 0 /* None */,
|
496
|
-
var _a;
|
489
|
+
function getTypeOfExpression(node, flags = 0 /* None */, inferenceContext) {
|
490
|
+
var _a, _b;
|
497
491
|
// Is this type already cached?
|
498
492
|
const cacheEntry = readTypeCacheEntry(node);
|
499
493
|
if (cacheEntry && !cacheEntry.typeResult.isIncomplete) {
|
@@ -504,7 +498,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
504
498
|
}
|
505
499
|
else {
|
506
500
|
// Is it cached in the speculative type cache?
|
507
|
-
const cachedTypeResult = speculativeTypeTracker.getSpeculativeType(node, expectedType);
|
501
|
+
const cachedTypeResult = speculativeTypeTracker.getSpeculativeType(node, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType);
|
508
502
|
if (cachedTypeResult) {
|
509
503
|
if (printExpressionTypes) {
|
510
504
|
console.log(`${getPrintExpressionTypesSpaces()}${ParseTreeUtils.printExpression(node)} (${getLineNum(node)}): Speculative ${printType(cachedTypeResult.type)}`);
|
@@ -520,14 +514,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
520
514
|
// the cancellation check. If the operation is canceled, an exception
|
521
515
|
// will be thrown at this point.
|
522
516
|
checkForCancellation();
|
523
|
-
|
517
|
+
if (inferenceContext) {
|
518
|
+
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
519
|
+
}
|
524
520
|
// If we haven't already fetched some core type definitions from the
|
525
521
|
// typeshed stubs, do so here. It would be better to fetch this when it's
|
526
522
|
// needed in assignType, but we don't have access to the parse tree
|
527
523
|
// at that point.
|
528
524
|
initializedBasicTypes(node);
|
529
525
|
let typeResult;
|
530
|
-
let reportExpectingTypeErrors = (flags &
|
526
|
+
let reportExpectingTypeErrors = (flags & 128 /* ExpectingType */) !== 0;
|
531
527
|
switch (node.nodeType) {
|
532
528
|
case 38 /* Name */: {
|
533
529
|
typeResult = getTypeOfName(node, flags);
|
@@ -542,11 +538,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
542
538
|
break;
|
543
539
|
}
|
544
540
|
case 9 /* Call */: {
|
545
|
-
typeResult = getTypeOfCall(node,
|
541
|
+
typeResult = getTypeOfCall(node, inferenceContext, flags);
|
546
542
|
break;
|
547
543
|
}
|
548
544
|
case 52 /* Tuple */: {
|
549
|
-
typeResult = getTypeOfTuple(node,
|
545
|
+
typeResult = getTypeOfTuple(node, inferenceContext, flags);
|
550
546
|
break;
|
551
547
|
}
|
552
548
|
case 11 /* Constant */: {
|
@@ -572,20 +568,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
572
568
|
break;
|
573
569
|
}
|
574
570
|
case 55 /* UnaryOperation */: {
|
575
|
-
typeResult = getTypeOfUnaryOperation(node,
|
571
|
+
typeResult = getTypeOfUnaryOperation(node, inferenceContext);
|
576
572
|
break;
|
577
573
|
}
|
578
574
|
case 7 /* BinaryOperation */: {
|
579
|
-
typeResult = getTypeOfBinaryOperation(node,
|
575
|
+
typeResult = getTypeOfBinaryOperation(node, inferenceContext, flags);
|
580
576
|
break;
|
581
577
|
}
|
582
578
|
case 5 /* AugmentedAssignment */: {
|
583
|
-
typeResult = getTypeOfAugmentedAssignment(node,
|
579
|
+
typeResult = getTypeOfAugmentedAssignment(node, inferenceContext);
|
584
580
|
break;
|
585
581
|
}
|
586
582
|
case 31 /* List */:
|
587
583
|
case 45 /* Set */: {
|
588
|
-
typeResult = getTypeOfListOrSet(node,
|
584
|
+
typeResult = getTypeOfListOrSet(node, inferenceContext);
|
589
585
|
break;
|
590
586
|
}
|
591
587
|
case 46 /* Slice */: {
|
@@ -593,23 +589,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
593
589
|
break;
|
594
590
|
}
|
595
591
|
case 6 /* Await */: {
|
596
|
-
typeResult = getTypeOfAwaitOperator(node, flags,
|
592
|
+
typeResult = getTypeOfAwaitOperator(node, flags, inferenceContext);
|
597
593
|
break;
|
598
594
|
}
|
599
595
|
case 51 /* Ternary */: {
|
600
|
-
typeResult = getTypeOfTernary(node, flags,
|
596
|
+
typeResult = getTypeOfTernary(node, flags, inferenceContext);
|
601
597
|
break;
|
602
598
|
}
|
603
599
|
case 32 /* ListComprehension */: {
|
604
|
-
typeResult = getTypeOfListComprehension(node,
|
600
|
+
typeResult = getTypeOfListComprehension(node, inferenceContext);
|
605
601
|
break;
|
606
602
|
}
|
607
603
|
case 15 /* Dictionary */: {
|
608
|
-
typeResult = getTypeOfDictionary(node,
|
604
|
+
typeResult = getTypeOfDictionary(node, inferenceContext);
|
609
605
|
break;
|
610
606
|
}
|
611
607
|
case 30 /* Lambda */: {
|
612
|
-
typeResult = getTypeOfLambda(node,
|
608
|
+
typeResult = getTypeOfLambda(node, inferenceContext);
|
613
609
|
break;
|
614
610
|
}
|
615
611
|
case 3 /* Assignment */: {
|
@@ -636,15 +632,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
636
632
|
break;
|
637
633
|
}
|
638
634
|
case 56 /* Unpack */: {
|
639
|
-
typeResult = getTypeOfUnpackOperator(node, flags,
|
635
|
+
typeResult = getTypeOfUnpackOperator(node, flags, inferenceContext);
|
640
636
|
break;
|
641
637
|
}
|
642
638
|
case 54 /* TypeAnnotation */: {
|
643
|
-
typeResult = getTypeOfExpression(node.typeAnnotation,
|
644
|
-
|
639
|
+
typeResult = getTypeOfExpression(node.typeAnnotation, 128 /* ExpectingType */ |
|
640
|
+
256 /* ExpectingTypeAnnotation */ |
|
645
641
|
8 /* EvaluateStringLiteralAsType */ |
|
646
|
-
32 /*
|
647
|
-
|
642
|
+
32 /* DisallowParamSpec */ |
|
643
|
+
64 /* DisallowTypeVarTuple */ |
|
648
644
|
32768 /* VariableTypeAnnotation */);
|
649
645
|
break;
|
650
646
|
}
|
@@ -665,14 +661,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
665
661
|
break;
|
666
662
|
}
|
667
663
|
default:
|
668
|
-
(0, debug_1.assertNever)(node);
|
664
|
+
(0, debug_1.assertNever)(node, `Illegal node type: ${node.nodeType}`);
|
669
665
|
}
|
670
666
|
if (!typeResult) {
|
671
667
|
// We shouldn't get here. If we do, report an error.
|
672
668
|
(0, debug_1.fail)(`Unhandled expression type '${ParseTreeUtils.printExpression(node)}'`);
|
673
669
|
}
|
674
670
|
if (reportExpectingTypeErrors && !typeResult.isIncomplete) {
|
675
|
-
if (flags &
|
671
|
+
if (flags & 64 /* DisallowTypeVarTuple */) {
|
676
672
|
if ((0, types_1.isVariadicTypeVar)(typeResult.type) && !typeResult.type.isVariadicInUnion) {
|
677
673
|
addError(localize_1.Localizer.Diagnostic.typeVarTupleContext(), node);
|
678
674
|
typeResult.type = types_1.UnknownType.create();
|
@@ -694,12 +690,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
694
690
|
typeResult.type.details.illegalRecursionDetected = true;
|
695
691
|
}
|
696
692
|
}
|
697
|
-
writeTypeCache(node, typeResult, flags,
|
698
|
-
if (
|
699
|
-
|
693
|
+
writeTypeCache(node, typeResult, flags, inferenceContext, /* allowSpeculativeCaching */ true);
|
694
|
+
if (inferenceContext &&
|
695
|
+
!(0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) &&
|
696
|
+
!(0, types_1.isNever)(inferenceContext.expectedType)) {
|
697
|
+
expectedTypeCache.set(node.id, inferenceContext.expectedType);
|
700
698
|
if (!typeResult.isIncomplete && !typeResult.expectedTypeDiagAddendum) {
|
701
699
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
702
|
-
|
700
|
+
// Make sure the resulting type is assignable to the expected type.
|
701
|
+
// Use the "solve for scopes" of the associated typeVarContext if
|
702
|
+
// it is provided.
|
703
|
+
if (!assignType(inferenceContext.expectedType, typeResult.type, diag, new typeVarContext_1.TypeVarContext((_b = inferenceContext.typeVarContext) === null || _b === void 0 ? void 0 : _b.getSolveForScopes()))) {
|
704
|
+
typeResult.typeErrors = true;
|
703
705
|
typeResult.expectedTypeDiagAddendum = diag;
|
704
706
|
diag.addTextRange(node);
|
705
707
|
}
|
@@ -711,11 +713,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
711
713
|
}
|
712
714
|
return typeResult;
|
713
715
|
}
|
714
|
-
function getTypeOfAwaitOperator(node, flags,
|
715
|
-
const effectiveExpectedType =
|
716
|
-
? createAwaitableReturnType(node, expectedType, /* isGenerator */ false)
|
716
|
+
function getTypeOfAwaitOperator(node, flags, inferenceContext) {
|
717
|
+
const effectiveExpectedType = inferenceContext
|
718
|
+
? createAwaitableReturnType(node, inferenceContext.expectedType, /* isGenerator */ false)
|
717
719
|
: undefined;
|
718
|
-
const exprTypeResult = getTypeOfExpression(node.expression, flags, effectiveExpectedType);
|
720
|
+
const exprTypeResult = getTypeOfExpression(node.expression, flags, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType));
|
719
721
|
const typeResult = {
|
720
722
|
type: getTypeOfAwaitable(exprTypeResult.type, node.expression),
|
721
723
|
};
|
@@ -728,7 +730,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
728
730
|
if ((flags & 1 /* ConvertEllipsisToAny */) !== 0) {
|
729
731
|
typeResult = { type: types_1.AnyType.create(/* isEllipsis */ true) };
|
730
732
|
}
|
731
|
-
else if ((flags &
|
733
|
+
else if ((flags & 512 /* ConvertEllipsisToUnknown */) !== 0) {
|
732
734
|
typeResult = { type: types_1.UnknownType.create() };
|
733
735
|
}
|
734
736
|
else {
|
@@ -749,19 +751,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
749
751
|
}
|
750
752
|
return typeResult;
|
751
753
|
}
|
752
|
-
function getTypeOfUnpackOperator(node, flags,
|
754
|
+
function getTypeOfUnpackOperator(node, flags, inferenceContext) {
|
753
755
|
var _a;
|
754
756
|
let typeResult;
|
755
757
|
let iterExpectedType;
|
756
|
-
if (
|
758
|
+
if (inferenceContext) {
|
757
759
|
const iterableType = getBuiltInType(node, 'Iterable');
|
758
760
|
if (iterableType && (0, types_1.isInstantiableClass)(iterableType)) {
|
759
|
-
iterExpectedType = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForSpecialization(iterableType, [expectedType],
|
761
|
+
iterExpectedType = types_1.ClassType.cloneAsInstance(types_1.ClassType.cloneForSpecialization(iterableType, [inferenceContext.expectedType],
|
762
|
+
/* isTypeArgumentExplicit */ true));
|
760
763
|
}
|
761
764
|
}
|
762
|
-
const iterTypeResult = getTypeOfExpression(node.expression, flags, iterExpectedType);
|
765
|
+
const iterTypeResult = getTypeOfExpression(node.expression, flags, (0, typeUtils_1.makeInferenceContext)(iterExpectedType));
|
763
766
|
const iterType = iterTypeResult.type;
|
764
|
-
if ((flags &
|
767
|
+
if ((flags & 64 /* DisallowTypeVarTuple */) === 0 &&
|
765
768
|
(0, types_1.isVariadicTypeVar)(iterType) &&
|
766
769
|
!iterType.isVariadicUnpacked) {
|
767
770
|
typeResult = { type: types_1.TypeVarType.cloneForUnpacked(iterType) };
|
@@ -789,7 +792,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
789
792
|
function getTypeOfStringList(node, flags, isExpectingType) {
|
790
793
|
let typeResult;
|
791
794
|
if (isExpectingType) {
|
792
|
-
let updatedFlags = flags | 4 /* AllowForwardReferences */ |
|
795
|
+
let updatedFlags = flags | 4 /* AllowForwardReferences */ | 128 /* ExpectingType */;
|
793
796
|
// In most cases, annotations within a string are not parsed by the interpreter.
|
794
797
|
// There are a few exceptions (e.g. the "bound" value for a TypeVar constructor).
|
795
798
|
if ((flags & 4194304 /* InterpreterParsesStringLiteral */) === 0) {
|
@@ -939,27 +942,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
939
942
|
return specialType;
|
940
943
|
}
|
941
944
|
}
|
942
|
-
let evaluatorFlags =
|
943
|
-
|
945
|
+
let evaluatorFlags = 128 /* ExpectingType */ |
|
946
|
+
256 /* ExpectingTypeAnnotation */ |
|
944
947
|
1 /* ConvertEllipsisToAny */ |
|
945
948
|
8 /* EvaluateStringLiteralAsType */;
|
946
949
|
if (options === null || options === void 0 ? void 0 : options.isVariableAnnotation) {
|
947
950
|
evaluatorFlags |= 32768 /* VariableTypeAnnotation */;
|
948
951
|
}
|
949
952
|
if (!(options === null || options === void 0 ? void 0 : options.allowFinal)) {
|
950
|
-
evaluatorFlags |= 16 /*
|
953
|
+
evaluatorFlags |= 16 /* DisallowFinal */;
|
951
954
|
}
|
952
955
|
if (!(options === null || options === void 0 ? void 0 : options.allowClassVar)) {
|
953
|
-
evaluatorFlags |= 131072 /*
|
956
|
+
evaluatorFlags |= 131072 /* DisallowClassVar */;
|
954
957
|
}
|
955
958
|
if (!(options === null || options === void 0 ? void 0 : options.allowTypeVarTuple)) {
|
956
|
-
evaluatorFlags |=
|
959
|
+
evaluatorFlags |= 64 /* DisallowTypeVarTuple */;
|
957
960
|
}
|
958
961
|
else {
|
959
962
|
evaluatorFlags |= 2097152 /* AllowUnpackedTupleOrTypeVarTuple */;
|
960
963
|
}
|
961
964
|
if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
|
962
|
-
evaluatorFlags |= 32 /*
|
965
|
+
evaluatorFlags |= 32 /* DisallowParamSpec */;
|
963
966
|
}
|
964
967
|
if (options === null || options === void 0 ? void 0 : options.associateTypeVarsWithScope) {
|
965
968
|
evaluatorFlags |= 8192 /* AssociateTypeVarsWithCurrentScope */;
|
@@ -1062,6 +1065,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1062
1065
|
return returnType;
|
1063
1066
|
}
|
1064
1067
|
function canBeFalsy(type, recursionCount = 0) {
|
1068
|
+
type = makeTopLevelTypeVarsConcrete(type);
|
1065
1069
|
if (recursionCount > types_1.maxTypeRecursionCount) {
|
1066
1070
|
return true;
|
1067
1071
|
}
|
@@ -1129,6 +1133,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1129
1133
|
}
|
1130
1134
|
}
|
1131
1135
|
function canBeTruthy(type, recursionCount = 0) {
|
1136
|
+
type = makeTopLevelTypeVarsConcrete(type);
|
1132
1137
|
if (recursionCount > types_1.maxTypeRecursionCount) {
|
1133
1138
|
return true;
|
1134
1139
|
}
|
@@ -1197,16 +1202,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1197
1202
|
// and return only the "None".
|
1198
1203
|
function removeTruthinessFromType(type) {
|
1199
1204
|
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
1200
|
-
|
1201
|
-
|
1205
|
+
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
1206
|
+
if ((0, types_1.isClassInstance)(concreteSubtype)) {
|
1207
|
+
if (concreteSubtype.literalValue !== undefined) {
|
1202
1208
|
// If the object is already definitely falsy, it's fine to
|
1203
1209
|
// include, otherwise it should be removed.
|
1204
|
-
return !
|
1210
|
+
return !concreteSubtype.literalValue ? subtype : undefined;
|
1205
1211
|
}
|
1206
1212
|
// If the object is a bool, make it "false", since
|
1207
1213
|
// "true" is a truthy value.
|
1208
|
-
if (types_1.ClassType.isBuiltIn(
|
1209
|
-
return types_1.ClassType.cloneWithLiteral(
|
1214
|
+
if (types_1.ClassType.isBuiltIn(concreteSubtype, 'bool')) {
|
1215
|
+
return types_1.ClassType.cloneWithLiteral(concreteSubtype, /* value */ false);
|
1210
1216
|
}
|
1211
1217
|
}
|
1212
1218
|
// If it's possible for the type to be falsy, include it.
|
@@ -1222,16 +1228,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1222
1228
|
// and return only the "int".
|
1223
1229
|
function removeFalsinessFromType(type) {
|
1224
1230
|
return (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
1225
|
-
|
1226
|
-
|
1231
|
+
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
1232
|
+
if ((0, types_1.isClassInstance)(concreteSubtype)) {
|
1233
|
+
if (concreteSubtype.literalValue !== undefined) {
|
1227
1234
|
// If the object is already definitely truthy, it's fine to
|
1228
1235
|
// include, otherwise it should be removed.
|
1229
|
-
return
|
1236
|
+
return concreteSubtype.literalValue ? subtype : undefined;
|
1230
1237
|
}
|
1231
1238
|
// If the object is a bool, make it "true", since
|
1232
1239
|
// "false" is a falsy value.
|
1233
|
-
if (types_1.ClassType.isBuiltIn(
|
1234
|
-
return types_1.ClassType.cloneWithLiteral(
|
1240
|
+
if (types_1.ClassType.isBuiltIn(concreteSubtype, 'bool')) {
|
1241
|
+
return types_1.ClassType.cloneWithLiteral(concreteSubtype, /* value */ true);
|
1235
1242
|
}
|
1236
1243
|
}
|
1237
1244
|
// If it's possible for the type to be truthy, include it.
|
@@ -2613,7 +2620,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2613
2620
|
suppressDiagnostics(node.typeExpression, () => {
|
2614
2621
|
callResult = validateConstructorArguments(node.typeExpression, [], concreteSubtype,
|
2615
2622
|
/* skipUnknownArgCheck */ false,
|
2616
|
-
/*
|
2623
|
+
/* inferenceContext */ undefined);
|
2617
2624
|
});
|
2618
2625
|
if (callResult && callResult.argumentErrors) {
|
2619
2626
|
diagAddendum.addMessage(localize_1.Localizer.Diagnostic.exceptionTypeNotInstantiable().format({
|
@@ -2764,14 +2771,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2764
2771
|
else {
|
2765
2772
|
// Look for the scope that contains the value definition and
|
2766
2773
|
// see if it has a declared type.
|
2767
|
-
let symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags &
|
2774
|
+
let symbolWithScope = lookUpSymbolRecursive(node, name, !allowForwardReferences, allowForwardReferences && (flags & 256 /* ExpectingTypeAnnotation */) !== 0);
|
2768
2775
|
if (!symbolWithScope) {
|
2769
2776
|
// If the node is part of a "from X import Y as Z" statement and the node
|
2770
2777
|
// is the "Y" (non-aliased) name, we need to look up the alias symbol
|
2771
2778
|
// since the non-aliased name is not in the symbol table.
|
2772
2779
|
const alias = getAliasFromImport(node);
|
2773
2780
|
if (alias) {
|
2774
|
-
symbolWithScope = lookUpSymbolRecursive(alias, alias.value, !allowForwardReferences, allowForwardReferences && (flags &
|
2781
|
+
symbolWithScope = lookUpSymbolRecursive(alias, alias.value, !allowForwardReferences, allowForwardReferences && (flags & 256 /* ExpectingTypeAnnotation */) !== 0);
|
2775
2782
|
}
|
2776
2783
|
}
|
2777
2784
|
if (symbolWithScope) {
|
@@ -2830,7 +2837,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2830
2837
|
}
|
2831
2838
|
const codeFlowTypeResult = getFlowTypeOfReference(node, symbol.id, typeAtStart,
|
2832
2839
|
/* startNode */ undefined, {
|
2833
|
-
skipConditionalNarrowing: (flags &
|
2840
|
+
skipConditionalNarrowing: (flags & 256 /* ExpectingTypeAnnotation */) !== 0,
|
2834
2841
|
});
|
2835
2842
|
if (codeFlowTypeResult.type) {
|
2836
2843
|
type = codeFlowTypeResult.type;
|
@@ -2850,7 +2857,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2850
2857
|
}
|
2851
2858
|
// Detect, report, and fill in missing type arguments if appropriate.
|
2852
2859
|
type = reportMissingTypeArguments(node, type, flags);
|
2853
|
-
if ((flags &
|
2860
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
2854
2861
|
// Verify that the name does not refer to a (non type alias) variable.
|
2855
2862
|
if (effectiveTypeInfo.includesVariableDecl && !type.typeAliasInfo) {
|
2856
2863
|
let isAllowedTypeForVariable = (0, types_1.isTypeVar)(type) || (0, typeUtils_1.isTypeAliasPlaceholder)(type);
|
@@ -2887,7 +2894,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2887
2894
|
}
|
2888
2895
|
}
|
2889
2896
|
if ((0, types_1.isParamSpec)(type)) {
|
2890
|
-
if (flags & 32 /*
|
2897
|
+
if (flags & 32 /* DisallowParamSpec */) {
|
2891
2898
|
addError(localize_1.Localizer.Diagnostic.paramSpecContext(), node);
|
2892
2899
|
type = types_1.UnknownType.create();
|
2893
2900
|
}
|
@@ -2895,7 +2902,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2895
2902
|
if ((0, types_1.isTypeVar)(type) &&
|
2896
2903
|
!type.details.isParamSpec &&
|
2897
2904
|
!type.isVariadicInUnion &&
|
2898
|
-
(flags &
|
2905
|
+
(flags & 128 /* ExpectingType */) === 0 &&
|
2899
2906
|
type.details.name === name) {
|
2900
2907
|
// Handle the special case of a PEP 604 union. These can appear within
|
2901
2908
|
// an implied type alias where we are not expecting a type.
|
@@ -2915,8 +2922,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2915
2922
|
}
|
2916
2923
|
}
|
2917
2924
|
}
|
2918
|
-
if ((flags &
|
2919
|
-
if ((flags &
|
2925
|
+
if ((flags & 128 /* ExpectingType */) !== 0) {
|
2926
|
+
if ((flags & 1024 /* AllowGenericClassType */) === 0) {
|
2920
2927
|
if ((0, types_1.isInstantiableClass)(type) && types_1.ClassType.isBuiltIn(type, 'Generic')) {
|
2921
2928
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericNotAllowed(), node);
|
2922
2929
|
}
|
@@ -3089,7 +3096,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3089
3096
|
}
|
3090
3097
|
// Is this a generic class that needs to be specialized?
|
3091
3098
|
if ((0, types_1.isInstantiableClass)(type)) {
|
3092
|
-
if ((flags &
|
3099
|
+
if ((flags & 128 /* ExpectingType */) !== 0) {
|
3093
3100
|
if ((0, typeUtils_1.requiresTypeArguments)(type) && !type.typeArguments) {
|
3094
3101
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
|
3095
3102
|
name: type.aliasName || type.details.name,
|
@@ -3101,7 +3108,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3101
3108
|
}
|
3102
3109
|
}
|
3103
3110
|
// Is this a generic type alias that needs to be specialized?
|
3104
|
-
if ((flags &
|
3111
|
+
if ((flags & 128 /* ExpectingType */) !== 0 &&
|
3105
3112
|
type.typeAliasInfo &&
|
3106
3113
|
type.typeAliasInfo.typeParameters &&
|
3107
3114
|
type.typeAliasInfo.typeParameters.length > 0 &&
|
@@ -3255,7 +3262,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3255
3262
|
function getTypeOfMemberAccess(node, flags) {
|
3256
3263
|
const baseTypeFlags = 2 /* DoNotSpecialize */ |
|
3257
3264
|
(flags &
|
3258
|
-
(
|
3265
|
+
(256 /* ExpectingTypeAnnotation */ |
|
3259
3266
|
32768 /* VariableTypeAnnotation */ |
|
3260
3267
|
4 /* AllowForwardReferences */ |
|
3261
3268
|
524288 /* NotParsedByInterpreter */ |
|
@@ -3296,7 +3303,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3296
3303
|
const codeFlowTypeResult = getFlowTypeOfReference(node, symbol_1.indeterminateSymbolId, typeAtStart,
|
3297
3304
|
/* startNode */ undefined, {
|
3298
3305
|
isTypeAtStartIncomplete,
|
3299
|
-
skipConditionalNarrowing: (flags &
|
3306
|
+
skipConditionalNarrowing: (flags & 256 /* ExpectingTypeAnnotation */) !== 0,
|
3300
3307
|
});
|
3301
3308
|
if (codeFlowTypeResult.type) {
|
3302
3309
|
typeResult.type = codeFlowTypeResult.type;
|
@@ -3306,8 +3313,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3306
3313
|
}
|
3307
3314
|
// Detect, report, and fill in missing type arguments if appropriate.
|
3308
3315
|
typeResult.type = reportMissingTypeArguments(node, typeResult.type, flags);
|
3309
|
-
deleteTypeCacheEntry(node);
|
3310
|
-
deleteTypeCacheEntry(node.memberName);
|
3311
3316
|
}
|
3312
3317
|
if (baseTypeResult.isIncomplete) {
|
3313
3318
|
typeResult.isIncomplete = true;
|
@@ -3381,7 +3386,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3381
3386
|
}
|
3382
3387
|
return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
|
3383
3388
|
}
|
3384
|
-
if (flags &
|
3389
|
+
if (flags & 128 /* ExpectingType */) {
|
3385
3390
|
if (!isIncomplete) {
|
3386
3391
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
|
3387
3392
|
type: printType(baseType),
|
@@ -4141,7 +4146,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4141
4146
|
// If this is meant to be a type and the base expression is a string expression,
|
4142
4147
|
// emit an error because this will generate a runtime exception in Python versions
|
4143
4148
|
// less than 3.10.
|
4144
|
-
if (flags &
|
4149
|
+
if (flags & 128 /* ExpectingType */) {
|
4145
4150
|
if (node.baseExpression.nodeType === 48 /* StringList */) {
|
4146
4151
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
4147
4152
|
if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
|
@@ -4197,7 +4202,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4197
4202
|
const codeFlowTypeResult = getFlowTypeOfReference(node, symbol_1.indeterminateSymbolId, indexTypeResult.type,
|
4198
4203
|
/* startNode */ undefined, {
|
4199
4204
|
isTypeAtStartIncomplete: !!baseTypeResult.isIncomplete || !!indexTypeResult.isIncomplete,
|
4200
|
-
skipConditionalNarrowing: (flags &
|
4205
|
+
skipConditionalNarrowing: (flags & 256 /* ExpectingTypeAnnotation */) !== 0,
|
4201
4206
|
});
|
4202
4207
|
if (codeFlowTypeResult.type) {
|
4203
4208
|
indexTypeResult.type = codeFlowTypeResult.type;
|
@@ -4205,14 +4210,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4205
4210
|
if (codeFlowTypeResult.isIncomplete) {
|
4206
4211
|
indexTypeResult.isIncomplete = true;
|
4207
4212
|
}
|
4208
|
-
deleteTypeCacheEntry(node);
|
4209
4213
|
}
|
4210
4214
|
}
|
4211
4215
|
if (baseTypeResult.isIncomplete) {
|
4212
4216
|
indexTypeResult.isIncomplete = true;
|
4213
4217
|
}
|
4214
4218
|
// Handle "Required" and "NotRequired" specially.
|
4215
|
-
if ((flags & 1048576 /*
|
4219
|
+
if ((flags & 1048576 /* AllowRequired */) !== 0) {
|
4216
4220
|
if ((0, types_1.isInstantiableClass)(baseTypeResult.type)) {
|
4217
4221
|
if (types_1.ClassType.isBuiltIn(baseTypeResult.type, 'Required')) {
|
4218
4222
|
indexTypeResult.isRequired = true;
|
@@ -4454,7 +4458,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4454
4458
|
if ((0, types_1.isAnyOrUnknown)(concreteSubtype)) {
|
4455
4459
|
return concreteSubtype;
|
4456
4460
|
}
|
4457
|
-
if (flags &
|
4461
|
+
if (flags & 128 /* ExpectingType */) {
|
4458
4462
|
if ((0, types_1.isTypeVar)(unexpandedSubtype)) {
|
4459
4463
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNotSubscriptable().format({
|
4460
4464
|
type: printType(unexpandedSubtype),
|
@@ -4790,16 +4794,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4790
4794
|
const typeArgs = [];
|
4791
4795
|
let adjFlags = flags;
|
4792
4796
|
if (isFinalAnnotation || isClassVarAnnotation) {
|
4793
|
-
adjFlags |= 131072 /*
|
4797
|
+
adjFlags |= 131072 /* DisallowClassVar */ | 16 /* DisallowFinal */;
|
4794
4798
|
}
|
4795
4799
|
else {
|
4796
4800
|
adjFlags &= ~(2 /* DoNotSpecialize */ |
|
4797
|
-
32 /*
|
4798
|
-
|
4799
|
-
1048576 /*
|
4801
|
+
32 /* DisallowParamSpec */ |
|
4802
|
+
64 /* DisallowTypeVarTuple */ |
|
4803
|
+
1048576 /* AllowRequired */ |
|
4800
4804
|
16384 /* EnforceTypeVarVarianceConsistency */);
|
4801
4805
|
if (!isAnnotatedClass) {
|
4802
|
-
adjFlags |= 131072 /*
|
4806
|
+
adjFlags |= 131072 /* DisallowClassVar */ | 16 /* DisallowFinal */;
|
4803
4807
|
}
|
4804
4808
|
adjFlags |= 2097152 /* AllowUnpackedTupleOrTypeVarTuple */;
|
4805
4809
|
}
|
@@ -4811,10 +4815,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4811
4815
|
// should be treated as a type. The others can be regular (non-type) objects.
|
4812
4816
|
if (hasCustomClassGetItem || (isAnnotatedClass && argIndex > 0)) {
|
4813
4817
|
typeResult = {
|
4814
|
-
...getTypeOfExpression(expr, 32 /*
|
4815
|
-
|
4818
|
+
...getTypeOfExpression(expr, 32 /* DisallowParamSpec */ |
|
4819
|
+
64 /* DisallowTypeVarTuple */ |
|
4816
4820
|
2 /* DoNotSpecialize */ |
|
4817
|
-
131072 /*
|
4821
|
+
131072 /* DisallowClassVar */),
|
4818
4822
|
node: expr,
|
4819
4823
|
};
|
4820
4824
|
}
|
@@ -4861,7 +4865,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4861
4865
|
function getTypeArg(node, flags) {
|
4862
4866
|
let typeResult;
|
4863
4867
|
let adjustedFlags = flags |
|
4864
|
-
|
4868
|
+
128 /* ExpectingType */ |
|
4865
4869
|
1 /* ConvertEllipsisToAny */ |
|
4866
4870
|
8 /* EvaluateStringLiteralAsType */;
|
4867
4871
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
@@ -4885,7 +4889,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4885
4889
|
if ((0, types_1.isClass)(typeResult.type) && types_1.ClassType.isBuiltIn(typeResult.type, 'Protocol')) {
|
4886
4890
|
addError(localize_1.Localizer.Diagnostic.protocolNotAllowedInTypeArgument(), node);
|
4887
4891
|
}
|
4888
|
-
if ((flags & 131072 /*
|
4892
|
+
if ((flags & 131072 /* DisallowClassVar */) !== 0) {
|
4889
4893
|
// "ClassVar" is not allowed as a type argument.
|
4890
4894
|
if ((0, types_1.isClass)(typeResult.type) && types_1.ClassType.isBuiltIn(typeResult.type, 'ClassVar')) {
|
4891
4895
|
addError(localize_1.Localizer.Diagnostic.classVarNotAllowed(), node);
|
@@ -4894,23 +4898,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4894
4898
|
}
|
4895
4899
|
return typeResult;
|
4896
4900
|
}
|
4897
|
-
function getTypeOfTuple(node,
|
4898
|
-
if ((flags &
|
4901
|
+
function getTypeOfTuple(node, inferenceContext, flags) {
|
4902
|
+
if ((flags & 128 /* ExpectingType */) !== 0 && node.expressions.length === 0 && !inferenceContext) {
|
4899
4903
|
return { type: makeTupleObject([]), isEmptyTupleShorthand: true };
|
4900
4904
|
}
|
4901
4905
|
// If the expected type is a union, recursively call for each of the subtypes
|
4902
4906
|
// to find one that matches.
|
4903
|
-
let effectiveExpectedType = expectedType;
|
4904
|
-
let expectedTypeContainsAny =
|
4905
|
-
if (
|
4907
|
+
let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
|
4908
|
+
let expectedTypeContainsAny = inferenceContext && (0, types_1.isAny)(inferenceContext.expectedType);
|
4909
|
+
if (inferenceContext && (0, types_1.isUnion)(inferenceContext.expectedType)) {
|
4906
4910
|
let matchingSubtype;
|
4907
|
-
(0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
|
4911
|
+
(0, typeUtils_1.doForEachSubtype)(inferenceContext.expectedType, (subtype) => {
|
4908
4912
|
if ((0, types_1.isAny)(subtype)) {
|
4909
4913
|
expectedTypeContainsAny = true;
|
4910
4914
|
}
|
4911
4915
|
if (!matchingSubtype) {
|
4912
4916
|
const subtypeResult = useSpeculativeMode(node, () => {
|
4913
|
-
return
|
4917
|
+
return getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
|
4914
4918
|
});
|
4915
4919
|
if (subtypeResult && assignType(subtype, subtypeResult.type)) {
|
4916
4920
|
matchingSubtype = subtype;
|
@@ -4921,7 +4925,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4921
4925
|
}
|
4922
4926
|
let expectedTypeDiagAddendum;
|
4923
4927
|
if (effectiveExpectedType) {
|
4924
|
-
const result =
|
4928
|
+
const result = getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
|
4925
4929
|
if (result && !result.typeErrors) {
|
4926
4930
|
return result;
|
4927
4931
|
}
|
@@ -4935,9 +4939,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4935
4939
|
}
|
4936
4940
|
return { ...typeResult, expectedTypeDiagAddendum };
|
4937
4941
|
}
|
4938
|
-
function
|
4939
|
-
expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedType);
|
4940
|
-
if (!(0, types_1.isClassInstance)(expectedType)) {
|
4942
|
+
function getTypeOfTupleWithContext(node, inferenceContext) {
|
4943
|
+
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
4944
|
+
if (!(0, types_1.isClassInstance)(inferenceContext.expectedType)) {
|
4941
4945
|
return undefined;
|
4942
4946
|
}
|
4943
4947
|
if (!tupleClassType || !(0, types_1.isInstantiableClass)(tupleClassType)) {
|
@@ -4945,9 +4949,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4945
4949
|
}
|
4946
4950
|
// Build an array of expected types.
|
4947
4951
|
let expectedTypes = [];
|
4948
|
-
if ((0, typeUtils_1.isTupleClass)(expectedType) && expectedType.tupleTypeArguments) {
|
4949
|
-
expectedTypes = expectedType.tupleTypeArguments.map((t) => (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(t.type));
|
4950
|
-
const unboundedIndex = expectedType.tupleTypeArguments.findIndex((t) => t.isUnbounded);
|
4952
|
+
if ((0, typeUtils_1.isTupleClass)(inferenceContext.expectedType) && inferenceContext.expectedType.tupleTypeArguments) {
|
4953
|
+
expectedTypes = inferenceContext.expectedType.tupleTypeArguments.map((t) => (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(t.type));
|
4954
|
+
const unboundedIndex = inferenceContext.expectedType.tupleTypeArguments.findIndex((t) => t.isUnbounded);
|
4951
4955
|
if (unboundedIndex >= 0) {
|
4952
4956
|
if (expectedTypes.length > node.expressions.length) {
|
4953
4957
|
expectedTypes.splice(unboundedIndex, 1);
|
@@ -4961,7 +4965,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4961
4965
|
}
|
4962
4966
|
else {
|
4963
4967
|
const tupleTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(tupleClassType));
|
4964
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), expectedType, tupleTypeVarContext, getTypeVarScopesForNode(node))) {
|
4968
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(tupleClassType), inferenceContext.expectedType, tupleTypeVarContext, getTypeVarScopesForNode(node))) {
|
4965
4969
|
return undefined;
|
4966
4970
|
}
|
4967
4971
|
const specializedTuple = (0, typeUtils_1.applySolvedTypeVars)(tupleClassType, tupleTypeVarContext);
|
@@ -4974,7 +4978,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4974
4978
|
}
|
4975
4979
|
}
|
4976
4980
|
const entryTypeResults = node.expressions.map((expr, index) => getTypeOfExpression(expr,
|
4977
|
-
/* flags */ undefined, index < expectedTypes.length ? expectedTypes[index] : undefined));
|
4981
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(index < expectedTypes.length ? expectedTypes[index] : undefined)));
|
4978
4982
|
const isIncomplete = entryTypeResults.some((result) => result.isIncomplete);
|
4979
4983
|
const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults),
|
4980
4984
|
/* isTypeArgumentExplicit */ true));
|
@@ -4997,6 +5001,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4997
5001
|
return { type: types_1.UnknownType.create() };
|
4998
5002
|
}
|
4999
5003
|
const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults)));
|
5004
|
+
// In certain loops, it's possible to construct arbitrarily-deep tuples
|
5005
|
+
// which can lead to infinite type analysis. Prevent this by detecting
|
5006
|
+
// the condition.
|
5007
|
+
if (isIncomplete) {
|
5008
|
+
const maxInferredTupleDepth = 8;
|
5009
|
+
if ((0, typeUtils_1.getTupleDepth)(type) > maxInferredTupleDepth) {
|
5010
|
+
return { type: types_1.UnknownType.create() };
|
5011
|
+
}
|
5012
|
+
}
|
5000
5013
|
return { type, isIncomplete };
|
5001
5014
|
}
|
5002
5015
|
function buildTupleTypesList(entryTypeResults) {
|
@@ -5041,7 +5054,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5041
5054
|
}
|
5042
5055
|
return entryTypes;
|
5043
5056
|
}
|
5044
|
-
function getTypeOfCall(node,
|
5057
|
+
function getTypeOfCall(node, inferenceContext, flags) {
|
5045
5058
|
var _a;
|
5046
5059
|
const baseTypeResult = getTypeOfExpression(node.leftExpression, 2 /* DoNotSpecialize */);
|
5047
5060
|
const argList = node.arguments.map((arg) => {
|
@@ -5063,15 +5076,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5063
5076
|
node.leftExpression.nodeType === 38 /* Name */ &&
|
5064
5077
|
node.leftExpression.value === 'reveal_type') {
|
5065
5078
|
// Handle the implicit "reveal_type" call.
|
5066
|
-
typeResult = getTypeOfRevealType(node,
|
5079
|
+
typeResult = getTypeOfRevealType(node, inferenceContext);
|
5067
5080
|
}
|
5068
5081
|
else if ((0, types_1.isFunction)(baseTypeResult.type) && baseTypeResult.type.details.builtInName === 'reveal_type') {
|
5069
5082
|
// Handle the "typing.reveal_type" call.
|
5070
|
-
typeResult = getTypeOfRevealType(node,
|
5083
|
+
typeResult = getTypeOfRevealType(node, inferenceContext);
|
5071
5084
|
}
|
5072
5085
|
else if ((0, types_1.isFunction)(baseTypeResult.type) && baseTypeResult.type.details.builtInName === 'assert_type') {
|
5073
5086
|
// Handle the "typing.assert_type" call.
|
5074
|
-
typeResult = getTypeOfAssertType(node,
|
5087
|
+
typeResult = getTypeOfAssertType(node, inferenceContext);
|
5075
5088
|
}
|
5076
5089
|
else if ((0, types_1.isAnyOrUnknown)(baseTypeResult.type) &&
|
5077
5090
|
node.leftExpression.nodeType === 38 /* Name */ &&
|
@@ -5087,11 +5100,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5087
5100
|
else {
|
5088
5101
|
const callResult = validateCallArguments(node, argList, baseTypeResult,
|
5089
5102
|
/* typeVarContext */ undefined,
|
5090
|
-
/* skipUnknownArgCheck */ false,
|
5103
|
+
/* skipUnknownArgCheck */ false, inferenceContext);
|
5091
5104
|
typeResult.type = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
|
5092
5105
|
if (callResult.argumentErrors) {
|
5093
5106
|
typeResult.typeErrors = true;
|
5094
5107
|
}
|
5108
|
+
else {
|
5109
|
+
typeResult.overloadsUsedForCall = callResult.overloadsUsedForCall;
|
5110
|
+
}
|
5095
5111
|
if (callResult.isTypeIncomplete) {
|
5096
5112
|
typeResult.isIncomplete = true;
|
5097
5113
|
}
|
@@ -5125,13 +5141,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5125
5141
|
});
|
5126
5142
|
}
|
5127
5143
|
}
|
5128
|
-
if ((flags &
|
5144
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
5129
5145
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAnnotationCall(), node);
|
5130
5146
|
typeResult = { type: types_1.UnknownType.create() };
|
5131
5147
|
}
|
5132
5148
|
return typeResult;
|
5133
5149
|
}
|
5134
|
-
function getTypeOfAssertType(node,
|
5150
|
+
function getTypeOfAssertType(node, inferenceContext) {
|
5135
5151
|
if (node.arguments.length !== 2 ||
|
5136
5152
|
node.arguments[0].argumentCategory !== 0 /* Simple */ ||
|
5137
5153
|
node.arguments[0].name !== undefined ||
|
@@ -5141,7 +5157,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5141
5157
|
return { type: types_1.UnknownType.create() };
|
5142
5158
|
}
|
5143
5159
|
const arg0TypeResult = getTypeOfExpression(node.arguments[0].valueExpression,
|
5144
|
-
/* flags */ undefined,
|
5160
|
+
/* flags */ undefined, inferenceContext);
|
5145
5161
|
if (arg0TypeResult.isIncomplete) {
|
5146
5162
|
return { type: types_1.UnknownType.create(/* isIncomplete */ true), isIncomplete: true };
|
5147
5163
|
}
|
@@ -5154,7 +5170,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5154
5170
|
}
|
5155
5171
|
return { type: arg0TypeResult.type };
|
5156
5172
|
}
|
5157
|
-
function getTypeOfRevealType(node,
|
5173
|
+
function getTypeOfRevealType(node, inferenceContext) {
|
5158
5174
|
let arg0Value;
|
5159
5175
|
let expectedRevealTypeNode;
|
5160
5176
|
let expectedRevealType;
|
@@ -5191,7 +5207,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5191
5207
|
addError(localize_1.Localizer.Diagnostic.revealTypeArgs(), node);
|
5192
5208
|
return { type: types_1.UnknownType.create() };
|
5193
5209
|
}
|
5194
|
-
const typeResult = getTypeOfExpression(arg0Value, /* flags */ undefined,
|
5210
|
+
const typeResult = getTypeOfExpression(arg0Value, /* flags */ undefined, inferenceContext);
|
5195
5211
|
const type = typeResult.type;
|
5196
5212
|
const exprString = ParseTreeUtils.printExpression(arg0Value);
|
5197
5213
|
const typeString = printType(type, { expandTypeAlias: true });
|
@@ -5395,17 +5411,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5395
5411
|
// there will be only one argument list in expandedArgTypes, and all entries
|
5396
5412
|
// (one for each argument) will be undefined. On subsequent calls, this
|
5397
5413
|
// list will grow to include union expansions.
|
5398
|
-
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, typeVarContext, skipUnknownArgCheck,
|
5414
|
+
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
5399
5415
|
var _a;
|
5400
5416
|
const returnTypes = [];
|
5401
5417
|
const matchedOverloads = [];
|
5402
5418
|
let isTypeIncomplete = false;
|
5419
|
+
const overloadsUsedForCall = [];
|
5420
|
+
let isDefinitiveMatchFound = false;
|
5403
5421
|
for (let expandedTypesIndex = 0; expandedTypesIndex < expandedArgTypes.length; expandedTypesIndex++) {
|
5404
5422
|
let matchedOverload;
|
5405
5423
|
const argTypeOverride = expandedArgTypes[expandedTypesIndex];
|
5406
5424
|
const hasArgTypeOverride = argTypeOverride.some((a) => a !== undefined);
|
5407
5425
|
const possibleMatchResults = [];
|
5408
|
-
|
5426
|
+
isDefinitiveMatchFound = false;
|
5409
5427
|
for (let overloadIndex = 0; overloadIndex < argParamMatches.length; overloadIndex++) {
|
5410
5428
|
const overload = argParamMatches[overloadIndex].overload;
|
5411
5429
|
let matchResults = argParamMatches[overloadIndex];
|
@@ -5433,12 +5451,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5433
5451
|
// record any final types in the type cache.
|
5434
5452
|
const callResult = useSpeculativeMode(errorNode, () => {
|
5435
5453
|
return validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, effectiveTypeVarContext,
|
5436
|
-
/* skipUnknownArgCheck */ true,
|
5454
|
+
/* skipUnknownArgCheck */ true, inferenceContext);
|
5437
5455
|
});
|
5438
5456
|
if (callResult.isTypeIncomplete) {
|
5439
5457
|
isTypeIncomplete = true;
|
5440
5458
|
}
|
5441
5459
|
if (!callResult.argumentErrors && callResult.returnType) {
|
5460
|
+
overloadsUsedForCall.push(overload);
|
5442
5461
|
matchedOverload = overload;
|
5443
5462
|
matchedOverloads.push({
|
5444
5463
|
overload: matchedOverload,
|
@@ -5484,14 +5503,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5484
5503
|
returnTypes.push(dedupedMatchResults.length > 1 ? types_1.UnknownType.createPossibleType(combinedTypes) : combinedTypes);
|
5485
5504
|
}
|
5486
5505
|
if (!matchedOverload) {
|
5487
|
-
return { argumentErrors: true, isTypeIncomplete };
|
5506
|
+
return { argumentErrors: true, isTypeIncomplete, overloadsUsedForCall };
|
5488
5507
|
}
|
5489
5508
|
}
|
5490
5509
|
// We found a match for all of the expanded argument lists. Copy the
|
5491
5510
|
// resulting type var context back into the caller's type var context.
|
5492
5511
|
// Use the type var context from the last matched overload because it
|
5493
5512
|
// includes the type var solutions for all earlier matched overloads.
|
5494
|
-
if (typeVarContext) {
|
5513
|
+
if (typeVarContext && isDefinitiveMatchFound) {
|
5495
5514
|
typeVarContext.copyFromClone(matchedOverloads[matchedOverloads.length - 1].typeVarContext);
|
5496
5515
|
}
|
5497
5516
|
// And run through the first expanded argument list one more time to
|
@@ -5499,7 +5518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5499
5518
|
const finalTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : matchedOverloads[0].typeVarContext;
|
5500
5519
|
finalTypeVarContext.unlock();
|
5501
5520
|
finalTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(matchedOverloads[0].overload));
|
5502
|
-
const finalCallResult = validateFunctionArgumentTypesWithExpectedType(errorNode, matchedOverloads[0].matchResults, finalTypeVarContext, skipUnknownArgCheck,
|
5521
|
+
const finalCallResult = validateFunctionArgumentTypesWithExpectedType(errorNode, matchedOverloads[0].matchResults, finalTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5503
5522
|
if (finalCallResult.isTypeIncomplete) {
|
5504
5523
|
isTypeIncomplete = true;
|
5505
5524
|
}
|
@@ -5509,6 +5528,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5509
5528
|
returnType: (0, types_1.combineTypes)(returnTypes),
|
5510
5529
|
isTypeIncomplete,
|
5511
5530
|
specializedInitSelfType: finalCallResult.specializedInitSelfType,
|
5531
|
+
overloadsUsedForCall,
|
5512
5532
|
};
|
5513
5533
|
}
|
5514
5534
|
function getBestOverloadForArguments(errorNode, type, argList) {
|
@@ -5548,7 +5568,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5548
5568
|
return a.overloadIndex - b.overloadIndex;
|
5549
5569
|
});
|
5550
5570
|
}
|
5551
|
-
function validateOverloadedFunctionArguments(errorNode, argList, type, typeVarContext, skipUnknownArgCheck,
|
5571
|
+
function validateOverloadedFunctionArguments(errorNode, argList, type, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
5552
5572
|
let filteredMatchResults = [];
|
5553
5573
|
let contextFreeArgTypes;
|
5554
5574
|
// Start by evaluating the types of the arguments without any expected
|
@@ -5582,7 +5602,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5582
5602
|
diagAddendum.addMessage(localize_1.Localizer.DiagnosticAddendum.argumentTypes().format({ types: argTypes.join(', ') }));
|
5583
5603
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.noOverload().format({ name: functionName }) + diagAddendum.getString(), errorNode);
|
5584
5604
|
}
|
5585
|
-
return { argumentErrors: true, isTypeIncomplete: false };
|
5605
|
+
return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
|
5586
5606
|
}
|
5587
5607
|
// Create a helper lambda that evaluates the overload that matches
|
5588
5608
|
// the arg/param lists.
|
@@ -5595,7 +5615,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5595
5615
|
const effectiveTypeVarContext = typeVarContext !== null && typeVarContext !== void 0 ? typeVarContext : new typeVarContext_1.TypeVarContext();
|
5596
5616
|
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(lastMatch.overload));
|
5597
5617
|
effectiveTypeVarContext.unlock();
|
5598
|
-
return validateFunctionArgumentTypesWithExpectedType(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck,
|
5618
|
+
return validateFunctionArgumentTypesWithExpectedType(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5599
5619
|
};
|
5600
5620
|
// If there is only one possible arg/param match among the overloads,
|
5601
5621
|
// use the normal type matching mechanism because it is faster and
|
@@ -5606,7 +5626,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5606
5626
|
let expandedArgTypes = [argList.map((arg) => undefined)];
|
5607
5627
|
let isTypeIncomplete = false;
|
5608
5628
|
while (true) {
|
5609
|
-
const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, typeVarContext, skipUnknownArgCheck,
|
5629
|
+
const callResult = validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, filteredMatchResults, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
5610
5630
|
if (callResult.isTypeIncomplete) {
|
5611
5631
|
isTypeIncomplete = true;
|
5612
5632
|
}
|
@@ -5618,7 +5638,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5618
5638
|
if (!contextFreeArgTypes) {
|
5619
5639
|
useSpeculativeMode(errorNode, () => {
|
5620
5640
|
// Evaluate the types of each argument expression without regard to
|
5621
|
-
// the
|
5641
|
+
// the context. We'll use this to determine whether we need to do
|
5622
5642
|
// union expansion.
|
5623
5643
|
contextFreeArgTypes = argList.map((arg) => {
|
5624
5644
|
if (arg.typeResult) {
|
@@ -5650,7 +5670,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5650
5670
|
result.returnType = types_1.UnknownType.create();
|
5651
5671
|
return { ...result, argumentErrors: true };
|
5652
5672
|
}
|
5653
|
-
return { argumentErrors: true, isTypeIncomplete: false };
|
5673
|
+
return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
|
5654
5674
|
}
|
5655
5675
|
// Replaces each item in the expandedArgTypes with n items where n is
|
5656
5676
|
// the number of subtypes in a union. The contextFreeArgTypes parameter
|
@@ -5702,13 +5722,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5702
5722
|
// If successful, it returns the resulting (specialized) object type that
|
5703
5723
|
// is allocated by the constructor. If unsuccessful, it records diagnostic
|
5704
5724
|
// information and returns undefined.
|
5705
|
-
function validateConstructorArguments(errorNode, argList, type, skipUnknownArgCheck,
|
5725
|
+
function validateConstructorArguments(errorNode, argList, type, skipUnknownArgCheck, inferenceContext) {
|
5706
5726
|
var _a;
|
5707
5727
|
let validatedTypes = false;
|
5708
5728
|
let returnType;
|
5709
5729
|
let reportedErrors = false;
|
5710
5730
|
let isTypeIncomplete = false;
|
5711
5731
|
let usedMetaclassCallMethod = false;
|
5732
|
+
const overloadsUsedForCall = [];
|
5712
5733
|
// Create a helper function that determines whether we should skip argument
|
5713
5734
|
// validation for either __init__ or __new__. This is required for certain
|
5714
5735
|
// synthesized constructor types, namely NamedTuples.
|
@@ -5726,13 +5747,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5726
5747
|
// If there is an expected type, analyze the constructor call
|
5727
5748
|
// for each of the subtypes that comprise the expected type. If
|
5728
5749
|
// one or more analyzes with no errors, use those results.
|
5729
|
-
if (
|
5730
|
-
const expectedCallResult = validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck,
|
5750
|
+
if (inferenceContext) {
|
5751
|
+
const expectedCallResult = validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, initMethodType);
|
5731
5752
|
if (expectedCallResult) {
|
5732
5753
|
returnType = expectedCallResult.returnType;
|
5733
5754
|
if (expectedCallResult.isTypeIncomplete) {
|
5734
5755
|
isTypeIncomplete = true;
|
5735
5756
|
}
|
5757
|
+
overloadsUsedForCall.push(...expectedCallResult.overloadsUsedForCall);
|
5736
5758
|
}
|
5737
5759
|
}
|
5738
5760
|
if (!returnType) {
|
@@ -5749,10 +5771,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5749
5771
|
adjustedClassType = types_1.ClassType.cloneAsInstantiable(callResult.specializedInitSelfType);
|
5750
5772
|
}
|
5751
5773
|
returnType = applyExpectedTypeForConstructor(adjustedClassType,
|
5752
|
-
/*
|
5774
|
+
/* inferenceContext */ undefined, typeVarContext);
|
5753
5775
|
if (callResult.isTypeIncomplete) {
|
5754
5776
|
isTypeIncomplete = true;
|
5755
5777
|
}
|
5778
|
+
overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
|
5756
5779
|
}
|
5757
5780
|
else {
|
5758
5781
|
reportedErrors = true;
|
@@ -5790,8 +5813,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5790
5813
|
const constructorMethodType = constructorMethodInfo.type;
|
5791
5814
|
// If there is an expected type that was not applied above when
|
5792
5815
|
// handling the __init__ method, try to apply it with the __new__ method.
|
5793
|
-
if (
|
5794
|
-
const expectedCallResult = validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck,
|
5816
|
+
if (inferenceContext && !returnType) {
|
5817
|
+
const expectedCallResult = validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, constructorMethodType);
|
5795
5818
|
if (expectedCallResult) {
|
5796
5819
|
returnType = expectedCallResult.returnType;
|
5797
5820
|
if (expectedCallResult.isTypeIncomplete) {
|
@@ -5806,14 +5829,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5806
5829
|
typeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeId)(constructorMethodType));
|
5807
5830
|
// Skip the unknown argument check if we've already checked for __init__.
|
5808
5831
|
const callResult = validateCallArguments(errorNode, argList, constructorMethodInfo, typeVarContext, skipUnknownArgCheck);
|
5832
|
+
if (callResult.isTypeIncomplete) {
|
5833
|
+
isTypeIncomplete = true;
|
5834
|
+
}
|
5809
5835
|
if (callResult.argumentErrors) {
|
5810
5836
|
reportedErrors = true;
|
5811
5837
|
}
|
5812
5838
|
else {
|
5813
5839
|
let newReturnType = callResult.returnType;
|
5814
|
-
if (callResult.isTypeIncomplete) {
|
5815
|
-
isTypeIncomplete = true;
|
5816
|
-
}
|
5817
5840
|
// If the constructor returned an object whose type matches the class of
|
5818
5841
|
// the original type being constructed, use the return type in case it was
|
5819
5842
|
// specialized. If it doesn't match, we'll fall back on the assumption that
|
@@ -5848,10 +5871,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5848
5871
|
}
|
5849
5872
|
}
|
5850
5873
|
if (!returnType) {
|
5851
|
-
returnType = applyExpectedTypeForConstructor(type,
|
5874
|
+
returnType = applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext);
|
5852
5875
|
}
|
5853
5876
|
else if ((0, types_1.isClassInstance)(returnType) && (0, typeUtils_1.isTupleClass)(returnType) && !returnType.tupleTypeArguments) {
|
5854
|
-
returnType = applyExpectedTypeForTupleConstructor(returnType,
|
5877
|
+
returnType = applyExpectedTypeForTupleConstructor(returnType, inferenceContext);
|
5855
5878
|
}
|
5856
5879
|
validatedTypes = true;
|
5857
5880
|
}
|
@@ -5880,7 +5903,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5880
5903
|
if (!returnType) {
|
5881
5904
|
// There was no __init__ or __new__ method or we couldn't match the provided
|
5882
5905
|
// arguments to them.
|
5883
|
-
if (!
|
5906
|
+
if (!inferenceContext && type.typeArguments) {
|
5884
5907
|
// If there was no expected type but the type was already specialized,
|
5885
5908
|
// assume that we're constructing an instance of the specialized type.
|
5886
5909
|
returnType = (0, typeUtils_1.convertToInstance)(type);
|
@@ -5889,10 +5912,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5889
5912
|
// Do our best to specialize the instantiated class based on the expected
|
5890
5913
|
// type if provided.
|
5891
5914
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
|
5892
|
-
if (
|
5893
|
-
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), expectedType, typeVarContext, getTypeVarScopesForNode(errorNode));
|
5915
|
+
if (inferenceContext) {
|
5916
|
+
(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(errorNode));
|
5894
5917
|
}
|
5895
|
-
returnType = applyExpectedTypeForConstructor(type,
|
5918
|
+
returnType = applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext);
|
5896
5919
|
}
|
5897
5920
|
}
|
5898
5921
|
if (!reportedErrors) {
|
@@ -5909,16 +5932,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5909
5932
|
reportedErrors = true;
|
5910
5933
|
}
|
5911
5934
|
}
|
5912
|
-
const result = {
|
5935
|
+
const result = {
|
5936
|
+
argumentErrors: reportedErrors,
|
5937
|
+
returnType,
|
5938
|
+
isTypeIncomplete,
|
5939
|
+
overloadsUsedForCall,
|
5940
|
+
};
|
5913
5941
|
return result;
|
5914
5942
|
}
|
5915
5943
|
// For a constructor call that targets a generic class and an "expected type"
|
5916
5944
|
// (i.e. bidirectional inference), this function attempts to infer the correct
|
5917
5945
|
// specialized return type for the constructor.
|
5918
|
-
function validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck,
|
5946
|
+
function validateConstructorMethodWithExpectedType(errorNode, argList, type, skipUnknownArgCheck, inferenceContext, constructorMethodType) {
|
5919
5947
|
let isTypeIncomplete = false;
|
5920
5948
|
let argumentErrors = false;
|
5921
|
-
const
|
5949
|
+
const overloadsUsedForCall = [];
|
5950
|
+
const returnType = (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (expectedSubType) => {
|
5922
5951
|
expectedSubType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedSubType);
|
5923
5952
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(type));
|
5924
5953
|
if ((0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, types_1.ClassType.cloneAsInstance(type), expectedSubType, typeVarContext, getTypeVarScopesForNode(errorNode))) {
|
@@ -5936,6 +5965,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5936
5965
|
if (callResult.argumentErrors) {
|
5937
5966
|
argumentErrors = true;
|
5938
5967
|
}
|
5968
|
+
overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
|
5939
5969
|
return applyExpectedSubtypeForConstructor(type, expectedSubType, typeVarContext);
|
5940
5970
|
}
|
5941
5971
|
}
|
@@ -5944,7 +5974,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5944
5974
|
if ((0, types_1.isNever)(returnType)) {
|
5945
5975
|
return undefined;
|
5946
5976
|
}
|
5947
|
-
return { returnType, isTypeIncomplete, argumentErrors };
|
5977
|
+
return { returnType, isTypeIncomplete, argumentErrors, overloadsUsedForCall };
|
5948
5978
|
}
|
5949
5979
|
function applyExpectedSubtypeForConstructor(type, expectedSubtype, typeVarContext) {
|
5950
5980
|
const specializedType = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstance(type), typeVarContext);
|
@@ -5959,10 +5989,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5959
5989
|
}
|
5960
5990
|
// Handles the case where a constructor is a generic type and the type
|
5961
5991
|
// arguments are not specified but can be provided by the expected type.
|
5962
|
-
function applyExpectedTypeForConstructor(type,
|
5992
|
+
function applyExpectedTypeForConstructor(type, inferenceContext, typeVarContext) {
|
5963
5993
|
let unsolvedTypeVarsAreUnknown = true;
|
5964
|
-
if (
|
5965
|
-
const specializedExpectedType = (0, typeUtils_1.mapSubtypes)(expectedType, (expectedSubtype) => {
|
5994
|
+
if (inferenceContext) {
|
5995
|
+
const specializedExpectedType = (0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (expectedSubtype) => {
|
5966
5996
|
return applyExpectedSubtypeForConstructor(type, expectedSubtype, typeVarContext);
|
5967
5997
|
});
|
5968
5998
|
if (!(0, types_1.isNever)(specializedExpectedType)) {
|
@@ -5982,13 +6012,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5982
6012
|
}
|
5983
6013
|
// Similar to applyExpectedTypeForConstructor, this function handles the
|
5984
6014
|
// special case of the tuple class.
|
5985
|
-
function applyExpectedTypeForTupleConstructor(type,
|
6015
|
+
function applyExpectedTypeForTupleConstructor(type, inferenceContext) {
|
5986
6016
|
let specializedType = type;
|
5987
|
-
if (
|
5988
|
-
(0, types_1.isClassInstance)(expectedType) &&
|
5989
|
-
(0, typeUtils_1.isTupleClass)(expectedType) &&
|
5990
|
-
expectedType.tupleTypeArguments) {
|
5991
|
-
specializedType = (0, typeUtils_1.specializeTupleClass)(type, expectedType.tupleTypeArguments);
|
6017
|
+
if (inferenceContext &&
|
6018
|
+
(0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
6019
|
+
(0, typeUtils_1.isTupleClass)(inferenceContext.expectedType) &&
|
6020
|
+
inferenceContext.expectedType.tupleTypeArguments) {
|
6021
|
+
specializedType = (0, typeUtils_1.specializeTupleClass)(type, inferenceContext.expectedType.tupleTypeArguments);
|
5992
6022
|
}
|
5993
6023
|
return specializedType;
|
5994
6024
|
}
|
@@ -5996,12 +6026,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5996
6026
|
// list, specializes the call based on arg types, and returns the
|
5997
6027
|
// specialized type of the return value. If it detects an error along
|
5998
6028
|
// the way, it emits a diagnostic and sets argumentErrors to true.
|
5999
|
-
function validateCallArguments(errorNode, argList, callTypeResult, typeVarContext, skipUnknownArgCheck = false,
|
6029
|
+
function validateCallArguments(errorNode, argList, callTypeResult, typeVarContext, skipUnknownArgCheck = false, inferenceContext, recursionCount = 0) {
|
6000
6030
|
let argumentErrors = false;
|
6001
6031
|
let isTypeIncomplete = false;
|
6002
6032
|
let specializedInitSelfType;
|
6033
|
+
const overloadsUsedForCall = [];
|
6003
6034
|
if (recursionCount > types_1.maxTypeRecursionCount) {
|
6004
|
-
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6035
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
6005
6036
|
}
|
6006
6037
|
recursionCount++;
|
6007
6038
|
if (types_1.TypeBase.isSpecialForm(callTypeResult.type)) {
|
@@ -6010,7 +6041,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6010
6041
|
expression: ParseTreeUtils.printExpression(exprNode),
|
6011
6042
|
type: printType(callTypeResult.type, { expandTypeAlias: true }),
|
6012
6043
|
}), exprNode);
|
6013
|
-
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6044
|
+
return { returnType: types_1.UnknownType.create(), argumentErrors: true, overloadsUsedForCall };
|
6014
6045
|
}
|
6015
6046
|
const returnType = mapSubtypesExpandTypeVars(callTypeResult.type,
|
6016
6047
|
/* conditionFilter */ undefined, (expandedSubtype, unexpandedSubtype) => {
|
@@ -6054,10 +6085,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6054
6085
|
effectiveTypeVarContext.addSolveForScope(types_1.WildcardTypeVarScopeId);
|
6055
6086
|
}
|
6056
6087
|
}
|
6057
|
-
const functionResult = validateFunctionArguments(errorNode, argList, expandedSubtype, effectiveTypeVarContext, skipUnknownArgCheck,
|
6088
|
+
const functionResult = validateFunctionArguments(errorNode, argList, expandedSubtype, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6058
6089
|
if (functionResult.isTypeIncomplete) {
|
6059
6090
|
isTypeIncomplete = true;
|
6060
6091
|
}
|
6092
|
+
overloadsUsedForCall.push(...functionResult.overloadsUsedForCall);
|
6061
6093
|
if (functionResult.argumentErrors) {
|
6062
6094
|
argumentErrors = true;
|
6063
6095
|
}
|
@@ -6102,7 +6134,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6102
6134
|
}
|
6103
6135
|
return (0, typeUtils_1.convertToInstance)(castToType);
|
6104
6136
|
}
|
6105
|
-
const functionResult = validateOverloadedFunctionArguments(errorNode, argList, expandedSubtype, typeVarContext, skipUnknownArgCheck,
|
6137
|
+
const functionResult = validateOverloadedFunctionArguments(errorNode, argList, expandedSubtype, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
6138
|
+
overloadsUsedForCall.push(...functionResult.overloadsUsedForCall);
|
6106
6139
|
if (functionResult.isTypeIncomplete) {
|
6107
6140
|
isTypeIncomplete = true;
|
6108
6141
|
}
|
@@ -6138,7 +6171,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6138
6171
|
const className = expandedSubtype.aliasName || expandedSubtype.details.name;
|
6139
6172
|
if (className === 'type') {
|
6140
6173
|
// Validate the constructor arguments.
|
6141
|
-
validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck,
|
6174
|
+
validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6142
6175
|
// Handle the 'type' call specially.
|
6143
6176
|
if (argList.length === 1) {
|
6144
6177
|
// The one-parameter form of "type" returns the class
|
@@ -6234,7 +6267,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6234
6267
|
}), errorNode);
|
6235
6268
|
}
|
6236
6269
|
// Assume this is a call to the constructor.
|
6237
|
-
const constructorResult = validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck,
|
6270
|
+
const constructorResult = validateConstructorArguments(errorNode, argList, expandedSubtype, skipUnknownArgCheck, inferenceContext);
|
6271
|
+
overloadsUsedForCall.push(...constructorResult.overloadsUsedForCall);
|
6238
6272
|
if (constructorResult.argumentErrors) {
|
6239
6273
|
argumentErrors = true;
|
6240
6274
|
}
|
@@ -6274,7 +6308,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6274
6308
|
else {
|
6275
6309
|
const memberType = (_d = getTypeOfObjectMember(errorNode, expandedSubtype, '__call__')) === null || _d === void 0 ? void 0 : _d.type;
|
6276
6310
|
if (memberType) {
|
6277
|
-
const functionResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck,
|
6311
|
+
const functionResult = validateCallArguments(errorNode, argList, { type: memberType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6312
|
+
overloadsUsedForCall.push(...functionResult.overloadsUsedForCall);
|
6278
6313
|
if (functionResult.argumentErrors) {
|
6279
6314
|
argumentErrors = true;
|
6280
6315
|
}
|
@@ -6306,7 +6341,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6306
6341
|
// need to handle recursive type aliases.
|
6307
6342
|
case 10 /* TypeVar */: {
|
6308
6343
|
expandedSubtype = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expandedSubtype);
|
6309
|
-
const callResult = validateCallArguments(errorNode, argList, { type: expandedSubtype }, typeVarContext, skipUnknownArgCheck,
|
6344
|
+
const callResult = validateCallArguments(errorNode, argList, { type: expandedSubtype }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6345
|
+
overloadsUsedForCall.push(...callResult.overloadsUsedForCall);
|
6310
6346
|
if (callResult.argumentErrors) {
|
6311
6347
|
argumentErrors = true;
|
6312
6348
|
}
|
@@ -6324,6 +6360,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6324
6360
|
returnType: (0, types_1.isNever)(returnType) && !returnType.isNoReturn ? undefined : returnType,
|
6325
6361
|
isTypeIncomplete,
|
6326
6362
|
specializedInitSelfType,
|
6363
|
+
overloadsUsedForCall,
|
6327
6364
|
};
|
6328
6365
|
}
|
6329
6366
|
// Expands any unpacked tuples within an argument list.
|
@@ -7129,19 +7166,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7129
7166
|
// After having matched arguments with parameters, this function evaluates the
|
7130
7167
|
// types of each argument expression and validates that the resulting type is
|
7131
7168
|
// compatible with the declared type of the corresponding parameter.
|
7132
|
-
function validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, typeVarContext, skipUnknownArgCheck = false,
|
7169
|
+
function validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, typeVarContext, skipUnknownArgCheck = false, inferenceContext) {
|
7133
7170
|
var _a;
|
7134
7171
|
const type = matchResults.overload;
|
7135
|
-
if (!
|
7136
|
-
(0, types_1.isAnyOrUnknown)(expectedType) ||
|
7137
|
-
(0, types_1.isNever)(expectedType) ||
|
7138
|
-
(0, typeUtils_1.requiresSpecialization)(expectedType) ||
|
7172
|
+
if (!inferenceContext ||
|
7173
|
+
(0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) ||
|
7174
|
+
(0, types_1.isNever)(inferenceContext.expectedType) ||
|
7175
|
+
(0, typeUtils_1.requiresSpecialization)(inferenceContext.expectedType) ||
|
7139
7176
|
!type.details.declaredReturnType ||
|
7140
7177
|
!(0, typeUtils_1.requiresSpecialization)((_a = types_1.FunctionType.getSpecializedReturnType(type)) !== null && _a !== void 0 ? _a : types_1.UnknownType.create())) {
|
7141
7178
|
return validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, skipUnknownArgCheck);
|
7142
7179
|
}
|
7143
7180
|
const effectiveReturnType = getFunctionEffectiveReturnType(type);
|
7144
|
-
let effectiveExpectedType = expectedType;
|
7181
|
+
let effectiveExpectedType = inferenceContext.expectedType;
|
7145
7182
|
let effectiveFlags = 0 /* Default */;
|
7146
7183
|
if ((0, typeUtils_1.containsLiteralType)(effectiveExpectedType, /* includeTypeArgs */ true)) {
|
7147
7184
|
effectiveFlags |= 128 /* RetainLiteralsForTypeVar */;
|
@@ -7149,7 +7186,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7149
7186
|
// If the expected type is a union, we don't know which type is expected.
|
7150
7187
|
// We may or may not be able to make use of the expected type. We'll evaluate
|
7151
7188
|
// speculatively to see if using the expected type works.
|
7152
|
-
if ((0, types_1.isUnion)(expectedType)) {
|
7189
|
+
if ((0, types_1.isUnion)(inferenceContext.expectedType)) {
|
7153
7190
|
let speculativeResults;
|
7154
7191
|
useSpeculativeMode(errorNode, () => {
|
7155
7192
|
const typeVarContextCopy = typeVarContext.clone();
|
@@ -7400,6 +7437,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7400
7437
|
isTypeIncomplete,
|
7401
7438
|
activeParam: matchResults.activeParam,
|
7402
7439
|
specializedInitSelfType,
|
7440
|
+
overloadsUsedForCall: argumentErrors ? [] : [type],
|
7403
7441
|
};
|
7404
7442
|
}
|
7405
7443
|
function adjustCallableReturnType(type) {
|
@@ -7419,7 +7457,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7419
7457
|
// Tries to assign the call arguments to the function parameter
|
7420
7458
|
// list and reports any mismatches in types or counts. Returns the
|
7421
7459
|
// specialized return type of the call.
|
7422
|
-
function validateFunctionArguments(errorNode, argList, type, typeVarContext, skipUnknownArgCheck = false,
|
7460
|
+
function validateFunctionArguments(errorNode, argList, type, typeVarContext, skipUnknownArgCheck = false, inferenceContext) {
|
7423
7461
|
const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, type, 0);
|
7424
7462
|
if (matchResults.argumentErrors) {
|
7425
7463
|
// Evaluate types of all args. This will ensure that referenced symbols are
|
@@ -7432,9 +7470,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7432
7470
|
return {
|
7433
7471
|
argumentErrors: true,
|
7434
7472
|
activeParam: matchResults.activeParam,
|
7473
|
+
overloadsUsedForCall: [],
|
7435
7474
|
};
|
7436
7475
|
}
|
7437
|
-
return validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, typeVarContext, skipUnknownArgCheck,
|
7476
|
+
return validateFunctionArgumentTypesWithExpectedType(errorNode, matchResults, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
7438
7477
|
}
|
7439
7478
|
// Determines whether the specified argument list satisfies the function
|
7440
7479
|
// signature bound to the specified ParamSpec. Return value indicates success.
|
@@ -7558,11 +7597,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7558
7597
|
// to true if this is the first pass through the parameter list because
|
7559
7598
|
// a wide bound on a TypeVar (if a narrow bound has not yet been established)
|
7560
7599
|
// will unnecessarily constrain the expected type.
|
7561
|
-
let expectedType
|
7562
|
-
|
7563
|
-
argParam.paramType
|
7564
|
-
|
7565
|
-
: (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, { useNarrowBoundOnly });
|
7600
|
+
let expectedType;
|
7601
|
+
if (!(0, types_1.isTypeVar)(argParam.paramType) || argParam.paramType.scopeId !== (functionType === null || functionType === void 0 ? void 0 : functionType.details.typeVarScopeId)) {
|
7602
|
+
expectedType = (0, typeUtils_1.applySolvedTypeVars)(argParam.paramType, typeVarContext, { useNarrowBoundOnly });
|
7603
|
+
}
|
7566
7604
|
// If the expected type is unknown, don't use an expected type. Instead,
|
7567
7605
|
// use default rules for evaluating the expression type.
|
7568
7606
|
if (expectedType && (0, types_1.isUnknown)(expectedType)) {
|
@@ -7575,10 +7613,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7575
7613
|
else {
|
7576
7614
|
const flags = argParam.expectingType
|
7577
7615
|
? 8 /* EvaluateStringLiteralAsType */ |
|
7578
|
-
32 /*
|
7579
|
-
|
7616
|
+
32 /* DisallowParamSpec */ |
|
7617
|
+
64 /* DisallowTypeVarTuple */
|
7580
7618
|
: 0 /* None */;
|
7581
|
-
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, expectedType);
|
7619
|
+
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedType, typeVarContext));
|
7582
7620
|
argType = exprTypeResult.type;
|
7583
7621
|
if (exprTypeResult.isIncomplete) {
|
7584
7622
|
isTypeIncomplete = true;
|
@@ -7591,7 +7629,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7591
7629
|
if (argParam.argument &&
|
7592
7630
|
argParam.argument.name &&
|
7593
7631
|
!speculativeTypeTracker.isSpeculative(argParam.errorNode)) {
|
7594
|
-
writeTypeCache(argParam.argument.name, { type: expectedType
|
7632
|
+
writeTypeCache(argParam.argument.name, { type: expectedType !== null && expectedType !== void 0 ? expectedType : argType, isIncomplete: isTypeIncomplete }, 0 /* None */);
|
7595
7633
|
}
|
7596
7634
|
}
|
7597
7635
|
else {
|
@@ -7601,8 +7639,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7601
7639
|
}
|
7602
7640
|
else if (argParam.expectingType && !argParam.argument.typeResult && argParam.argument.valueExpression) {
|
7603
7641
|
const argTypeResult = getTypeOfExpression(argParam.argument.valueExpression, 8 /* EvaluateStringLiteralAsType */ |
|
7604
|
-
32 /*
|
7605
|
-
|
7642
|
+
32 /* DisallowParamSpec */ |
|
7643
|
+
64 /* DisallowTypeVarTuple */);
|
7606
7644
|
argType = argTypeResult.type;
|
7607
7645
|
if (argTypeResult.isIncomplete) {
|
7608
7646
|
isTypeIncomplete = true;
|
@@ -8139,7 +8177,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8139
8177
|
function getTypeOfConstant(node, flags) {
|
8140
8178
|
let type;
|
8141
8179
|
if (node.constType === 26 /* None */) {
|
8142
|
-
type = (flags &
|
8180
|
+
type = (flags & 128 /* ExpectingType */) !== 0 ? types_1.NoneType.createType() : types_1.NoneType.createInstance();
|
8143
8181
|
}
|
8144
8182
|
else if (node.constType === 33 /* True */ ||
|
8145
8183
|
node.constType === 15 /* False */ ||
|
@@ -8161,7 +8199,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8161
8199
|
}
|
8162
8200
|
return { type };
|
8163
8201
|
}
|
8164
|
-
function getTypeOfUnaryOperation(node,
|
8202
|
+
function getTypeOfUnaryOperation(node, inferenceContext) {
|
8165
8203
|
const exprTypeResult = getTypeOfExpression(node.expression);
|
8166
8204
|
let exprType = makeTopLevelTypeVarsConcrete(exprTypeResult.type);
|
8167
8205
|
const isIncomplete = exprTypeResult.isIncomplete;
|
@@ -8224,15 +8262,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8224
8262
|
}
|
8225
8263
|
else {
|
8226
8264
|
const magicMethodName = unaryOperatorMap[node.operator];
|
8227
|
-
type = getTypeOfMagicMethodReturn(exprType, [], magicMethodName, node,
|
8265
|
+
type = getTypeOfMagicMethodReturn(exprType, [], magicMethodName, node, inferenceContext);
|
8228
8266
|
}
|
8229
8267
|
if (!type) {
|
8230
8268
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
8231
|
-
if (
|
8269
|
+
if (inferenceContext) {
|
8232
8270
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeNotSupportUnaryOperatorBidirectional().format({
|
8233
8271
|
operator: ParseTreeUtils.printOperator(node.operator),
|
8234
8272
|
type: printType(exprType),
|
8235
|
-
expectedType: printType(expectedType),
|
8273
|
+
expectedType: printType(inferenceContext.expectedType),
|
8236
8274
|
}), node);
|
8237
8275
|
}
|
8238
8276
|
else {
|
@@ -8247,10 +8285,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8247
8285
|
}
|
8248
8286
|
return { type, isIncomplete };
|
8249
8287
|
}
|
8250
|
-
function getTypeOfBinaryOperation(node,
|
8288
|
+
function getTypeOfBinaryOperation(node, inferenceContext, flags) {
|
8251
8289
|
const leftExpression = node.leftExpression;
|
8252
8290
|
let rightExpression = node.rightExpression;
|
8253
8291
|
let isIncomplete = false;
|
8292
|
+
let typeErrors = false;
|
8254
8293
|
// If this is a comparison and the left expression is also a comparison,
|
8255
8294
|
// we need to change the behavior to accommodate python's "chained
|
8256
8295
|
// comparisons" feature.
|
@@ -8259,7 +8298,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8259
8298
|
!rightExpression.parenthesized &&
|
8260
8299
|
ParseTreeUtils.operatorSupportsChaining(rightExpression.operator)) {
|
8261
8300
|
// Evaluate the right expression so it is type checked.
|
8262
|
-
getTypeOfBinaryOperation(rightExpression,
|
8301
|
+
getTypeOfBinaryOperation(rightExpression, inferenceContext, flags);
|
8263
8302
|
// Use the left side of the right expression for comparison purposes.
|
8264
8303
|
rightExpression = rightExpression.leftExpression;
|
8265
8304
|
}
|
@@ -8267,21 +8306,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8267
8306
|
// For most binary operations, the "expected type" is applied to the output
|
8268
8307
|
// of the magic method for that operation. However, the "or" and "and" operators
|
8269
8308
|
// have no magic method, so we apply the expected type directly to both operands.
|
8270
|
-
let expectedOperandType = node.operator === 37 /* Or */ || node.operator === 36 /* And */
|
8309
|
+
let expectedOperandType = node.operator === 37 /* Or */ || node.operator === 36 /* And */
|
8310
|
+
? inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType
|
8311
|
+
: undefined;
|
8271
8312
|
// Handle the very special case where the expected type is a list
|
8272
8313
|
// and the operator is a multiply. This comes up in the common case
|
8273
8314
|
// of "x: List[Optional[X]] = [None] * y" where y is an integer literal.
|
8274
8315
|
let expectedLeftOperandType;
|
8275
8316
|
if (node.operator === 26 /* Multiply */ &&
|
8276
|
-
|
8277
|
-
(0, types_1.isClassInstance)(expectedType) &&
|
8278
|
-
types_1.ClassType.isBuiltIn(expectedType, 'list') &&
|
8279
|
-
expectedType.typeArguments &&
|
8280
|
-
expectedType.typeArguments.length >= 1 &&
|
8317
|
+
inferenceContext &&
|
8318
|
+
(0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
8319
|
+
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'list') &&
|
8320
|
+
inferenceContext.expectedType.typeArguments &&
|
8321
|
+
inferenceContext.expectedType.typeArguments.length >= 1 &&
|
8281
8322
|
node.leftExpression.nodeType === 31 /* List */) {
|
8282
|
-
expectedLeftOperandType = expectedType;
|
8323
|
+
expectedLeftOperandType = inferenceContext.expectedType;
|
8283
8324
|
}
|
8284
|
-
const
|
8325
|
+
const effectiveExpectedType = expectedOperandType !== null && expectedOperandType !== void 0 ? expectedOperandType : expectedLeftOperandType;
|
8326
|
+
const leftTypeResult = getTypeOfExpression(leftExpression, flags, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType));
|
8285
8327
|
let leftType = leftTypeResult.type;
|
8286
8328
|
if (!expectedOperandType) {
|
8287
8329
|
if (node.operator === 37 /* Or */ || node.operator === 36 /* And */) {
|
@@ -8302,7 +8344,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8302
8344
|
}
|
8303
8345
|
}
|
8304
8346
|
}
|
8305
|
-
const rightTypeResult = getTypeOfExpression(rightExpression, flags, expectedOperandType);
|
8347
|
+
const rightTypeResult = getTypeOfExpression(rightExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedOperandType));
|
8306
8348
|
let rightType = rightTypeResult.type;
|
8307
8349
|
if (leftTypeResult.isIncomplete || rightTypeResult.isIncomplete) {
|
8308
8350
|
isIncomplete = true;
|
@@ -8396,8 +8438,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8396
8438
|
// incomplete because we may be evaluating types within a loop,
|
8397
8439
|
// so the literal values may change each time.
|
8398
8440
|
const isLiteralMathAllowed = !ParseTreeUtils.isWithinLoop(node);
|
8399
|
-
|
8441
|
+
// Don't special-case tuple __add__ if the left type is a union. This
|
8442
|
+
// can result in an infinite loop if we keep creating new tuple types
|
8443
|
+
// within a loop construct using __add__.
|
8444
|
+
const isTupleAddAllowed = !(0, types_1.isUnion)(leftType);
|
8445
|
+
let type = validateBinaryOperation(node.operator, { type: leftType, isIncomplete: leftTypeResult.isIncomplete }, { type: rightType, isIncomplete: rightTypeResult.isIncomplete }, node, inferenceContext, diag, { isLiteralMathAllowed, isTupleAddAllowed });
|
8400
8446
|
if (!diag.isEmpty() || !type) {
|
8447
|
+
typeErrors = true;
|
8401
8448
|
if (!isIncomplete) {
|
8402
8449
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
8403
8450
|
if (isLeftOptionalType && diag.getMessages().length === 1) {
|
@@ -8419,7 +8466,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8419
8466
|
}
|
8420
8467
|
type = types_1.UnknownType.create();
|
8421
8468
|
}
|
8422
|
-
return { type, isIncomplete };
|
8469
|
+
return { type, isIncomplete, typeErrors };
|
8423
8470
|
}
|
8424
8471
|
function customMetaclassSupportsMethod(type, methodName) {
|
8425
8472
|
if (!(0, types_1.isInstantiableClass)(type)) {
|
@@ -8441,7 +8488,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8441
8488
|
}
|
8442
8489
|
return true;
|
8443
8490
|
}
|
8444
|
-
function getTypeOfAugmentedAssignment(node,
|
8491
|
+
function getTypeOfAugmentedAssignment(node, inferenceContext) {
|
8445
8492
|
const operatorMap = {
|
8446
8493
|
[1 /* AddEqual */]: ['__iadd__', 0 /* Add */],
|
8447
8494
|
[34 /* SubtractEqual */]: ['__isub__', 33 /* Subtract */],
|
@@ -8468,7 +8515,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8468
8515
|
// us to support the case where a TypedDict is being updated with a dict expression.
|
8469
8516
|
expectedOperandType = leftType;
|
8470
8517
|
}
|
8471
|
-
const rightTypeResult = getTypeOfExpression(node.rightExpression,
|
8518
|
+
const rightTypeResult = getTypeOfExpression(node.rightExpression,
|
8519
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedOperandType));
|
8472
8520
|
const rightType = rightTypeResult.type;
|
8473
8521
|
const isIncomplete = !!rightTypeResult.isIncomplete || !!leftTypeResult.isIncomplete;
|
8474
8522
|
if ((0, types_1.isNever)(leftType) || (0, types_1.isNever)(rightType)) {
|
@@ -8482,14 +8530,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8482
8530
|
return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
|
8483
8531
|
}
|
8484
8532
|
const magicMethodName = operatorMap[node.operator][0];
|
8485
|
-
let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node,
|
8533
|
+
let returnType = getTypeOfMagicMethodReturn(leftSubtypeUnexpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
|
8486
8534
|
if (!returnType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
8487
8535
|
// Try with the expanded left type.
|
8488
|
-
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node,
|
8536
|
+
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
|
8489
8537
|
}
|
8490
8538
|
if (!returnType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
8491
8539
|
// Try with the expanded left and right type.
|
8492
|
-
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node,
|
8540
|
+
returnType = getTypeOfMagicMethodReturn(leftSubtypeExpanded, [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, node, inferenceContext);
|
8493
8541
|
}
|
8494
8542
|
if (!returnType) {
|
8495
8543
|
// If the LHS class didn't support the magic method for augmented
|
@@ -8502,7 +8550,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8502
8550
|
!rightTypeResult.isIncomplete &&
|
8503
8551
|
(0, typeUtils_1.getUnionSubtypeCount)(leftType) * (0, typeUtils_1.getUnionSubtypeCount)(rightType) <
|
8504
8552
|
maxLiteralMathSubtypeCount;
|
8505
|
-
|
8553
|
+
// Don't special-case tuple __add__ if the left type is a union. This
|
8554
|
+
// can result in an infinite loop if we keep creating new tuple types
|
8555
|
+
// within a loop construct using __add__.
|
8556
|
+
const isTupleAddAllowed = !(0, types_1.isUnion)(leftType);
|
8557
|
+
returnType = validateBinaryOperation(binaryOperator, { type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }, { type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }, node, inferenceContext, diag, { isLiteralMathAllowed, isTupleAddAllowed });
|
8506
8558
|
}
|
8507
8559
|
return returnType;
|
8508
8560
|
});
|
@@ -8525,7 +8577,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8525
8577
|
assignTypeToExpression(node.destExpression, typeResult.type, !!typeResult.isIncomplete, node.rightExpression);
|
8526
8578
|
return typeResult;
|
8527
8579
|
}
|
8528
|
-
function validateBinaryOperation(operator, leftTypeResult, rightTypeResult, errorNode,
|
8580
|
+
function validateBinaryOperation(operator, leftTypeResult, rightTypeResult, errorNode, inferenceContext, diag, options) {
|
8529
8581
|
const leftType = leftTypeResult.type;
|
8530
8582
|
const rightType = rightTypeResult.type;
|
8531
8583
|
let type;
|
@@ -8579,7 +8631,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8579
8631
|
return (0, typeUtils_1.preserveUnknown)(leftSubtype, rightSubtypeExpanded);
|
8580
8632
|
}
|
8581
8633
|
let returnType = getTypeOfMagicMethodReturn(rightSubtypeExpanded, [{ type: leftSubtype, isIncomplete: leftTypeResult.isIncomplete }], '__contains__', errorNode,
|
8582
|
-
/*
|
8634
|
+
/* inferenceContext */ undefined);
|
8583
8635
|
if (!returnType) {
|
8584
8636
|
// If __contains__ was not supported, fall back
|
8585
8637
|
// on an iterable.
|
@@ -8626,7 +8678,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8626
8678
|
// Handle certain operations on certain homogenous literal types
|
8627
8679
|
// using special-case math. For example, Literal[1, 2] + Literal[3, 4]
|
8628
8680
|
// should result in Literal[4, 5, 6].
|
8629
|
-
if (isLiteralMathAllowed) {
|
8681
|
+
if (options.isLiteralMathAllowed) {
|
8630
8682
|
const leftLiteralClassName = (0, typeUtils_1.getLiteralTypeClassName)(leftType);
|
8631
8683
|
if (leftLiteralClassName && !(0, typeUtils_1.getTypeCondition)(leftType)) {
|
8632
8684
|
const rightLiteralClassName = (0, typeUtils_1.getLiteralTypeClassName)(rightType);
|
@@ -8690,7 +8742,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8690
8742
|
else {
|
8691
8743
|
// Convert back to a simple number if it fits. Leave as a bigint
|
8692
8744
|
// if it doesn't.
|
8693
|
-
if (newValue
|
8745
|
+
if (newValue >= Number.MIN_SAFE_INTEGER &&
|
8746
|
+
newValue <= Number.MAX_SAFE_INTEGER) {
|
8694
8747
|
newValue = Number(newValue);
|
8695
8748
|
}
|
8696
8749
|
return types_1.ClassType.cloneWithLiteral(leftClassSubtype, newValue);
|
@@ -8718,7 +8771,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8718
8771
|
return (0, typeUtils_1.preserveUnknown)(leftSubtypeUnexpanded, rightSubtypeUnexpanded);
|
8719
8772
|
}
|
8720
8773
|
// Special-case __add__ for tuples when the types for both tuples are known.
|
8721
|
-
if (
|
8774
|
+
if (options.isTupleAddAllowed &&
|
8775
|
+
operator === 0 /* Add */ &&
|
8722
8776
|
(0, types_1.isClassInstance)(leftSubtypeExpanded) &&
|
8723
8777
|
(0, typeUtils_1.isTupleClass)(leftSubtypeExpanded) &&
|
8724
8778
|
leftSubtypeExpanded.tupleTypeArguments &&
|
@@ -8735,19 +8789,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8735
8789
|
]));
|
8736
8790
|
}
|
8737
8791
|
const magicMethodName = binaryOperatorMap[operator][0];
|
8738
|
-
let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode,
|
8792
|
+
let resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeUnexpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
|
8739
8793
|
if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
8740
8794
|
// Try the expanded left type.
|
8741
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode,
|
8795
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeUnexpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
|
8742
8796
|
}
|
8743
8797
|
if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
8744
8798
|
// Try the expanded left and right type.
|
8745
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode,
|
8799
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(leftSubtypeExpanded), [{ type: rightSubtypeExpanded, isIncomplete: rightTypeResult.isIncomplete }], magicMethodName, errorNode, inferenceContext);
|
8746
8800
|
}
|
8747
8801
|
if (!resultType) {
|
8748
8802
|
// Try the alternate form (swapping right and left).
|
8749
8803
|
const altMagicMethodName = binaryOperatorMap[operator][1];
|
8750
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode,
|
8804
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeUnexpanded), [{ type: leftSubtypeUnexpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, inferenceContext);
|
8751
8805
|
if (!resultType && rightSubtypeUnexpanded !== rightSubtypeExpanded) {
|
8752
8806
|
// Try the expanded right type.
|
8753
8807
|
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [
|
@@ -8755,20 +8809,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8755
8809
|
type: leftSubtypeUnexpanded,
|
8756
8810
|
isIncomplete: leftTypeResult.isIncomplete,
|
8757
8811
|
},
|
8758
|
-
], altMagicMethodName, errorNode,
|
8812
|
+
], altMagicMethodName, errorNode, inferenceContext);
|
8759
8813
|
}
|
8760
8814
|
if (!resultType && leftSubtypeUnexpanded !== leftSubtypeExpanded) {
|
8761
8815
|
// Try the expanded right and left type.
|
8762
|
-
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode,
|
8816
|
+
resultType = getTypeOfMagicMethodReturn(convertFunctionToObject(rightSubtypeExpanded), [{ type: leftSubtypeExpanded, isIncomplete: leftTypeResult.isIncomplete }], altMagicMethodName, errorNode, inferenceContext);
|
8763
8817
|
}
|
8764
8818
|
}
|
8765
8819
|
if (!resultType) {
|
8766
|
-
if (
|
8820
|
+
if (inferenceContext) {
|
8767
8821
|
diag.addMessage(localize_1.Localizer.Diagnostic.typeNotSupportBinaryOperatorBidirectional().format({
|
8768
8822
|
operator: ParseTreeUtils.printOperator(operator),
|
8769
8823
|
leftType: printType(leftSubtypeExpanded),
|
8770
8824
|
rightType: printType(rightSubtypeExpanded),
|
8771
|
-
expectedType: printType(expectedType),
|
8825
|
+
expectedType: printType(inferenceContext.expectedType),
|
8772
8826
|
}));
|
8773
8827
|
}
|
8774
8828
|
else {
|
@@ -8786,7 +8840,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8786
8840
|
}
|
8787
8841
|
return type && (0, types_1.isNever)(type) ? undefined : type;
|
8788
8842
|
}
|
8789
|
-
function getTypeOfMagicMethodReturn(objType, args, magicMethodName, errorNode,
|
8843
|
+
function getTypeOfMagicMethodReturn(objType, args, magicMethodName, errorNode, inferenceContext) {
|
8790
8844
|
let magicMethodSupported = true;
|
8791
8845
|
// Create a helper lambda for object subtypes.
|
8792
8846
|
const handleSubtype = (subtype) => {
|
@@ -8814,7 +8868,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8814
8868
|
useSpeculativeMode(errorNode, () => {
|
8815
8869
|
callResult = validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
|
8816
8870
|
/* typeVarContext */ undefined,
|
8817
|
-
/* skipUnknownArgCheck */ true,
|
8871
|
+
/* skipUnknownArgCheck */ true, inferenceContext);
|
8818
8872
|
});
|
8819
8873
|
if (callResult.argumentErrors) {
|
8820
8874
|
magicMethodSupported = false;
|
@@ -8862,20 +8916,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8862
8916
|
}
|
8863
8917
|
return type;
|
8864
8918
|
}
|
8865
|
-
function getTypeOfDictionary(node,
|
8919
|
+
function getTypeOfDictionary(node, inferenceContext) {
|
8866
8920
|
// If the expected type is a union, analyze for each of the subtypes
|
8867
8921
|
// to find one that matches.
|
8868
|
-
let effectiveExpectedType = expectedType;
|
8869
|
-
if (
|
8922
|
+
let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
|
8923
|
+
if (inferenceContext && (0, types_1.isUnion)(inferenceContext.expectedType)) {
|
8870
8924
|
let matchingSubtype;
|
8871
8925
|
let matchingSubtypeResult;
|
8872
|
-
(0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
|
8926
|
+
(0, typeUtils_1.doForEachSubtype)(inferenceContext.expectedType, (subtype) => {
|
8873
8927
|
// Use shortcut if we've already found a match.
|
8874
8928
|
if (matchingSubtypeResult && !matchingSubtypeResult.typeErrors) {
|
8875
8929
|
return;
|
8876
8930
|
}
|
8877
8931
|
const subtypeResult = useSpeculativeMode(node, () => {
|
8878
|
-
return
|
8932
|
+
return getTypeOfDictionaryWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
|
8879
8933
|
});
|
8880
8934
|
if (subtypeResult && assignType(subtype, subtypeResult.type)) {
|
8881
8935
|
// If this is the first result we're seeing or it's the first result
|
@@ -8891,28 +8945,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8891
8945
|
let expectedTypeDiagAddendum = undefined;
|
8892
8946
|
if (effectiveExpectedType) {
|
8893
8947
|
expectedTypeDiagAddendum = new diagnostic_1.DiagnosticAddendum();
|
8894
|
-
const result =
|
8948
|
+
const result = getTypeOfDictionaryWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext), expectedTypeDiagAddendum);
|
8895
8949
|
if (result) {
|
8896
8950
|
return result;
|
8897
8951
|
}
|
8898
8952
|
}
|
8899
|
-
const result = getTypeOfDictionaryInferred(node, /* hasExpectedType */ !!
|
8953
|
+
const result = getTypeOfDictionaryInferred(node, /* hasExpectedType */ !!inferenceContext);
|
8900
8954
|
return { ...result, expectedTypeDiagAddendum };
|
8901
8955
|
}
|
8902
|
-
|
8903
|
-
|
8904
|
-
|
8905
|
-
|
8906
|
-
expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedType);
|
8907
|
-
if (!(0, types_1.isClassInstance)(expectedType)) {
|
8956
|
+
function getTypeOfDictionaryWithContext(node, inferenceContext, expectedDiagAddendum) {
|
8957
|
+
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
8958
|
+
const concreteExpectedType = makeTopLevelTypeVarsConcrete(inferenceContext.expectedType);
|
8959
|
+
if (!(0, types_1.isClassInstance)(concreteExpectedType)) {
|
8908
8960
|
return undefined;
|
8909
8961
|
}
|
8910
8962
|
const keyTypes = [];
|
8911
8963
|
const valueTypes = [];
|
8912
8964
|
let isIncomplete = false;
|
8913
8965
|
// Handle TypedDict's as a special case.
|
8914
|
-
if (types_1.ClassType.isTypedDictClass(
|
8915
|
-
const expectedTypedDictEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface,
|
8966
|
+
if (types_1.ClassType.isTypedDictClass(concreteExpectedType)) {
|
8967
|
+
const expectedTypedDictEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface, concreteExpectedType);
|
8916
8968
|
// Infer the key and value types if possible.
|
8917
8969
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8918
8970
|
/* forceStrictInference */ true,
|
@@ -8920,8 +8972,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8920
8972
|
/* expectedValueType */ undefined, expectedTypedDictEntries, expectedDiagAddendum)) {
|
8921
8973
|
isIncomplete = true;
|
8922
8974
|
}
|
8923
|
-
if (types_1.ClassType.isTypedDictClass(
|
8924
|
-
const resultTypedDict = (0, typedDicts_1.assignToTypedDict)(evaluatorInterface,
|
8975
|
+
if (types_1.ClassType.isTypedDictClass(concreteExpectedType)) {
|
8976
|
+
const resultTypedDict = (0, typedDicts_1.assignToTypedDict)(evaluatorInterface, concreteExpectedType, keyTypes, valueTypes,
|
8925
8977
|
// Don't overwrite existing expectedDiagAddendum messages if they were
|
8926
8978
|
// already provided by getKeyValueTypesFromDictionary.
|
8927
8979
|
(expectedDiagAddendum === null || expectedDiagAddendum === void 0 ? void 0 : expectedDiagAddendum.isEmpty()) ? expectedDiagAddendum : undefined);
|
@@ -8939,7 +8991,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8939
8991
|
return undefined;
|
8940
8992
|
}
|
8941
8993
|
const dictTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInDict));
|
8942
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, expectedType, dictTypeVarContext, getTypeVarScopesForNode(node))) {
|
8994
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInDict, inferenceContext.expectedType, dictTypeVarContext, getTypeVarScopesForNode(node))) {
|
8943
8995
|
return undefined;
|
8944
8996
|
}
|
8945
8997
|
const specializedDict = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInDict), dictTypeVarContext);
|
@@ -8956,8 +9008,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8956
9008
|
// Dict and MutableMapping types have invariant value types, so they
|
8957
9009
|
// cannot be narrowed further. Other super-types like Mapping, Collection,
|
8958
9010
|
// and Iterable use covariant value types, so they can be narrowed.
|
8959
|
-
const isValueTypeInvariant = (0, types_1.isClassInstance)(expectedType) &&
|
8960
|
-
(types_1.ClassType.isBuiltIn(expectedType, 'dict') ||
|
9011
|
+
const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
9012
|
+
(types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
|
9013
|
+
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
|
8961
9014
|
const specializedKeyType = inferTypeArgFromExpectedType(expectedKeyType, keyTypes.map((result) => result.type),
|
8962
9015
|
/* isNarrowable */ false);
|
8963
9016
|
const specializedValueType = inferTypeArgFromExpectedType(expectedValueType, valueTypes.map((result) => result.type),
|
@@ -9021,7 +9074,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9021
9074
|
let addUnknown = true;
|
9022
9075
|
if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
|
9023
9076
|
const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
|
9024
|
-
/* flags */ undefined, expectedKeyType !== null && expectedKeyType !== void 0 ? expectedKeyType : (forceStrictInference ? types_1.NeverType.createNever() : undefined));
|
9077
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedKeyType !== null && expectedKeyType !== void 0 ? expectedKeyType : (forceStrictInference ? types_1.NeverType.createNever() : undefined)));
|
9025
9078
|
if (keyTypeResult.isIncomplete) {
|
9026
9079
|
isIncomplete = true;
|
9027
9080
|
}
|
@@ -9035,12 +9088,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9035
9088
|
types_1.ClassType.isBuiltIn(keyType, 'str') &&
|
9036
9089
|
(0, typeUtils_1.isLiteralType)(keyType) &&
|
9037
9090
|
expectedTypedDictEntries.has(keyType.literalValue)) {
|
9091
|
+
const effectiveValueType = expectedTypedDictEntries.get(keyType.literalValue).valueType;
|
9038
9092
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
9039
|
-
/* flags */ undefined,
|
9093
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
|
9040
9094
|
}
|
9041
9095
|
else {
|
9096
|
+
const effectiveValueType = expectedValueType !== null && expectedValueType !== void 0 ? expectedValueType : (forceStrictInference ? types_1.NeverType.createNever() : undefined);
|
9042
9097
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
9043
|
-
/* flags */ undefined,
|
9098
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(effectiveValueType));
|
9044
9099
|
}
|
9045
9100
|
if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
|
9046
9101
|
expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
|
@@ -9138,20 +9193,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9138
9193
|
});
|
9139
9194
|
return isIncomplete;
|
9140
9195
|
}
|
9141
|
-
function getTypeOfListOrSet(node,
|
9196
|
+
function getTypeOfListOrSet(node, inferenceContext) {
|
9142
9197
|
// If the expected type is a union, recursively call for each of the subtypes
|
9143
9198
|
// to find one that matches.
|
9144
|
-
let effectiveExpectedType = expectedType;
|
9145
|
-
if (
|
9199
|
+
let effectiveExpectedType = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType;
|
9200
|
+
if (inferenceContext && (0, types_1.isUnion)(inferenceContext.expectedType)) {
|
9146
9201
|
let matchingSubtype;
|
9147
9202
|
let matchingSubtypeResult;
|
9148
|
-
(0, typeUtils_1.doForEachSubtype)(expectedType, (subtype) => {
|
9203
|
+
(0, typeUtils_1.doForEachSubtype)(inferenceContext.expectedType, (subtype) => {
|
9149
9204
|
// Use shortcut if we've already found a match.
|
9150
9205
|
if (matchingSubtypeResult && !matchingSubtypeResult.typeErrors) {
|
9151
9206
|
return;
|
9152
9207
|
}
|
9153
9208
|
const subtypeResult = useSpeculativeMode(node, () => {
|
9154
|
-
return
|
9209
|
+
return getTypeOfListOrSetWithContext(node, (0, typeUtils_1.makeInferenceContext)(subtype, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
|
9155
9210
|
});
|
9156
9211
|
if (subtypeResult && assignType(subtype, subtypeResult.type)) {
|
9157
9212
|
// If this is the first result we're seeing or it's the first result
|
@@ -9166,24 +9221,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9166
9221
|
}
|
9167
9222
|
let expectedTypeDiagAddendum;
|
9168
9223
|
if (effectiveExpectedType) {
|
9169
|
-
const result =
|
9224
|
+
const result = getTypeOfListOrSetWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
|
9170
9225
|
if (result && !result.typeErrors) {
|
9171
9226
|
return result;
|
9172
9227
|
}
|
9173
9228
|
expectedTypeDiagAddendum = result === null || result === void 0 ? void 0 : result.expectedTypeDiagAddendum;
|
9174
9229
|
}
|
9175
|
-
const typeResult = getTypeOfListOrSetInferred(node, /* hasExpectedType */
|
9230
|
+
const typeResult = getTypeOfListOrSetInferred(node, /* hasExpectedType */ inferenceContext !== undefined);
|
9176
9231
|
return { ...typeResult, expectedTypeDiagAddendum };
|
9177
9232
|
}
|
9178
9233
|
// Attempts to determine the type of a list or set statement based on an expected type.
|
9179
9234
|
// Returns undefined if that type cannot be honored.
|
9180
|
-
function
|
9235
|
+
function getTypeOfListOrSetWithContext(node, inferenceContext) {
|
9181
9236
|
const builtInClassName = node.nodeType === 31 /* List */ ? 'list' : 'set';
|
9182
|
-
expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(expectedType);
|
9237
|
+
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
9183
9238
|
let isIncomplete = false;
|
9184
9239
|
let typeErrors = false;
|
9185
9240
|
const verifyHashable = node.nodeType === 45 /* Set */;
|
9186
|
-
if (!(0, types_1.isClassInstance)(expectedType)) {
|
9241
|
+
if (!(0, types_1.isClassInstance)(inferenceContext.expectedType)) {
|
9187
9242
|
return undefined;
|
9188
9243
|
}
|
9189
9244
|
const builtInListOrSet = getBuiltInObject(node, builtInClassName);
|
@@ -9191,7 +9246,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9191
9246
|
return undefined;
|
9192
9247
|
}
|
9193
9248
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(builtInListOrSet));
|
9194
|
-
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, expectedType, typeVarContext, getTypeVarScopesForNode(node))) {
|
9249
|
+
if (!(0, constraintSolver_1.populateTypeVarContextBasedOnExpectedType)(evaluatorInterface, builtInListOrSet, inferenceContext.expectedType, typeVarContext, getTypeVarScopesForNode(node))) {
|
9195
9250
|
return undefined;
|
9196
9251
|
}
|
9197
9252
|
const specializedListOrSet = (0, typeUtils_1.applySolvedTypeVars)(types_1.ClassType.cloneAsInstantiable(builtInListOrSet), typeVarContext);
|
@@ -9207,7 +9262,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9207
9262
|
entryTypeResult = getElementTypeFromListComprehension(entry, expectedEntryType);
|
9208
9263
|
}
|
9209
9264
|
else {
|
9210
|
-
entryTypeResult = getTypeOfExpression(entry,
|
9265
|
+
entryTypeResult = getTypeOfExpression(entry,
|
9266
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedEntryType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.typeVarContext));
|
9211
9267
|
}
|
9212
9268
|
entryTypes.push(entryTypeResult.type);
|
9213
9269
|
if (entryTypeResult.isIncomplete) {
|
@@ -9223,7 +9279,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9223
9279
|
verifySetEntryOrDictKeyIsHashable(entry, entryTypeResult.type, /* isDictKey */ false);
|
9224
9280
|
}
|
9225
9281
|
});
|
9226
|
-
const isExpectedTypeListOrSet = (0, types_1.isClassInstance)(expectedType) &&
|
9282
|
+
const isExpectedTypeListOrSet = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
9283
|
+
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, builtInClassName);
|
9227
9284
|
const specializedEntryType = inferTypeArgFromExpectedType(expectedEntryType, entryTypes,
|
9228
9285
|
/* isNarrowable */ !isExpectedTypeListOrSet);
|
9229
9286
|
if (!specializedEntryType) {
|
@@ -9346,13 +9403,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9346
9403
|
}
|
9347
9404
|
return undefined;
|
9348
9405
|
}
|
9349
|
-
function getTypeOfTernary(node, flags,
|
9406
|
+
function getTypeOfTernary(node, flags, inferenceContext) {
|
9350
9407
|
getTypeOfExpression(node.testExpression);
|
9351
9408
|
const typesToCombine = [];
|
9352
9409
|
let isIncomplete = false;
|
9353
9410
|
let typeErrors = false;
|
9354
9411
|
if (isNodeReachable(node.ifExpression)) {
|
9355
|
-
const ifType = getTypeOfExpression(node.ifExpression, flags,
|
9412
|
+
const ifType = getTypeOfExpression(node.ifExpression, flags, inferenceContext);
|
9356
9413
|
typesToCombine.push(ifType.type);
|
9357
9414
|
if (ifType.isIncomplete) {
|
9358
9415
|
isIncomplete = true;
|
@@ -9362,7 +9419,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9362
9419
|
}
|
9363
9420
|
}
|
9364
9421
|
if (isNodeReachable(node.elseExpression)) {
|
9365
|
-
const elseType = getTypeOfExpression(node.elseExpression, flags,
|
9422
|
+
const elseType = getTypeOfExpression(node.elseExpression, flags, inferenceContext);
|
9366
9423
|
typesToCombine.push(elseType.type);
|
9367
9424
|
if (elseType.isIncomplete) {
|
9368
9425
|
isIncomplete = true;
|
@@ -9396,7 +9453,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9396
9453
|
}
|
9397
9454
|
}
|
9398
9455
|
if (node.expression) {
|
9399
|
-
const exprResult = getTypeOfExpression(node.expression,
|
9456
|
+
const exprResult = getTypeOfExpression(node.expression,
|
9457
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedYieldType));
|
9400
9458
|
if (exprResult.isIncomplete) {
|
9401
9459
|
isIncomplete = true;
|
9402
9460
|
}
|
@@ -9427,7 +9485,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9427
9485
|
}
|
9428
9486
|
return { type: returnedType || types_1.UnknownType.create() };
|
9429
9487
|
}
|
9430
|
-
function getTypeOfLambda(node,
|
9488
|
+
function getTypeOfLambda(node, inferenceContext) {
|
9431
9489
|
let isIncomplete = false;
|
9432
9490
|
const functionType = types_1.FunctionType.createInstance('', '', '', 131072 /* PartiallyEvaluated */);
|
9433
9491
|
functionType.details.typeVarScopeId = getScopeIdForNode(node);
|
@@ -9435,8 +9493,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9435
9493
|
// lambda depends on itself.
|
9436
9494
|
writeTypeCache(node, { type: functionType, isIncomplete: true }, 0 /* None */);
|
9437
9495
|
let expectedFunctionTypes = [];
|
9438
|
-
if (
|
9439
|
-
(0, typeUtils_1.mapSubtypes)(expectedType, (subtype) => {
|
9496
|
+
if (inferenceContext) {
|
9497
|
+
(0, typeUtils_1.mapSubtypes)(inferenceContext.expectedType, (subtype) => {
|
9440
9498
|
if ((0, types_1.isFunction)(subtype)) {
|
9441
9499
|
expectedFunctionTypes.push(subtype);
|
9442
9500
|
}
|
@@ -9526,16 +9584,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9526
9584
|
// evaluation scope for the return expression and do not allow retention
|
9527
9585
|
// of the cached types.
|
9528
9586
|
const inferLambdaReturnType = () => {
|
9529
|
-
const returnTypeResult = getTypeOfExpression(node.expression,
|
9587
|
+
const returnTypeResult = getTypeOfExpression(node.expression,
|
9588
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedReturnType));
|
9530
9589
|
functionType.inferredReturnType = returnTypeResult.type;
|
9531
9590
|
if (returnTypeResult.isIncomplete) {
|
9532
9591
|
isIncomplete = true;
|
9533
9592
|
}
|
9534
9593
|
};
|
9535
9594
|
if (speculativeTypeTracker.isSpeculative(node)) {
|
9595
|
+
// We need to set allowCacheRetention to false because we don't want to
|
9596
|
+
// cache the type of the lambda return expression because it depends on
|
9597
|
+
// the parameter types that we set above, and the speculative type cache
|
9598
|
+
// doesn't know about that context.
|
9536
9599
|
useSpeculativeMode(node.expression, () => {
|
9537
9600
|
inferLambdaReturnType();
|
9538
|
-
}
|
9601
|
+
},
|
9602
|
+
/* allowCacheRetention */ false);
|
9539
9603
|
}
|
9540
9604
|
else {
|
9541
9605
|
inferLambdaReturnType();
|
@@ -9544,7 +9608,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9544
9608
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
9545
9609
|
return { type: functionType, isIncomplete };
|
9546
9610
|
}
|
9547
|
-
function getTypeOfListComprehension(node,
|
9611
|
+
function getTypeOfListComprehension(node, inferenceContext) {
|
9548
9612
|
var _a;
|
9549
9613
|
let isIncomplete = false;
|
9550
9614
|
let typeErrors = false;
|
@@ -9558,8 +9622,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9558
9622
|
isAsync = true;
|
9559
9623
|
}
|
9560
9624
|
let expectedElementType;
|
9561
|
-
if (
|
9562
|
-
expectedElementType = (_a = getTypeOfIterator({ type: expectedType }, isAsync,
|
9625
|
+
if (inferenceContext) {
|
9626
|
+
expectedElementType = (_a = getTypeOfIterator({ type: inferenceContext.expectedType }, isAsync,
|
9627
|
+
/* errorNode */ undefined)) === null || _a === void 0 ? void 0 : _a.type;
|
9563
9628
|
}
|
9564
9629
|
const elementTypeResult = getElementTypeFromListComprehension(node, expectedElementType);
|
9565
9630
|
if (elementTypeResult.isIncomplete) {
|
@@ -9572,9 +9637,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9572
9637
|
// Handle the special case where a generator function (e.g. `(await x for x in y)`)
|
9573
9638
|
// is expected to be an AsyncGenerator.
|
9574
9639
|
if (!isAsync &&
|
9575
|
-
|
9576
|
-
(0, types_1.isClassInstance)(expectedType) &&
|
9577
|
-
types_1.ClassType.isBuiltIn(expectedType, 'AsyncGenerator')) {
|
9640
|
+
inferenceContext &&
|
9641
|
+
(0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
9642
|
+
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'AsyncGenerator')) {
|
9578
9643
|
isAsync = true;
|
9579
9644
|
}
|
9580
9645
|
const builtInIteratorType = getTypingType(node, isAsync ? 'AsyncGenerator' : 'Generator');
|
@@ -9652,7 +9717,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9652
9717
|
if (node.expression.nodeType === 17 /* DictionaryKeyEntry */) {
|
9653
9718
|
// Create a tuple with the key/value types.
|
9654
9719
|
const keyTypeResult = getTypeOfExpression(node.expression.keyExpression,
|
9655
|
-
/* flags */ undefined, expectedKeyType);
|
9720
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedKeyType));
|
9656
9721
|
if (keyTypeResult.isIncomplete) {
|
9657
9722
|
isIncomplete = true;
|
9658
9723
|
}
|
@@ -9664,7 +9729,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9664
9729
|
keyType = stripLiteralValue(keyType);
|
9665
9730
|
}
|
9666
9731
|
const valueTypeResult = getTypeOfExpression(node.expression.valueExpression,
|
9667
|
-
/* flags */ undefined, expectedValueOrElementType);
|
9732
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedValueOrElementType));
|
9668
9733
|
if (valueTypeResult.isIncomplete) {
|
9669
9734
|
isIncomplete = true;
|
9670
9735
|
}
|
@@ -9679,11 +9744,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9679
9744
|
}
|
9680
9745
|
else if (node.expression.nodeType === 16 /* DictionaryExpandEntry */) {
|
9681
9746
|
// The parser should have reported an error in this case because it's not allowed.
|
9682
|
-
getTypeOfExpression(node.expression.expandExpression,
|
9747
|
+
getTypeOfExpression(node.expression.expandExpression,
|
9748
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedValueOrElementType));
|
9683
9749
|
}
|
9684
9750
|
else if ((0, parseNodes_1.isExpressionNode)(node)) {
|
9685
9751
|
const exprTypeResult = getTypeOfExpression(node.expression,
|
9686
|
-
/* flags */ undefined, expectedValueOrElementType);
|
9752
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(expectedValueOrElementType));
|
9687
9753
|
if (exprTypeResult.isIncomplete) {
|
9688
9754
|
isIncomplete = true;
|
9689
9755
|
}
|
@@ -9885,7 +9951,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9885
9951
|
// If no type arguments are provided, the resulting type
|
9886
9952
|
// depends on whether we're evaluating a type annotation or
|
9887
9953
|
// we're in some other context.
|
9888
|
-
if ((flags &
|
9954
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
9889
9955
|
addError(localize_1.Localizer.Diagnostic.optionalExtraArgs(), errorNode);
|
9890
9956
|
return types_1.UnknownType.create();
|
9891
9957
|
}
|
@@ -10009,7 +10075,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10009
10075
|
// Creates a ClassVar type.
|
10010
10076
|
function createClassVarType(classType, errorNode, typeArgs, flags) {
|
10011
10077
|
var _a;
|
10012
|
-
if (flags & 131072 /*
|
10078
|
+
if (flags & 131072 /* DisallowClassVar */) {
|
10013
10079
|
addError(localize_1.Localizer.Diagnostic.classVarNotAllowed(), errorNode);
|
10014
10080
|
return types_1.AnyType.create();
|
10015
10081
|
}
|
@@ -10042,7 +10108,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10042
10108
|
// depends on whether we're evaluating a type annotation or
|
10043
10109
|
// we're in some other context.
|
10044
10110
|
if (!typeArgs) {
|
10045
|
-
if ((flags &
|
10111
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
10046
10112
|
addError(localize_1.Localizer.Diagnostic.typeGuardArgCount(), errorNode);
|
10047
10113
|
}
|
10048
10114
|
return classType;
|
@@ -10103,7 +10169,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10103
10169
|
// If no type arguments are provided, the resulting type
|
10104
10170
|
// depends on whether we're evaluating a type annotation or
|
10105
10171
|
// we're in some other context.
|
10106
|
-
if (!typeArgs && (flags &
|
10172
|
+
if (!typeArgs && (flags & 256 /* ExpectingTypeAnnotation */) === 0) {
|
10107
10173
|
return classType;
|
10108
10174
|
}
|
10109
10175
|
if (!typeArgs || typeArgs.length !== 1) {
|
@@ -10124,7 +10190,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10124
10190
|
isUsageLegal = true;
|
10125
10191
|
}
|
10126
10192
|
}
|
10127
|
-
if ((flags & 1048576 /*
|
10193
|
+
if ((flags & 1048576 /* AllowRequired */) !== 0) {
|
10128
10194
|
isUsageLegal = true;
|
10129
10195
|
}
|
10130
10196
|
if (!isUsageLegal) {
|
@@ -10139,7 +10205,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10139
10205
|
// If no type arguments are provided, the resulting type
|
10140
10206
|
// depends on whether we're evaluating a type annotation or
|
10141
10207
|
// we're in some other context.
|
10142
|
-
if (!typeArgs && (flags &
|
10208
|
+
if (!typeArgs && (flags & 256 /* ExpectingTypeAnnotation */) === 0) {
|
10143
10209
|
return classType;
|
10144
10210
|
}
|
10145
10211
|
if (!typeArgs || typeArgs.length !== 1) {
|
@@ -10173,7 +10239,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10173
10239
|
}
|
10174
10240
|
// Creates a "Final" type.
|
10175
10241
|
function createFinalType(classType, errorNode, typeArgs, flags) {
|
10176
|
-
if (flags & 16 /*
|
10242
|
+
if (flags & 16 /* DisallowFinal */) {
|
10177
10243
|
addError(localize_1.Localizer.Diagnostic.finalContext(), errorNode);
|
10178
10244
|
return types_1.AnyType.create();
|
10179
10245
|
}
|
@@ -10330,7 +10396,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10330
10396
|
// If no type arguments are provided, the resulting type
|
10331
10397
|
// depends on whether we're evaluating a type annotation or
|
10332
10398
|
// we're in some other context.
|
10333
|
-
if ((flags &
|
10399
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
10334
10400
|
addError(localize_1.Localizer.Diagnostic.unionTypeArgCount(), errorNode);
|
10335
10401
|
return types_1.NeverType.createNever();
|
10336
10402
|
}
|
@@ -10381,7 +10447,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10381
10447
|
// If no type arguments are provided, the resulting type
|
10382
10448
|
// depends on whether we're evaluating a type annotation or
|
10383
10449
|
// we're in some other context.
|
10384
|
-
if ((flags & (
|
10450
|
+
if ((flags & (256 /* ExpectingTypeAnnotation */ | 262144 /* DisallowNakedGeneric */)) !== 0) {
|
10385
10451
|
addError(localize_1.Localizer.Diagnostic.genericTypeArgMissing(), errorNode);
|
10386
10452
|
}
|
10387
10453
|
return classType;
|
@@ -10611,7 +10677,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10611
10677
|
let flags = 0 /* None */;
|
10612
10678
|
if (fileInfo.isStubFile) {
|
10613
10679
|
// An assignment of ellipsis means "Any" within a type stub file.
|
10614
|
-
flags |=
|
10680
|
+
flags |= 512 /* ConvertEllipsisToUnknown */;
|
10615
10681
|
}
|
10616
10682
|
if (node.rightExpression.nodeType === 38 /* Name */ ||
|
10617
10683
|
node.rightExpression.nodeType === 35 /* MemberAccess */) {
|
@@ -10622,11 +10688,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10622
10688
|
}
|
10623
10689
|
if (isDeclaredTypeAlias(node.leftExpression)) {
|
10624
10690
|
flags |=
|
10625
|
-
|
10691
|
+
128 /* ExpectingType */ |
|
10626
10692
|
8 /* EvaluateStringLiteralAsType */ |
|
10627
|
-
32 /*
|
10628
|
-
|
10629
|
-
131072 /*
|
10693
|
+
32 /* DisallowParamSpec */ |
|
10694
|
+
64 /* DisallowTypeVarTuple */ |
|
10695
|
+
131072 /* DisallowClassVar */;
|
10630
10696
|
flags &= ~2 /* DoNotSpecialize */;
|
10631
10697
|
}
|
10632
10698
|
// Is this type already cached?
|
@@ -10684,7 +10750,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10684
10750
|
/* flags */ undefined);
|
10685
10751
|
}
|
10686
10752
|
}
|
10687
|
-
const srcTypeResult = getTypeOfExpression(node.rightExpression, flags, declaredType);
|
10753
|
+
const srcTypeResult = getTypeOfExpression(node.rightExpression, flags, (0, typeUtils_1.makeInferenceContext)(declaredType));
|
10688
10754
|
let srcType = srcTypeResult.type;
|
10689
10755
|
expectedTypeDiagAddendum = srcTypeResult.expectedTypeDiagAddendum;
|
10690
10756
|
if (srcTypeResult.isIncomplete) {
|
@@ -10714,12 +10780,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10714
10780
|
(0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, node.leftExpression, () => rightHandType) || rightHandType;
|
10715
10781
|
}
|
10716
10782
|
if (typeAliasNameNode) {
|
10717
|
-
// Clear out the temporary types we wrote above.
|
10718
|
-
deleteTypeCacheEntry(node);
|
10719
|
-
deleteTypeCacheEntry(node.leftExpression);
|
10720
|
-
if (node.leftExpression.nodeType === 54 /* TypeAnnotation */) {
|
10721
|
-
deleteTypeCacheEntry(node.leftExpression.valueExpression);
|
10722
|
-
}
|
10723
10783
|
// If this was a speculative type alias, it becomes a real type alias
|
10724
10784
|
// only if the evaluated type is an instantiable type.
|
10725
10785
|
if (!isSpeculativeTypeAlias ||
|
@@ -10819,8 +10879,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10819
10879
|
if (aliasTypeResult.isIncomplete) {
|
10820
10880
|
isIncomplete = true;
|
10821
10881
|
}
|
10822
|
-
// Clear the temporary type we wrote above.
|
10823
|
-
deleteTypeCacheEntry(node.name);
|
10824
10882
|
aliasType = transformTypeForTypeAlias(aliasType, node.name, node.expression, typeParameters, (_a = node.typeParameters) === null || _a === void 0 ? void 0 : _a.parameters);
|
10825
10883
|
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, aliasType)) {
|
10826
10884
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
@@ -10843,7 +10901,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10843
10901
|
if (readTypeCache(node, 0 /* None */)) {
|
10844
10902
|
return;
|
10845
10903
|
}
|
10846
|
-
const destTypeResult = getTypeOfAugmentedAssignment(node, /*
|
10904
|
+
const destTypeResult = getTypeOfAugmentedAssignment(node, /* inferenceContext */ undefined);
|
10847
10905
|
writeTypeCache(node, destTypeResult, 0 /* None */);
|
10848
10906
|
}
|
10849
10907
|
function getPseudoGenericTypeVarName(paramName) {
|
@@ -10917,8 +10975,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10917
10975
|
let protocolTypeParameters;
|
10918
10976
|
const initSubclassArgs = [];
|
10919
10977
|
let metaclassNode;
|
10920
|
-
let
|
10921
|
-
|
10978
|
+
let isMetaclassDeferred = false;
|
10979
|
+
let exprFlags = 128 /* ExpectingType */ |
|
10980
|
+
1024 /* AllowGenericClassType */ |
|
10922
10981
|
262144 /* DisallowNakedGeneric */ |
|
10923
10982
|
2048 /* DisallowTypeVarsWithScopeId */ |
|
10924
10983
|
8192 /* AssociateTypeVarsWithCurrentScope */ |
|
@@ -10948,14 +11007,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10948
11007
|
argType = types_1.UnknownType.create();
|
10949
11008
|
}
|
10950
11009
|
else {
|
10951
|
-
if (types_1.ClassType.isPartiallyEvaluated(argType)
|
11010
|
+
if (types_1.ClassType.isPartiallyEvaluated(argType) ||
|
11011
|
+
argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
|
10952
11012
|
// If the base class is partially evaluated, install a callback
|
10953
11013
|
// so we can fix up this class (e.g. compute the MRO) when the
|
10954
11014
|
// dependent class is completed.
|
10955
11015
|
classTypeHooks.push({
|
10956
11016
|
dependency: argType,
|
10957
|
-
callback: () => completeClassTypeDeferred(classType, node.name),
|
11017
|
+
callback: () => completeClassTypeDeferred(classType, node, node.name),
|
10958
11018
|
});
|
11019
|
+
isMetaclassDeferred = true;
|
10959
11020
|
}
|
10960
11021
|
if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
|
10961
11022
|
if (!fileInfo.isStubFile &&
|
@@ -11335,6 +11396,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11335
11396
|
if (types_1.ClassType.isBuiltIn(classType, 'UnionType')) {
|
11336
11397
|
unionType = types_1.ClassType.cloneAsInstance(classType);
|
11337
11398
|
}
|
11399
|
+
// Validate that arguments passed to `__init_subclass__` are of the correct type.
|
11400
|
+
// Defer this if the metaclass calculation is deferred.
|
11401
|
+
if (!isMetaclassDeferred) {
|
11402
|
+
validateInitSubclassArgs(node, classType);
|
11403
|
+
}
|
11338
11404
|
return { classType, decoratedType };
|
11339
11405
|
}
|
11340
11406
|
// Determines whether the type parameters has a default that refers to another
|
@@ -11475,6 +11541,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11475
11541
|
effectiveMetaclass = baseClassMeta ? types_1.UnknownType.create() : undefined;
|
11476
11542
|
break;
|
11477
11543
|
}
|
11544
|
+
if (types_1.ClassType.isEnumClass(baseClass)) {
|
11545
|
+
classType.details.flags |= 1048576 /* EnumClass */;
|
11546
|
+
}
|
11478
11547
|
}
|
11479
11548
|
else {
|
11480
11549
|
// If one of the base classes is unknown, then the effective
|
@@ -11525,6 +11594,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11525
11594
|
originalClassType.details.classDataClassTransform = (0, dataClasses_1.validateDataClassTransformDecorator)(evaluatorInterface, decoratorNode.expression);
|
11526
11595
|
}
|
11527
11596
|
}
|
11597
|
+
if ((0, types_1.isOverloadedFunction)(decoratorCallType)) {
|
11598
|
+
if (decoratorCallType.overloads.length > 0 &&
|
11599
|
+
decoratorCallType.overloads[0].details.builtInName === 'deprecated') {
|
11600
|
+
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
11601
|
+
return inputClassType;
|
11602
|
+
}
|
11603
|
+
}
|
11528
11604
|
}
|
11529
11605
|
if ((0, types_1.isOverloadedFunction)(decoratorType)) {
|
11530
11606
|
const dataclassBehaviors = (0, dataClasses_1.getDataclassDecoratorBehaviors)(decoratorType);
|
@@ -11533,6 +11609,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11533
11609
|
/* callNode */ undefined);
|
11534
11610
|
return inputClassType;
|
11535
11611
|
}
|
11612
|
+
if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') {
|
11613
|
+
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
11614
|
+
return inputClassType;
|
11615
|
+
}
|
11536
11616
|
}
|
11537
11617
|
else if ((0, types_1.isFunction)(decoratorType)) {
|
11538
11618
|
if (decoratorType.details.builtInName === 'final') {
|
@@ -11542,7 +11622,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11542
11622
|
// dependency between builtins, typing and _typeshed stubs.
|
11543
11623
|
return inputClassType;
|
11544
11624
|
}
|
11545
|
-
|
11625
|
+
if (decoratorType.details.builtInName === 'runtime_checkable') {
|
11546
11626
|
originalClassType.details.flags |= 32768 /* RuntimeCheckable */;
|
11547
11627
|
// Don't call getTypeOfDecorator for runtime_checkable. It appears
|
11548
11628
|
// frequently in stubs, and it's a waste of time to validate its
|
@@ -11568,6 +11648,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11568
11648
|
}
|
11569
11649
|
return getTypeOfDecorator(decoratorNode, inputClassType);
|
11570
11650
|
}
|
11651
|
+
// Given a @typing.deprecated decorator node, returns either '' or a custom
|
11652
|
+
// deprecation message if one is provided.
|
11653
|
+
function getCustomDeprecationMessage(decorator) {
|
11654
|
+
if (decorator.expression.nodeType === 9 /* Call */ &&
|
11655
|
+
decorator.expression.arguments.length > 0 &&
|
11656
|
+
decorator.expression.arguments[0].argumentCategory === 0 /* Simple */ &&
|
11657
|
+
decorator.expression.arguments[0].valueExpression.nodeType === 48 /* StringList */ &&
|
11658
|
+
decorator.expression.arguments[0].valueExpression.strings.length === 1) {
|
11659
|
+
return decorator.expression.arguments[0].valueExpression.strings[0].value;
|
11660
|
+
}
|
11661
|
+
return '';
|
11662
|
+
}
|
11571
11663
|
// Runs any registered "callback hooks" that depend on the specified class type.
|
11572
11664
|
// This allows us to complete any work that requires dependent classes to be
|
11573
11665
|
// completed.
|
@@ -11582,15 +11674,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11582
11674
|
}
|
11583
11675
|
// Recomputes the MRO and effective metaclass for the class after dependent
|
11584
11676
|
// classes have been fully constructed.
|
11585
|
-
function completeClassTypeDeferred(type, errorNode) {
|
11677
|
+
function completeClassTypeDeferred(type, node, errorNode) {
|
11586
11678
|
// Recompute the MRO linearization.
|
11587
11679
|
if (!(0, typeUtils_1.computeMroLinearization)(type)) {
|
11588
11680
|
addError(localize_1.Localizer.Diagnostic.methodOrdering(), errorNode);
|
11589
11681
|
}
|
11590
11682
|
// Recompute the effective metaclass.
|
11591
11683
|
computeEffectiveMetaclass(type, errorNode);
|
11684
|
+
validateInitSubclassArgs(node, type);
|
11592
11685
|
}
|
11593
|
-
function validateInitSubclassArgs(node, classType
|
11686
|
+
function validateInitSubclassArgs(node, classType) {
|
11687
|
+
// Collect arguments that will be passed to the `__init_subclass__`
|
11688
|
+
// method described in PEP 487 and validate it.
|
11689
|
+
const argList = [];
|
11690
|
+
node.arguments.forEach((arg) => {
|
11691
|
+
if (arg.name && arg.name.value !== 'metaclass') {
|
11692
|
+
argList.push({
|
11693
|
+
argumentCategory: 0 /* Simple */,
|
11694
|
+
node: arg,
|
11695
|
+
name: arg.name,
|
11696
|
+
valueExpression: arg.valueExpression,
|
11697
|
+
});
|
11698
|
+
}
|
11699
|
+
});
|
11594
11700
|
const errorNode = argList.length > 0 ? argList[0].node.name : node.name;
|
11595
11701
|
const initSubclassMethodInfo = getTypeOfClassMemberName(errorNode, classType,
|
11596
11702
|
/* isAccessedThroughObject */ false, '__init_subclass__', { method: 'get' },
|
@@ -11602,7 +11708,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11602
11708
|
if (initSubclassMethodType) {
|
11603
11709
|
validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
|
11604
11710
|
/* typeVarContext */ undefined,
|
11605
|
-
/* skipUnknownArgCheck */ false, types_1.NoneType.createInstance());
|
11711
|
+
/* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(types_1.NoneType.createInstance()));
|
11606
11712
|
}
|
11607
11713
|
}
|
11608
11714
|
else if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
|
@@ -11852,7 +11958,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11852
11958
|
}
|
11853
11959
|
let defaultValueType;
|
11854
11960
|
if (param.defaultValue) {
|
11855
|
-
defaultValueType = getTypeOfExpression(param.defaultValue, 1 /* ConvertEllipsisToAny */, annotatedType).type;
|
11961
|
+
defaultValueType = getTypeOfExpression(param.defaultValue, 1 /* ConvertEllipsisToAny */, (0, typeUtils_1.makeInferenceContext)(annotatedType)).type;
|
11856
11962
|
}
|
11857
11963
|
if (annotatedType) {
|
11858
11964
|
// If there was both a type annotation and a default value, verify
|
@@ -12110,7 +12216,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12110
12216
|
// parameter is annotated with a "raw" function-scoped type variable, as in:
|
12111
12217
|
// "def foo(value: T = 3)"
|
12112
12218
|
// In this case, we need to include the default value type in a union.
|
12113
|
-
const defaultArgType = getTypeOfExpression(param.defaultValue, 1 /* ConvertEllipsisToAny */, type).type;
|
12219
|
+
const defaultArgType = getTypeOfExpression(param.defaultValue, 1 /* ConvertEllipsisToAny */, (0, typeUtils_1.makeInferenceContext)(type)).type;
|
12114
12220
|
if (!(0, types_1.isAny)(defaultArgType)) {
|
12115
12221
|
type = (0, types_1.combineTypes)([type, defaultArgType]);
|
12116
12222
|
}
|
@@ -12310,6 +12416,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12310
12416
|
return inputFunctionType;
|
12311
12417
|
}
|
12312
12418
|
}
|
12419
|
+
if ((0, types_1.isOverloadedFunction)(decoratorCallType)) {
|
12420
|
+
if (decoratorCallType.overloads.length > 0 &&
|
12421
|
+
decoratorCallType.overloads[0].details.builtInName === 'deprecated') {
|
12422
|
+
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12423
|
+
return inputFunctionType;
|
12424
|
+
}
|
12425
|
+
}
|
12313
12426
|
}
|
12314
12427
|
let returnType = getTypeOfDecorator(decoratorNode, inputFunctionType);
|
12315
12428
|
// Check for some built-in decorator types with known semantics.
|
@@ -12343,6 +12456,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12343
12456
|
}
|
12344
12457
|
}
|
12345
12458
|
}
|
12459
|
+
else if ((0, types_1.isOverloadedFunction)(decoratorType)) {
|
12460
|
+
if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') {
|
12461
|
+
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12462
|
+
return inputFunctionType;
|
12463
|
+
}
|
12464
|
+
}
|
12346
12465
|
else if ((0, types_1.isInstantiableClass)(decoratorType)) {
|
12347
12466
|
if (types_1.ClassType.isBuiltIn(decoratorType)) {
|
12348
12467
|
switch (decoratorType.details.name) {
|
@@ -12756,7 +12875,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12756
12875
|
const additionalHelp = new diagnostic_1.DiagnosticAddendum();
|
12757
12876
|
if ((0, types_1.isClass)(subtype)) {
|
12758
12877
|
let enterType = getTypeOfMagicMethodReturn(subtype, [], enterMethodName, node.expression,
|
12759
|
-
/*
|
12878
|
+
/* inferenceContext */ undefined);
|
12760
12879
|
if (enterType) {
|
12761
12880
|
// For "async while", an implicit "await" is performed.
|
12762
12881
|
if (isAsync) {
|
@@ -12766,7 +12885,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12766
12885
|
}
|
12767
12886
|
if (!isAsync) {
|
12768
12887
|
if (getTypeOfMagicMethodReturn(subtype, [], '__aenter__', node.expression,
|
12769
|
-
/*
|
12888
|
+
/* inferenceContext */ undefined)) {
|
12770
12889
|
additionalHelp.addMessage(localize_1.Localizer.DiagnosticAddendum.asyncHelp());
|
12771
12890
|
}
|
12772
12891
|
}
|
@@ -12786,7 +12905,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12786
12905
|
if ((0, types_1.isClass)(subtype)) {
|
12787
12906
|
const anyArg = { type: types_1.AnyType.create() };
|
12788
12907
|
const exitType = getTypeOfMagicMethodReturn(subtype, [anyArg, anyArg, anyArg], exitMethodName, node.expression,
|
12789
|
-
/*
|
12908
|
+
/* inferenceContext */ undefined);
|
12790
12909
|
if (exitType) {
|
12791
12910
|
return;
|
12792
12911
|
}
|
@@ -13130,6 +13249,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13130
13249
|
nodeToEvaluate = argumentNode.parent;
|
13131
13250
|
continue;
|
13132
13251
|
}
|
13252
|
+
if (argumentNode.parent.nodeType === 10 /* Class */) {
|
13253
|
+
// If this is an argument node within a class declaration,
|
13254
|
+
// evaluate the full class declaration node.
|
13255
|
+
getTypeOfClass(argumentNode.parent);
|
13256
|
+
return;
|
13257
|
+
}
|
13133
13258
|
}
|
13134
13259
|
let parent = nodeToEvaluate.parent;
|
13135
13260
|
if (!parent) {
|
@@ -13170,18 +13295,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13170
13295
|
nodeToEvaluate = parent;
|
13171
13296
|
continue;
|
13172
13297
|
}
|
13173
|
-
else {
|
13174
|
-
// Check for expression types that are always contextual.
|
13175
|
-
if (nodeToEvaluate.nodeType !== 15 /* Dictionary */ &&
|
13176
|
-
nodeToEvaluate.nodeType !== 31 /* List */ &&
|
13177
|
-
nodeToEvaluate.nodeType !== 30 /* Lambda */ &&
|
13178
|
-
nodeToEvaluate.nodeType !== 45 /* Set */ &&
|
13179
|
-
nodeToEvaluate.nodeType !== 52 /* Tuple */ &&
|
13180
|
-
nodeToEvaluate.nodeType !== 56 /* Unpack */ &&
|
13181
|
-
nodeToEvaluate.nodeType !== 32 /* ListComprehension */) {
|
13182
|
-
break;
|
13183
|
-
}
|
13184
|
-
}
|
13185
13298
|
if (!(0, parseNodes_1.isExpressionNode)(parent)) {
|
13186
13299
|
// If we've hit a non-expression node, we generally want to
|
13187
13300
|
// stop. However, there are a few special "pass through"
|
@@ -13268,7 +13381,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13268
13381
|
const declaredReturnType = enclosingFunctionNode
|
13269
13382
|
? getFunctionDeclaredReturnType(enclosingFunctionNode)
|
13270
13383
|
: undefined;
|
13271
|
-
getTypeOfExpression(parent.returnExpression, 0 /* None */, declaredReturnType);
|
13384
|
+
getTypeOfExpression(parent.returnExpression, 0 /* None */, (0, typeUtils_1.makeInferenceContext)(declaredReturnType));
|
13272
13385
|
return;
|
13273
13386
|
}
|
13274
13387
|
break;
|
@@ -13444,16 +13557,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13444
13557
|
// don't bother doing additional work.
|
13445
13558
|
let cacheEntry = readTypeCacheEntry(subnode);
|
13446
13559
|
if (cacheEntry && !cacheEntry.typeResult.isIncomplete) {
|
13447
|
-
return
|
13560
|
+
return cacheEntry.typeResult;
|
13448
13561
|
}
|
13449
13562
|
callback();
|
13450
13563
|
cacheEntry = readTypeCacheEntry(subnode);
|
13451
13564
|
if (cacheEntry) {
|
13452
|
-
return
|
13453
|
-
type: cacheEntry.typeResult.type,
|
13454
|
-
isIncomplete: cacheEntry.typeResult.isIncomplete,
|
13455
|
-
expectedTypeDiagAddendum: cacheEntry.typeResult.expectedTypeDiagAddendum,
|
13456
|
-
};
|
13565
|
+
return cacheEntry.typeResult;
|
13457
13566
|
}
|
13458
13567
|
return undefined;
|
13459
13568
|
}
|
@@ -13850,9 +13959,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13850
13959
|
return getTypeOfExpressionExpectingType(arg.valueExpression);
|
13851
13960
|
}
|
13852
13961
|
function getTypeOfExpressionExpectingType(node, options) {
|
13853
|
-
let flags =
|
13854
|
-
8 /* EvaluateStringLiteralAsType */ |
|
13855
|
-
131072 /* ClassVarDisallowed */;
|
13962
|
+
let flags = 128 /* ExpectingType */ | 8 /* EvaluateStringLiteralAsType */ | 131072 /* DisallowClassVar */;
|
13856
13963
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
13857
13964
|
if (fileInfo.isStubFile) {
|
13858
13965
|
flags |= 4 /* AllowForwardReferences */;
|
@@ -13861,19 +13968,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13861
13968
|
flags |= 4194304 /* InterpreterParsesStringLiteral */;
|
13862
13969
|
}
|
13863
13970
|
if (!(options === null || options === void 0 ? void 0 : options.allowFinal)) {
|
13864
|
-
flags |= 16 /*
|
13971
|
+
flags |= 16 /* DisallowFinal */;
|
13865
13972
|
}
|
13866
13973
|
if (options === null || options === void 0 ? void 0 : options.allowRequired) {
|
13867
|
-
flags |= 1048576 /*
|
13974
|
+
flags |= 1048576 /* AllowRequired */ | 256 /* ExpectingTypeAnnotation */;
|
13868
13975
|
}
|
13869
13976
|
if (options === null || options === void 0 ? void 0 : options.allowUnpackedTuple) {
|
13870
13977
|
flags |= 2097152 /* AllowUnpackedTupleOrTypeVarTuple */;
|
13871
13978
|
}
|
13872
13979
|
else {
|
13873
|
-
flags |=
|
13980
|
+
flags |= 64 /* DisallowTypeVarTuple */;
|
13874
13981
|
}
|
13875
13982
|
if (!(options === null || options === void 0 ? void 0 : options.allowParamSpec)) {
|
13876
|
-
flags |= 32 /*
|
13983
|
+
flags |= 32 /* DisallowParamSpec */;
|
13877
13984
|
}
|
13878
13985
|
return getTypeOfExpression(node, flags);
|
13879
13986
|
}
|
@@ -14004,8 +14111,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14004
14111
|
// Disables recording of errors and warnings and disables
|
14005
14112
|
// any caching of types, under the assumption that we're
|
14006
14113
|
// performing speculative evaluations.
|
14007
|
-
function useSpeculativeMode(speculativeNode, callback) {
|
14008
|
-
speculativeTypeTracker.enterSpeculativeContext(speculativeNode);
|
14114
|
+
function useSpeculativeMode(speculativeNode, callback, allowCacheRetention = true) {
|
14115
|
+
speculativeTypeTracker.enterSpeculativeContext(speculativeNode, allowCacheRetention);
|
14009
14116
|
try {
|
14010
14117
|
const result = callback();
|
14011
14118
|
speculativeTypeTracker.leaveSpeculativeContext();
|
@@ -16225,6 +16332,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16225
16332
|
}
|
16226
16333
|
});
|
16227
16334
|
}
|
16335
|
+
else if (remainingSrcSubtypes.length === 0) {
|
16336
|
+
// If we've assigned all of the source subtypes but one or more dest
|
16337
|
+
// TypeVars have gone unmatched, treat this as success.
|
16338
|
+
return true;
|
16339
|
+
}
|
16228
16340
|
else {
|
16229
16341
|
// Try to assign a union of the remaining source types to
|
16230
16342
|
// the first destination TypeVar.
|
@@ -16484,6 +16596,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16484
16596
|
if (constructorFunction.specializedTypes) {
|
16485
16597
|
constructorFunction.specializedTypes.returnType = objectType;
|
16486
16598
|
}
|
16599
|
+
if (!constructorFunction.details.docString && classType.details.docString) {
|
16600
|
+
constructorFunction.details.docString = classType.details.docString;
|
16601
|
+
}
|
16487
16602
|
}
|
16488
16603
|
return constructorFunction;
|
16489
16604
|
};
|
@@ -16512,10 +16627,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16512
16627
|
if (newInfo) {
|
16513
16628
|
const newType = getTypeOfMember(newInfo);
|
16514
16629
|
const convertNewToConstructor = (newSubtype) => {
|
16515
|
-
|
16630
|
+
let constructorFunction = bindFunctionToClassOrObject(classType, newSubtype,
|
16516
16631
|
/* memberClass */ undefined,
|
16517
16632
|
/* errorNode */ undefined, recursionCount,
|
16518
16633
|
/* treatConstructorAsClassMember */ true);
|
16634
|
+
if (constructorFunction) {
|
16635
|
+
constructorFunction = types_1.FunctionType.clone(constructorFunction);
|
16636
|
+
if (!constructorFunction.details.docString && classType.details.docString) {
|
16637
|
+
constructorFunction.details.docString = classType.details.docString;
|
16638
|
+
}
|
16639
|
+
}
|
16640
|
+
return constructorFunction;
|
16519
16641
|
};
|
16520
16642
|
if ((0, types_1.isFunction)(newType)) {
|
16521
16643
|
return convertNewToConstructor(newType);
|
@@ -16541,6 +16663,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16541
16663
|
const constructorFunction = types_1.FunctionType.createSynthesizedInstance('__new__', 1 /* ConstructorMethod */);
|
16542
16664
|
constructorFunction.details.declaredReturnType = types_1.ClassType.cloneAsInstance(classType);
|
16543
16665
|
types_1.FunctionType.addDefaultParameters(constructorFunction);
|
16666
|
+
if (!constructorFunction.details.docString && classType.details.docString) {
|
16667
|
+
constructorFunction.details.docString = classType.details.docString;
|
16668
|
+
}
|
16544
16669
|
return constructorFunction;
|
16545
16670
|
}
|
16546
16671
|
// If the class is a protocol and it has a `__call__` method but no other methods
|
@@ -17707,10 +17832,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17707
17832
|
types_1.OverloadedFunctionType.addOverload(newOverloadType, boundMethod);
|
17708
17833
|
}
|
17709
17834
|
});
|
17710
|
-
if (newOverloadType.
|
17711
|
-
return newOverloadType.overloads[0];
|
17712
|
-
}
|
17713
|
-
else if (newOverloadType.overloads.length === 0) {
|
17835
|
+
if (types_1.OverloadedFunctionType.getOverloads(newOverloadType).length === 0) {
|
17714
17836
|
// No overloads matched, so rebind with the errorNode
|
17715
17837
|
// to report the error(s) to the user.
|
17716
17838
|
if (errorNode) {
|
@@ -17720,6 +17842,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17720
17842
|
}
|
17721
17843
|
return undefined;
|
17722
17844
|
}
|
17845
|
+
else if (newOverloadType.overloads.length === 1) {
|
17846
|
+
return newOverloadType.overloads[0];
|
17847
|
+
}
|
17723
17848
|
return newOverloadType;
|
17724
17849
|
}
|
17725
17850
|
return memberType;
|
@@ -17911,7 +18036,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17911
18036
|
narrowConstrainedTypeVar,
|
17912
18037
|
assignType,
|
17913
18038
|
validateOverrideMethod,
|
17914
|
-
validateInitSubclassArgs,
|
17915
18039
|
assignTypeToExpression,
|
17916
18040
|
assignClassToSelf,
|
17917
18041
|
getTypedDictClassType,
|