@zzzen/pyright-internal 1.2.0-dev.20230611 → 1.2.0-dev.20230625
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/checker.js +11 -3
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +28 -4
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/codeFlowUtils.js +2 -0
- package/dist/analyzer/codeFlowUtils.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +19 -2
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructors.js +9 -4
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.js +65 -1
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/decorators.d.ts +7 -0
- package/dist/analyzer/decorators.js +438 -0
- package/dist/analyzer/decorators.js.map +1 -0
- package/dist/analyzer/operations.d.ts +1 -1
- package/dist/analyzer/operations.js +4 -4
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/parameterUtils.d.ts +2 -1
- package/dist/analyzer/parameterUtils.js +1 -0
- package/dist/analyzer/parameterUtils.js.map +1 -1
- package/dist/analyzer/program.d.ts +2 -2
- package/dist/analyzer/program.js +2 -25
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +1 -1
- package/dist/analyzer/protocols.js +47 -26
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +2 -2
- package/dist/analyzer/service.js +2 -7
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +397 -649
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +6 -4
- package/dist/analyzer/typeEvaluatorTypes.js +4 -2
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +22 -19
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.d.ts +2 -1
- package/dist/analyzer/typePrinter.js +27 -5
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +13 -12
- package/dist/analyzer/typeUtils.js +87 -54
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.js +9 -11
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +7 -3
- package/dist/analyzer/types.js +56 -14
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/extensibility.d.ts +9 -5
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/workspaceEditUtils.d.ts +3 -3
- package/dist/common/workspaceEditUtils.js +23 -13
- package/dist/common/workspaceEditUtils.js.map +1 -1
- package/dist/languageServerBase.d.ts +48 -0
- package/dist/languageServerBase.js +3 -3
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/completionProvider.js +2 -0
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.js +13 -9
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +1 -4
- package/dist/localization/localize.js +1 -1
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +1 -1
- package/dist/parser/parser.js +5 -2
- package/dist/parser/parser.js.map +1 -1
- package/dist/pyright.js +40 -3
- package/dist/pyright.js.map +1 -1
- package/dist/tests/checker.test.js +1 -1
- package/dist/tests/fourslash/completions.typeAlias.fourslash.js +1 -1
- package/dist/tests/fourslash/completions.variableDocStrings.fourslash.js +1 -1
- package/dist/tests/fourslash/hover.docstring.alias.fourslash.js +3 -3
- package/dist/tests/fourslash/hover.init.fourslash.js +1 -1
- package/dist/tests/fourslash/hover.variable.docString.fourslash.js +1 -1
- package/dist/tests/positionUtils.test.js +10 -0
- package/dist/tests/positionUtils.test.js.map +1 -1
- package/dist/tests/tokenizer.test.js +12 -1
- package/dist/tests/tokenizer.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +185 -137
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +257 -323
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +223 -178
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +59 -47
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/typePrinter.test.js +2 -2
- package/dist/tests/workspaceEditUtils.test.js +2 -3
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/package.json +1 -1
@@ -54,6 +54,7 @@ const constraintSolver_1 = require("./constraintSolver");
|
|
54
54
|
const constructors_1 = require("./constructors");
|
55
55
|
const dataClasses_1 = require("./dataClasses");
|
56
56
|
const declarationUtils_1 = require("./declarationUtils");
|
57
|
+
const decorators_1 = require("./decorators");
|
57
58
|
const enums_1 = require("./enums");
|
58
59
|
const functionTransform_1 = require("./functionTransform");
|
59
60
|
const namedTuples_1 = require("./namedTuples");
|
@@ -211,7 +212,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
211
212
|
return typeCache.size;
|
212
213
|
}
|
213
214
|
// This function should be called immediately prior to discarding
|
214
|
-
// the type evaluator. It forcibly
|
215
|
+
// the type evaluator. It forcibly replaces existing cache maps
|
215
216
|
// with empty equivalents. This shouldn't be necessary, but there
|
216
217
|
// is apparently a bug in the v8 GC where it is unable to detect
|
217
218
|
// circular references in complex data structures, so it fails
|
@@ -371,10 +372,27 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
371
372
|
// context, logging any errors in the process. This may require the
|
372
373
|
// type of surrounding statements to be evaluated.
|
373
374
|
function getType(node) {
|
374
|
-
var _a;
|
375
|
-
|
375
|
+
var _a, _b;
|
376
|
+
let type = (_a = evaluateTypeForSubnode(node, () => {
|
376
377
|
evaluateTypesForExpressionInContext(node);
|
377
378
|
})) === null || _a === void 0 ? void 0 : _a.type;
|
379
|
+
// If this is a type parameter with a calculated variance, see if we
|
380
|
+
// can swap it out for a version that has a computed variance.
|
381
|
+
if (type && (0, types_1.isTypeVar)(type) && type.details.declaredVariance === 0 /* Auto */) {
|
382
|
+
const typeVarType = type;
|
383
|
+
const typeParamListNode = ParseTreeUtils.getParentNodeOfType(node, 76 /* TypeParameterList */);
|
384
|
+
if (((_b = typeParamListNode === null || typeParamListNode === void 0 ? void 0 : typeParamListNode.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 10 /* Class */) {
|
385
|
+
const classTypeResult = getTypeOfClass(typeParamListNode.parent);
|
386
|
+
if (classTypeResult) {
|
387
|
+
inferTypeParameterVarianceForClass(classTypeResult.classType);
|
388
|
+
const typeParam = classTypeResult.classType.details.typeParameters.find((param) => (0, types_1.isTypeSame)(param, typeVarType, { ignoreTypeFlags: true }));
|
389
|
+
if (typeParam) {
|
390
|
+
type = types_1.TypeBase.isInstance(type) ? types_1.TypeVarType.cloneAsInstance(typeParam) : typeParam;
|
391
|
+
}
|
392
|
+
}
|
393
|
+
}
|
394
|
+
}
|
395
|
+
return type;
|
378
396
|
}
|
379
397
|
function getTypeResult(node) {
|
380
398
|
return evaluateTypeForSubnode(node, () => {
|
@@ -446,7 +464,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
446
464
|
}
|
447
465
|
}
|
448
466
|
function getTypeOfExpression(node, flags = 0 /* None */, inferenceContext) {
|
449
|
-
var _a;
|
450
467
|
// Is this type already cached?
|
451
468
|
const cacheEntry = readTypeCacheEntry(node);
|
452
469
|
if (cacheEntry &&
|
@@ -485,7 +502,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
485
502
|
// at that point.
|
486
503
|
initializedBasicTypes(node);
|
487
504
|
let typeResult;
|
488
|
-
let
|
505
|
+
let expectingInstantiable = (flags & 128 /* ExpectingInstantiableType */) !== 0;
|
489
506
|
switch (node.nodeType) {
|
490
507
|
case 38 /* Name */: {
|
491
508
|
typeResult = getTypeOfName(node, flags);
|
@@ -500,11 +517,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
500
517
|
break;
|
501
518
|
}
|
502
519
|
case 9 /* Call */: {
|
503
|
-
typeResult = getTypeOfCall(node,
|
520
|
+
typeResult = getTypeOfCall(node, flags, inferenceContext);
|
504
521
|
break;
|
505
522
|
}
|
506
523
|
case 52 /* Tuple */: {
|
507
|
-
typeResult = getTypeOfTuple(node,
|
524
|
+
typeResult = getTypeOfTuple(node, flags, inferenceContext);
|
508
525
|
break;
|
509
526
|
}
|
510
527
|
case 11 /* Constant */: {
|
@@ -516,7 +533,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
516
533
|
if (isExpectingType) {
|
517
534
|
// Don't report expecting type errors again. We will have already
|
518
535
|
// reported them when analyzing the contents of the string.
|
519
|
-
|
536
|
+
expectingInstantiable = false;
|
520
537
|
}
|
521
538
|
typeResult = getTypeOfStringList(node, flags, isExpectingType);
|
522
539
|
break;
|
@@ -534,7 +551,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
534
551
|
break;
|
535
552
|
}
|
536
553
|
case 7 /* BinaryOperation */: {
|
537
|
-
|
554
|
+
let effectiveFlags = flags;
|
555
|
+
// If we're expecting an instantiable type and this isn't a union operator,
|
556
|
+
// don't require that the two operands are also instantiable types.
|
557
|
+
if (expectingInstantiable && node.operator !== 6 /* BitwiseOr */) {
|
558
|
+
effectiveFlags &= ~128 /* ExpectingInstantiableType */;
|
559
|
+
}
|
560
|
+
typeResult = (0, operations_1.getTypeOfBinaryOperation)(evaluatorInterface, node, effectiveFlags, inferenceContext);
|
538
561
|
break;
|
539
562
|
}
|
540
563
|
case 5 /* AugmentedAssignment */: {
|
@@ -596,7 +619,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
596
619
|
break;
|
597
620
|
}
|
598
621
|
case 54 /* TypeAnnotation */: {
|
599
|
-
typeResult = getTypeOfExpression(node.typeAnnotation, 128 /*
|
622
|
+
typeResult = getTypeOfExpression(node.typeAnnotation, 128 /* ExpectingInstantiableType */ |
|
600
623
|
256 /* ExpectingTypeAnnotation */ |
|
601
624
|
8 /* EvaluateStringLiteralAsType */ |
|
602
625
|
32 /* DisallowParamSpec */ |
|
@@ -627,23 +650,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
627
650
|
// We shouldn't get here. If we do, report an error.
|
628
651
|
(0, debug_1.fail)(`Unhandled expression type '${ParseTreeUtils.printExpression(node)}'`);
|
629
652
|
}
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
addError(localize_1.Localizer.Diagnostic.typeVarTupleContext(), node);
|
634
|
-
typeResult.type = types_1.UnknownType.create();
|
635
|
-
}
|
636
|
-
}
|
637
|
-
if (!(0, typeUtils_1.isEffectivelyInstantiable)(typeResult.type)) {
|
638
|
-
const isEmptyVariadic = (0, types_1.isClassInstance)(typeResult.type) &&
|
639
|
-
types_1.ClassType.isTupleClass(typeResult.type) &&
|
640
|
-
((_a = typeResult.type.tupleTypeArguments) === null || _a === void 0 ? void 0 : _a.length) === 0;
|
641
|
-
if (!isEmptyVariadic) {
|
642
|
-
addExpectedClassDiagnostic(typeResult.type, node);
|
643
|
-
typeResult.type = types_1.UnknownType.create();
|
644
|
-
typeResult.typeErrors = true;
|
645
|
-
}
|
646
|
-
}
|
653
|
+
// Do we need to validate that the type is instantiable?
|
654
|
+
if (expectingInstantiable) {
|
655
|
+
validateTypeIsInstantiable(typeResult, flags, node);
|
647
656
|
}
|
648
657
|
writeTypeCache(node, typeResult, flags, inferenceContext, /* allowSpeculativeCaching */ true);
|
649
658
|
// If there was an expected type, make sure that the result type is compatible.
|
@@ -659,7 +668,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
659
668
|
if (!typeResult.isIncomplete && !typeResult.expectedTypeDiagAddendum) {
|
660
669
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
661
670
|
// Make sure the resulting type is assignable to the expected type.
|
662
|
-
if (!assignType(inferenceContext.expectedType, typeResult.type, diag
|
671
|
+
if (!assignType(inferenceContext.expectedType, typeResult.type, diag,
|
672
|
+
/* destTypeVarContext */ undefined,
|
673
|
+
/* srcTypeVarContext */ undefined, 512 /* IgnoreTypeVarScope */)) {
|
663
674
|
typeResult.typeErrors = true;
|
664
675
|
typeResult.expectedTypeDiagAddendum = diag;
|
665
676
|
diag.addTextRange(node);
|
@@ -672,6 +683,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
672
683
|
}
|
673
684
|
return typeResult;
|
674
685
|
}
|
686
|
+
function validateTypeIsInstantiable(typeResult, flags, node) {
|
687
|
+
var _a;
|
688
|
+
// If the type is incomplete, don't log any diagnostics yet.
|
689
|
+
if (typeResult.isIncomplete) {
|
690
|
+
return;
|
691
|
+
}
|
692
|
+
if (flags & 64 /* DisallowTypeVarTuple */) {
|
693
|
+
if ((0, types_1.isVariadicTypeVar)(typeResult.type) && !typeResult.type.isVariadicInUnion) {
|
694
|
+
addError(localize_1.Localizer.Diagnostic.typeVarTupleContext(), node);
|
695
|
+
typeResult.type = types_1.UnknownType.create();
|
696
|
+
}
|
697
|
+
}
|
698
|
+
if (!(0, typeUtils_1.isEffectivelyInstantiable)(typeResult.type)) {
|
699
|
+
const isEmptyVariadic = (0, types_1.isClassInstance)(typeResult.type) &&
|
700
|
+
types_1.ClassType.isTupleClass(typeResult.type) &&
|
701
|
+
((_a = typeResult.type.tupleTypeArguments) === null || _a === void 0 ? void 0 : _a.length) === 0;
|
702
|
+
if (!isEmptyVariadic) {
|
703
|
+
addExpectedClassDiagnostic(typeResult.type, node);
|
704
|
+
typeResult.type = types_1.UnknownType.create();
|
705
|
+
typeResult.typeErrors = true;
|
706
|
+
}
|
707
|
+
}
|
708
|
+
}
|
675
709
|
function getTypeOfAwaitOperator(node, flags, inferenceContext) {
|
676
710
|
const effectiveExpectedType = inferenceContext
|
677
711
|
? createAwaitableReturnType(node, inferenceContext.expectedType, /* isGenerator */ false)
|
@@ -748,7 +782,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
748
782
|
function getTypeOfStringList(node, flags, isExpectingType) {
|
749
783
|
let typeResult;
|
750
784
|
if (isExpectingType) {
|
751
|
-
let updatedFlags = flags | 4 /* AllowForwardReferences */ | 128 /*
|
785
|
+
let updatedFlags = flags | 4 /* AllowForwardReferences */ | 128 /* ExpectingInstantiableType */;
|
752
786
|
// In most cases, annotations within a string are not parsed by the interpreter.
|
753
787
|
// There are a few exceptions (e.g. the "bound" value for a TypeVar constructor).
|
754
788
|
if ((flags & 4194304 /* InterpreterParsesStringLiteral */) === 0) {
|
@@ -911,7 +945,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
911
945
|
return specialType;
|
912
946
|
}
|
913
947
|
}
|
914
|
-
let evaluatorFlags = 128 /*
|
948
|
+
let evaluatorFlags = 128 /* ExpectingInstantiableType */ |
|
915
949
|
256 /* ExpectingTypeAnnotation */ |
|
916
950
|
1 /* ConvertEllipsisToAny */ |
|
917
951
|
8 /* EvaluateStringLiteralAsType */;
|
@@ -975,64 +1009,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
975
1009
|
}
|
976
1010
|
return (0, typeUtils_1.convertToInstance)(annotationType);
|
977
1011
|
}
|
978
|
-
function getTypeOfDecorator(node, functionOrClassType) {
|
979
|
-
// Evaluate the type of the decorator expression.
|
980
|
-
let flags = AnalyzerNodeInfo.getFileInfo(node).isStubFile
|
981
|
-
? 4 /* AllowForwardReferences */
|
982
|
-
: 0 /* None */;
|
983
|
-
if (node.expression.nodeType !== 9 /* Call */) {
|
984
|
-
flags |= 2 /* DoNotSpecialize */;
|
985
|
-
}
|
986
|
-
const decoratorTypeResult = getTypeOfExpression(node.expression, flags);
|
987
|
-
// Special-case the combination of a classmethod decorator applied
|
988
|
-
// to a property. This is allowed in Python 3.9, but it's not reflected
|
989
|
-
// in the builtins.pyi stub for classmethod.
|
990
|
-
if ((0, types_1.isInstantiableClass)(decoratorTypeResult.type) &&
|
991
|
-
types_1.ClassType.isBuiltIn(decoratorTypeResult.type, 'classmethod') &&
|
992
|
-
(0, typeUtils_1.isProperty)(functionOrClassType)) {
|
993
|
-
return functionOrClassType;
|
994
|
-
}
|
995
|
-
const argList = [
|
996
|
-
{
|
997
|
-
argumentCategory: 0 /* Simple */,
|
998
|
-
typeResult: { type: functionOrClassType },
|
999
|
-
},
|
1000
|
-
];
|
1001
|
-
const returnType = validateCallArguments(node.expression, argList, decoratorTypeResult,
|
1002
|
-
/* typeVarContext */ undefined,
|
1003
|
-
/* skipUnknownArgCheck */ true).returnType || types_1.UnknownType.create();
|
1004
|
-
// If the return type is a function that has no annotations
|
1005
|
-
// and just *args and **kwargs parameters, assume that it
|
1006
|
-
// preserves the type of the input function.
|
1007
|
-
if ((0, types_1.isFunction)(returnType) && !returnType.details.declaredReturnType) {
|
1008
|
-
if (!returnType.details.parameters.some((param, index) => {
|
1009
|
-
// Don't allow * or / separators or params with declared types.
|
1010
|
-
if (!param.name || param.hasDeclaredType) {
|
1011
|
-
return true;
|
1012
|
-
}
|
1013
|
-
// Allow *args or **kwargs parameters.
|
1014
|
-
if (param.category !== 0 /* Simple */) {
|
1015
|
-
return false;
|
1016
|
-
}
|
1017
|
-
// Allow inferred "self" or "cls" parameters.
|
1018
|
-
return index !== 0 || !param.isTypeInferred;
|
1019
|
-
})) {
|
1020
|
-
return functionOrClassType;
|
1021
|
-
}
|
1022
|
-
}
|
1023
|
-
// If the decorator is completely unannotated and the return type
|
1024
|
-
// includes unknowns, assume that it preserves the type of the input
|
1025
|
-
// function.
|
1026
|
-
if ((0, typeUtils_1.isPartlyUnknown)(returnType)) {
|
1027
|
-
if ((0, types_1.isFunction)(decoratorTypeResult.type)) {
|
1028
|
-
if (!decoratorTypeResult.type.details.parameters.find((param) => param.typeAnnotation !== undefined) &&
|
1029
|
-
decoratorTypeResult.type.details.declaredReturnType === undefined) {
|
1030
|
-
return functionOrClassType;
|
1031
|
-
}
|
1032
|
-
}
|
1033
|
-
}
|
1034
|
-
return returnType;
|
1035
|
-
}
|
1036
1012
|
function canBeFalsy(type, recursionCount = 0) {
|
1037
1013
|
type = makeTopLevelTypeVarsConcrete(type);
|
1038
1014
|
if (recursionCount > types_1.maxTypeRecursionCount) {
|
@@ -1259,21 +1235,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1259
1235
|
memberInfo = getTypeOfClassMemberName(errorNode, classType,
|
1260
1236
|
/* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
|
1261
1237
|
}
|
1262
|
-
// If this is a protocol class X and we're accessing a non ClassVar,
|
1263
|
-
// emit an error.
|
1264
|
-
if (memberInfo &&
|
1265
|
-
memberInfo.classType &&
|
1266
|
-
memberInfo.symbol &&
|
1267
|
-
(0, types_1.isClass)(memberInfo.classType) &&
|
1268
|
-
types_1.ClassType.isProtocolClass(memberInfo.classType)) {
|
1269
|
-
const primaryDecl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(memberInfo.symbol);
|
1270
|
-
if (primaryDecl && primaryDecl.type === 1 /* Variable */ && !memberInfo.isClassVar) {
|
1271
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolMemberNotClassVar().format({
|
1272
|
-
memberName,
|
1273
|
-
className: memberInfo.classType.details.name,
|
1274
|
-
}), errorNode);
|
1275
|
-
}
|
1276
|
-
}
|
1277
1238
|
const isMemberPresentOnClass = (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.classType) !== undefined;
|
1278
1239
|
// If it wasn't found on the class, see if it's part of the metaclass.
|
1279
1240
|
if (!memberInfo) {
|
@@ -2896,7 +2857,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2896
2857
|
if ((0, types_1.isTypeVar)(type) &&
|
2897
2858
|
!type.details.isParamSpec &&
|
2898
2859
|
!type.isVariadicInUnion &&
|
2899
|
-
(flags & 128 /*
|
2860
|
+
(flags & 128 /* ExpectingInstantiableType */) === 0 &&
|
2900
2861
|
type.details.name === name) {
|
2901
2862
|
// Handle the special case of a PEP 604 union. These can appear within
|
2902
2863
|
// an implied type alias where we are not expecting a type.
|
@@ -2916,7 +2877,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2916
2877
|
}
|
2917
2878
|
}
|
2918
2879
|
}
|
2919
|
-
if ((flags & 128 /*
|
2880
|
+
if ((flags & 128 /* ExpectingInstantiableType */) !== 0) {
|
2920
2881
|
if ((flags & 1024 /* AllowGenericClassType */) === 0) {
|
2921
2882
|
if ((0, types_1.isInstantiableClass)(type) && types_1.ClassType.isBuiltIn(type, 'Generic')) {
|
2922
2883
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericNotAllowed(), node);
|
@@ -3097,7 +3058,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3097
3058
|
}
|
3098
3059
|
// Is this a generic class that needs to be specialized?
|
3099
3060
|
if ((0, types_1.isInstantiableClass)(type)) {
|
3100
|
-
if ((flags & 128 /*
|
3061
|
+
if ((flags & 128 /* ExpectingInstantiableType */) !== 0 &&
|
3062
|
+
(flags & 512 /* AllowMissingTypeArgs */) === 0) {
|
3101
3063
|
if (!type.typeAliasInfo && (0, typeUtils_1.requiresTypeArguments)(type)) {
|
3102
3064
|
if (!type.typeArguments || !type.isTypeArgumentExplicit) {
|
3103
3065
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
|
@@ -3111,7 +3073,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3111
3073
|
}
|
3112
3074
|
}
|
3113
3075
|
// Is this a generic type alias that needs to be specialized?
|
3114
|
-
if ((flags & 128 /*
|
3076
|
+
if ((flags & 128 /* ExpectingInstantiableType */) !== 0 &&
|
3115
3077
|
type.typeAliasInfo &&
|
3116
3078
|
type.typeAliasInfo.typeParameters &&
|
3117
3079
|
type.typeAliasInfo.typeParameters.length > 0 &&
|
@@ -4209,7 +4171,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4209
4171
|
// If this is meant to be a type and the base expression is a string expression,
|
4210
4172
|
// emit an error because this will generate a runtime exception in Python versions
|
4211
4173
|
// less than 3.10.
|
4212
|
-
if (flags & 128 /*
|
4174
|
+
if (flags & 128 /* ExpectingInstantiableType */) {
|
4213
4175
|
if (node.baseExpression.nodeType === 48 /* StringList */) {
|
4214
4176
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
4215
4177
|
if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
|
@@ -4541,7 +4503,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4541
4503
|
if ((0, types_1.isAnyOrUnknown)(concreteSubtype)) {
|
4542
4504
|
return concreteSubtype;
|
4543
4505
|
}
|
4544
|
-
if (flags & 128 /*
|
4506
|
+
if (flags & 128 /* ExpectingInstantiableType */) {
|
4545
4507
|
if ((0, types_1.isTypeVar)(unexpandedSubtype)) {
|
4546
4508
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNotSubscriptable().format({
|
4547
4509
|
type: printType(unexpandedSubtype),
|
@@ -4556,7 +4518,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4556
4518
|
if (concreteSubtype.details.effectiveMetaclass &&
|
4557
4519
|
(0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass) &&
|
4558
4520
|
!types_1.ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) &&
|
4559
|
-
(flags & 128 /*
|
4521
|
+
(flags & 128 /* ExpectingInstantiableType */) === 0) {
|
4560
4522
|
const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
|
4561
4523
|
/* usage */ undefined,
|
4562
4524
|
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 32 /* ConsiderMetaclassOnly */);
|
@@ -5063,7 +5025,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5063
5025
|
function getTypeArg(node, flags, supportsDictExpression) {
|
5064
5026
|
let typeResult;
|
5065
5027
|
let adjustedFlags = flags |
|
5066
|
-
128 /*
|
5028
|
+
128 /* ExpectingInstantiableType */ |
|
5067
5029
|
1 /* ConvertEllipsisToAny */ |
|
5068
5030
|
8 /* EvaluateStringLiteralAsType */;
|
5069
5031
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
@@ -5110,8 +5072,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5110
5072
|
}
|
5111
5073
|
return typeResult;
|
5112
5074
|
}
|
5113
|
-
function getTypeOfTuple(node,
|
5114
|
-
if ((flags & 128 /*
|
5075
|
+
function getTypeOfTuple(node, flags, inferenceContext) {
|
5076
|
+
if ((flags & 128 /* ExpectingInstantiableType */) !== 0 &&
|
5077
|
+
node.expressions.length === 0 &&
|
5078
|
+
!inferenceContext) {
|
5115
5079
|
return { type: makeTupleObject([]), isEmptyTupleShorthand: true };
|
5116
5080
|
}
|
5117
5081
|
// If the expected type is a union, recursively call for each of the subtypes
|
@@ -5263,7 +5227,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5263
5227
|
}
|
5264
5228
|
return entryTypes;
|
5265
5229
|
}
|
5266
|
-
function getTypeOfCall(node,
|
5230
|
+
function getTypeOfCall(node, flags, inferenceContext) {
|
5267
5231
|
var _a;
|
5268
5232
|
let baseTypeResult;
|
5269
5233
|
// Handle immediate calls of lambdas specially.
|
@@ -5551,9 +5515,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5551
5515
|
return types_1.NoneType.createInstance();
|
5552
5516
|
}
|
5553
5517
|
function getTypeOfSuperCall(node) {
|
5518
|
+
var _a;
|
5554
5519
|
if (node.arguments.length > 2) {
|
5555
5520
|
addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
|
5556
5521
|
}
|
5522
|
+
const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
|
5523
|
+
const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
|
5557
5524
|
// Determine which class the "super" call is applied to. If
|
5558
5525
|
// there is no first argument, then the class is implicit.
|
5559
5526
|
let targetClassType;
|
@@ -5565,10 +5532,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5565
5532
|
}
|
5566
5533
|
}
|
5567
5534
|
else {
|
5568
|
-
|
5569
|
-
|
5570
|
-
const classTypeInfo = getTypeOfClass(enclosingClass);
|
5571
|
-
targetClassType = classTypeInfo ? classTypeInfo.classType : types_1.UnknownType.create();
|
5535
|
+
if (enclosingClassType) {
|
5536
|
+
targetClassType = enclosingClassType !== null && enclosingClassType !== void 0 ? enclosingClassType : types_1.UnknownType.create();
|
5572
5537
|
}
|
5573
5538
|
else {
|
5574
5539
|
addError(localize_1.Localizer.Diagnostic.superCallZeroArgForm(), node.leftExpression);
|
@@ -5608,33 +5573,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5608
5573
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.superCallSecondArg().format({ type: printType(targetClassType) }), node.arguments[1].valueExpression);
|
5609
5574
|
}
|
5610
5575
|
}
|
5611
|
-
else {
|
5576
|
+
else if (enclosingClassType) {
|
5577
|
+
bindToType = types_1.ClassType.cloneAsInstance(enclosingClassType);
|
5578
|
+
// Get the type from the self or cls parameter if it is explicitly annotated.
|
5579
|
+
// If it's a TypeVar, change the bindToType into a conditional type.
|
5612
5580
|
const enclosingMethod = ParseTreeUtils.getEnclosingFunction(node);
|
5613
5581
|
let implicitBindToType;
|
5614
|
-
// Get the type from the self or cls parameter if it is explicitly annotated.
|
5615
5582
|
if (enclosingMethod) {
|
5616
5583
|
const methodTypeInfo = getTypeOfFunction(enclosingMethod);
|
5617
5584
|
if (methodTypeInfo) {
|
5618
5585
|
const methodType = methodTypeInfo.functionType;
|
5619
|
-
if (types_1.FunctionType.isClassMethod(methodType)
|
5586
|
+
if (types_1.FunctionType.isClassMethod(methodType) ||
|
5587
|
+
types_1.FunctionType.isConstructorMethod(methodType) ||
|
5588
|
+
types_1.FunctionType.isInstanceMethod(methodType)) {
|
5620
5589
|
if (methodType.details.parameters.length > 0 &&
|
5621
5590
|
methodType.details.parameters[0].hasDeclaredType) {
|
5622
5591
|
implicitBindToType = makeTopLevelTypeVarsConcrete(methodType.details.parameters[0].type);
|
5623
5592
|
}
|
5624
5593
|
}
|
5625
|
-
else if (types_1.FunctionType.isInstanceMethod(methodType)) {
|
5626
|
-
if (methodType.details.parameters.length > 0 &&
|
5627
|
-
methodType.details.parameters[0].hasDeclaredType) {
|
5628
|
-
implicitBindToType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.convertToInstantiable)(methodType.details.parameters[0].type));
|
5629
|
-
}
|
5630
|
-
}
|
5631
5594
|
}
|
5632
5595
|
}
|
5633
|
-
if (
|
5634
|
-
bindToType = implicitBindToType;
|
5635
|
-
}
|
5636
|
-
else if ((0, types_1.isInstantiableClass)(targetClassType)) {
|
5637
|
-
bindToType = targetClassType;
|
5596
|
+
if (bindToType && implicitBindToType) {
|
5597
|
+
bindToType = (0, typeUtils_1.addConditionToType)(bindToType, (0, typeUtils_1.getTypeCondition)(implicitBindToType));
|
5638
5598
|
}
|
5639
5599
|
}
|
5640
5600
|
// Determine whether super() should return an instance of the class or
|
@@ -5659,7 +5619,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5659
5619
|
const parentNode = node.parent;
|
5660
5620
|
if (parentNode.nodeType === 35 /* MemberAccess */) {
|
5661
5621
|
const memberName = parentNode.memberName.value;
|
5662
|
-
const
|
5622
|
+
const effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
|
5623
|
+
const lookupResults = bindToType
|
5624
|
+
? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
|
5625
|
+
: undefined;
|
5663
5626
|
if (lookupResults && (0, types_1.isInstantiableClass)(lookupResults.classType)) {
|
5664
5627
|
return {
|
5665
5628
|
type: resultIsInstance
|
@@ -5867,6 +5830,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5867
5830
|
if (matches.length < 2) {
|
5868
5831
|
return matches;
|
5869
5832
|
}
|
5833
|
+
// If the relevance of some matches differs, filter out the ones that
|
5834
|
+
// are lower relevance. This favors *args parameters in cases where
|
5835
|
+
// a *args argument is used.
|
5836
|
+
if (matches[0].matchResults.relevance !== matches[matches.length - 1].matchResults.relevance) {
|
5837
|
+
matches = matches.filter((m) => m.matchResults.relevance === matches[0].matchResults.relevance);
|
5838
|
+
if (matches.length < 2) {
|
5839
|
+
return matches;
|
5840
|
+
}
|
5841
|
+
}
|
5870
5842
|
// If all of the return types match, select the first one.
|
5871
5843
|
if ((0, typeUtils_1.areTypesSame)(matches.map((match) => match.returnType), { treatAnySameAsUnknown: true })) {
|
5872
5844
|
return [matches[0]];
|
@@ -5875,6 +5847,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5875
5847
|
if (!firstArgResults) {
|
5876
5848
|
return matches;
|
5877
5849
|
}
|
5850
|
+
let foundAmbiguousAnyArg = false;
|
5878
5851
|
for (let i = 0; i < firstArgResults.length; i++) {
|
5879
5852
|
// If the arg is Any or Unknown, see if the corresponding
|
5880
5853
|
// parameter types differ in any way.
|
@@ -5883,10 +5856,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5883
5856
|
? match.matchResults.argParams[i].paramType
|
5884
5857
|
: types_1.UnknownType.create());
|
5885
5858
|
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
5886
|
-
|
5859
|
+
foundAmbiguousAnyArg = true;
|
5887
5860
|
}
|
5888
5861
|
}
|
5889
5862
|
}
|
5863
|
+
// If the first overload has a different number of effective arguments
|
5864
|
+
// than latter overloads, don't filter any of them. This typically means
|
5865
|
+
// that one of the arguments is an unpacked iterator, and it maps to
|
5866
|
+
// an indeterminate number of parameters, which means that the overload
|
5867
|
+
// selection is ambiguous.
|
5868
|
+
if (foundAmbiguousAnyArg || matches.some((match) => match.argResults.length !== firstArgResults.length)) {
|
5869
|
+
return matches;
|
5870
|
+
}
|
5890
5871
|
return [matches[0]];
|
5891
5872
|
}
|
5892
5873
|
function getBestOverloadForArguments(errorNode, typeResult, argList) {
|
@@ -6185,8 +6166,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6185
6166
|
// Verify that the cast is necessary.
|
6186
6167
|
const castToType = getTypeOfArgumentExpectingType(argList[0]).type;
|
6187
6168
|
const castFromType = getTypeOfArgument(argList[1]).type;
|
6188
|
-
if (
|
6189
|
-
if ((0, types_1.isTypeSame)(
|
6169
|
+
if (types_1.TypeBase.isInstantiable(castToType) && !(0, types_1.isUnknown)(castToType)) {
|
6170
|
+
if ((0, types_1.isTypeSame)((0, typeUtils_1.convertToInstance)(castToType), castFromType, {
|
6190
6171
|
ignorePseudoGeneric: true,
|
6191
6172
|
})) {
|
6192
6173
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUnnecessaryCast, diagnosticRules_1.DiagnosticRule.reportUnnecessaryCast, localize_1.Localizer.Diagnostic.unnecessaryCast().format({
|
@@ -6883,7 +6864,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6883
6864
|
while (argIndex < argList.length) {
|
6884
6865
|
if (argList[argIndex].argumentCategory === 2 /* UnpackedDictionary */) {
|
6885
6866
|
// Verify that the type used in this expression is a SupportsKeysAndGetItem[str, T].
|
6886
|
-
const argType = getTypeOfArgument(argList[argIndex]).type;
|
6867
|
+
const argType = getTypeOfArgument(argList[argIndex], (0, typeUtils_1.makeInferenceContext)(paramDetails.unpackedKwargsTypedDictType)).type;
|
6887
6868
|
if ((0, types_1.isAnyOrUnknown)(argType)) {
|
6888
6869
|
unpackedDictionaryArgType = argType;
|
6889
6870
|
}
|
@@ -6993,6 +6974,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6993
6974
|
unpackedDictionaryArgType = types_1.UnknownType.create();
|
6994
6975
|
}
|
6995
6976
|
}
|
6977
|
+
if (paramDetails.kwargsIndex !== undefined && unpackedDictionaryArgType) {
|
6978
|
+
const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
|
6979
|
+
validateArgTypeParams.push({
|
6980
|
+
paramCategory: 0 /* Simple */,
|
6981
|
+
paramType,
|
6982
|
+
requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
|
6983
|
+
argType: unpackedDictionaryArgType,
|
6984
|
+
argument: argList[argIndex],
|
6985
|
+
errorNode: argList[argIndex].valueExpression || errorNode,
|
6986
|
+
paramName: paramDetails.params[paramDetails.kwargsIndex].param.name,
|
6987
|
+
});
|
6988
|
+
}
|
6996
6989
|
if (!isValidMappingType) {
|
6997
6990
|
if (!isDiagnosticSuppressedForNode(errorNode)) {
|
6998
6991
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
|
@@ -7265,7 +7258,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7265
7258
|
// Special-case the builtin isinstance and issubclass functions.
|
7266
7259
|
if (['isinstance', 'issubclass'].some((name) => name === typeResult.type.details.builtInName) &&
|
7267
7260
|
validateArgTypeParams.length === 2) {
|
7268
|
-
validateArgTypeParams[1].
|
7261
|
+
validateArgTypeParams[1].isinstanceParam = true;
|
7269
7262
|
}
|
7270
7263
|
return {
|
7271
7264
|
overload: typeResult.type,
|
@@ -7324,13 +7317,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7324
7317
|
// the expected type if possible.
|
7325
7318
|
// Determine which type arguments are needed to match the expected type.
|
7326
7319
|
if ((0, types_1.isClassInstance)(effectiveReturnType)) {
|
7327
|
-
// If the return type is a class and the expected type is a union
|
7328
|
-
// that
|
7320
|
+
// If the return type is a class and the expected type is a union
|
7321
|
+
// that is type compatible with that class, filter the subtypes in
|
7322
|
+
// the union to see if we can find one that is potentially compatible.
|
7329
7323
|
if ((0, types_1.isUnion)(effectiveExpectedType)) {
|
7330
7324
|
const filteredType = (0, typeUtils_1.mapSubtypes)(effectiveExpectedType, (subtype) => {
|
7331
|
-
|
7332
|
-
|
7333
|
-
|
7325
|
+
if (!(0, types_1.isClassInstance)(subtype) || subtype.details.typeParameters.length === 0) {
|
7326
|
+
return undefined;
|
7327
|
+
}
|
7328
|
+
if (types_1.ClassType.isProtocolClass(subtype) ||
|
7329
|
+
subtype.details.mro.some((mroClass) => {
|
7330
|
+
return ((0, types_1.isClassInstance)(mroClass) &&
|
7331
|
+
mroClass.details.typeParameters.length > 0 &&
|
7332
|
+
types_1.ClassType.isSameGenericClass(effectiveReturnType, mroClass));
|
7333
|
+
})) {
|
7334
|
+
return subtype;
|
7335
|
+
}
|
7336
|
+
return undefined;
|
7334
7337
|
});
|
7335
7338
|
if ((0, types_1.isClassInstance)(filteredType)) {
|
7336
7339
|
effectiveExpectedType = filteredType;
|
@@ -7645,6 +7648,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7645
7648
|
// list and reports any mismatches in types or counts. Returns the
|
7646
7649
|
// specialized return type of the call.
|
7647
7650
|
function validateFunctionArguments(errorNode, argList, typeResult, typeVarContext, skipUnknownArgCheck = false, inferenceContext) {
|
7651
|
+
var _a;
|
7652
|
+
const signatureTracker = (_a = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.signatureTracker) !== null && _a !== void 0 ? _a : new typeUtils_1.UniqueSignatureTracker();
|
7653
|
+
typeResult.type = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(typeResult.type, signatureTracker, errorNode.start);
|
7648
7654
|
const matchResults = matchFunctionArgumentsToParameters(errorNode, argList, typeResult, 0);
|
7649
7655
|
if (matchResults.argumentErrors) {
|
7650
7656
|
// Evaluate types of all args. This will ensure that referenced symbols are
|
@@ -7660,7 +7666,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7660
7666
|
overloadsUsedForCall: [],
|
7661
7667
|
};
|
7662
7668
|
}
|
7663
|
-
return validateFunctionArgumentTypesWithContext(errorNode, matchResults, typeVarContext, skipUnknownArgCheck, inferenceContext);
|
7669
|
+
return validateFunctionArgumentTypesWithContext(errorNode, matchResults, typeVarContext, skipUnknownArgCheck, (0, typeUtils_1.makeInferenceContext)(inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.expectedType, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.isTypeIncomplete, signatureTracker));
|
7664
7670
|
}
|
7665
7671
|
// Determines whether the specified argument list satisfies the function
|
7666
7672
|
// signature bound to the specified ParamSpec. Return value indicates success.
|
@@ -7849,11 +7855,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7849
7855
|
argType = argParam.argType;
|
7850
7856
|
}
|
7851
7857
|
else {
|
7852
|
-
const flags = argParam.
|
7853
|
-
?
|
7858
|
+
const flags = argParam.isinstanceParam
|
7859
|
+
? 512 /* AllowMissingTypeArgs */ |
|
7860
|
+
8 /* EvaluateStringLiteralAsType */ |
|
7854
7861
|
32 /* DisallowParamSpec */ |
|
7855
7862
|
64 /* DisallowTypeVarTuple */
|
7856
|
-
:
|
7863
|
+
: 2 /* DoNotSpecialize */;
|
7857
7864
|
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedType, !!(typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete), signatureTracker));
|
7858
7865
|
argType = exprTypeResult.type;
|
7859
7866
|
// If the type includes multiple instances of a generic function
|
@@ -7888,15 +7895,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7888
7895
|
if (argParam.argType) {
|
7889
7896
|
argType = argParam.argType;
|
7890
7897
|
}
|
7891
|
-
else if (argParam.expectingType && !argParam.argument.typeResult && argParam.argument.valueExpression) {
|
7892
|
-
const argTypeResult = getTypeOfExpression(argParam.argument.valueExpression, 8 /* EvaluateStringLiteralAsType */ |
|
7893
|
-
32 /* DisallowParamSpec */ |
|
7894
|
-
64 /* DisallowTypeVarTuple */);
|
7895
|
-
argType = argTypeResult.type;
|
7896
|
-
if (argTypeResult.isIncomplete) {
|
7897
|
-
isTypeIncomplete = true;
|
7898
|
-
}
|
7899
|
-
}
|
7900
7898
|
else {
|
7901
7899
|
const argTypeResult = getTypeOfArgument(argParam.argument);
|
7902
7900
|
argType = argTypeResult.type;
|
@@ -8412,7 +8410,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8412
8410
|
typeParameters = [];
|
8413
8411
|
let isTypeParamListValid = true;
|
8414
8412
|
typeParamsExpr.expressions.map((expr) => {
|
8415
|
-
let entryType = getTypeOfExpression(expr, 128 /*
|
8413
|
+
let entryType = getTypeOfExpression(expr, 128 /* ExpectingInstantiableType */).type;
|
8416
8414
|
if ((0, types_1.isTypeVar)(entryType)) {
|
8417
8415
|
if (entryType.scopeId) {
|
8418
8416
|
isTypeParamListValid = false;
|
@@ -8432,7 +8430,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8432
8430
|
}
|
8433
8431
|
}
|
8434
8432
|
return getTypeOfTypeAliasCommon(nameNode, nameNode, valueExpr,
|
8435
|
-
/* typeParamNodes */ undefined, () => typeParameters);
|
8433
|
+
/* typeParamNodes */ undefined, () => typeParameters !== null && typeParameters !== void 0 ? typeParameters : []);
|
8436
8434
|
}
|
8437
8435
|
function getBooleanValue(node) {
|
8438
8436
|
if (node.nodeType === 11 /* Constant */) {
|
@@ -8566,7 +8564,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8566
8564
|
function getTypeOfConstant(node, flags) {
|
8567
8565
|
let type;
|
8568
8566
|
if (node.constType === 26 /* None */) {
|
8569
|
-
type =
|
8567
|
+
type =
|
8568
|
+
(flags & 128 /* ExpectingInstantiableType */) !== 0
|
8569
|
+
? types_1.NoneType.createType()
|
8570
|
+
: types_1.NoneType.createInstance();
|
8570
8571
|
}
|
8571
8572
|
else if (node.constType === 33 /* True */ ||
|
8572
8573
|
node.constType === 15 /* False */ ||
|
@@ -8714,6 +8715,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8714
8715
|
// Infer the key and value types if possible.
|
8715
8716
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8716
8717
|
/* forceStrictInference */ true,
|
8718
|
+
/* isValueTypeInvariant */ true,
|
8717
8719
|
/* expectedKeyType */ undefined,
|
8718
8720
|
/* expectedValueType */ undefined, expectedTypedDictEntries, expectedDiagAddendum)) {
|
8719
8721
|
isIncomplete = true;
|
@@ -8746,17 +8748,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8746
8748
|
}
|
8747
8749
|
const expectedKeyType = specializedDict.typeArguments[0];
|
8748
8750
|
const expectedValueType = specializedDict.typeArguments[1];
|
8749
|
-
// Infer the key and value types if possible.
|
8750
|
-
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8751
|
-
/* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
8752
|
-
isIncomplete = true;
|
8753
|
-
}
|
8754
8751
|
// Dict and MutableMapping types have invariant value types, so they
|
8755
8752
|
// cannot be narrowed further. Other super-types like Mapping, Collection,
|
8756
8753
|
// and Iterable use covariant value types, so they can be narrowed.
|
8757
8754
|
const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
8758
8755
|
(types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
|
8759
8756
|
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
|
8757
|
+
// Infer the key and value types if possible.
|
8758
|
+
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8759
|
+
/* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
8760
|
+
isIncomplete = true;
|
8761
|
+
}
|
8760
8762
|
const specializedKeyType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedKeyType), keyTypes.map((result) => result.type),
|
8761
8763
|
/* isNarrowable */ false);
|
8762
8764
|
const specializedValueType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedValueType), valueTypes.map((result) => result.type), !isValueTypeInvariant);
|
@@ -8778,7 +8780,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8778
8780
|
let isIncomplete = false;
|
8779
8781
|
// Infer the key and value types if possible.
|
8780
8782
|
if (getKeyAndValueTypesFromDictionary(node, keyTypeResults, valueTypeResults,
|
8781
|
-
/* forceStrictInference */ hasExpectedType
|
8783
|
+
/* forceStrictInference */ hasExpectedType,
|
8784
|
+
/* isValueTypeInvariant */ false)) {
|
8782
8785
|
isIncomplete = true;
|
8783
8786
|
}
|
8784
8787
|
// Strip any literal values.
|
@@ -8816,11 +8819,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8816
8819
|
}
|
8817
8820
|
return { type, isIncomplete };
|
8818
8821
|
}
|
8819
|
-
function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
|
8822
|
+
function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, isValueTypeInvariant, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
|
8820
8823
|
let isIncomplete = false;
|
8821
8824
|
// Infer the key and value types if possible.
|
8822
8825
|
node.entries.forEach((entryNode, index) => {
|
8823
|
-
var _a;
|
8826
|
+
var _a, _b, _c;
|
8824
8827
|
let addUnknown = true;
|
8825
8828
|
if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
|
8826
8829
|
const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
|
@@ -8836,19 +8839,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8836
8839
|
expectedDiagAddendum.addAddendum(keyTypeResult.expectedTypeDiagAddendum);
|
8837
8840
|
}
|
8838
8841
|
let valueTypeResult;
|
8842
|
+
let entryInferenceContext;
|
8839
8843
|
if (expectedTypedDictEntries &&
|
8840
8844
|
(0, types_1.isClassInstance)(keyType) &&
|
8841
8845
|
types_1.ClassType.isBuiltIn(keyType, 'str') &&
|
8842
8846
|
(0, typeUtils_1.isLiteralType)(keyType) &&
|
8843
8847
|
expectedTypedDictEntries.has(keyType.literalValue)) {
|
8844
8848
|
const effectiveValueType = expectedTypedDictEntries.get(keyType.literalValue).valueType;
|
8849
|
+
entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
|
8845
8850
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
8846
|
-
/* flags */ undefined,
|
8851
|
+
/* flags */ undefined, entryInferenceContext);
|
8847
8852
|
}
|
8848
8853
|
else {
|
8849
8854
|
const effectiveValueType = expectedValueType !== null && expectedValueType !== void 0 ? expectedValueType : (forceStrictInference ? types_1.NeverType.createNever() : undefined);
|
8855
|
+
entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
|
8850
8856
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
8851
|
-
/* flags */ undefined,
|
8857
|
+
/* flags */ undefined, entryInferenceContext);
|
8858
|
+
}
|
8859
|
+
if (entryInferenceContext && !valueTypeResult.typeErrors) {
|
8860
|
+
valueTypeResult.type =
|
8861
|
+
(_a = inferTypeArgFromExpectedEntryType(entryInferenceContext, [valueTypeResult.type], !isValueTypeInvariant)) !== null && _a !== void 0 ? _a : valueTypeResult.type;
|
8852
8862
|
}
|
8853
8863
|
if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
|
8854
8864
|
expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
|
@@ -8871,8 +8881,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8871
8881
|
/* isTypeArgumentExplicit */ true));
|
8872
8882
|
}
|
8873
8883
|
}
|
8884
|
+
const entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(expectedType);
|
8874
8885
|
const unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
|
8875
|
-
/* flags */ undefined,
|
8886
|
+
/* flags */ undefined, entryInferenceContext);
|
8887
|
+
if (entryInferenceContext && !unexpandedTypeResult.typeErrors) {
|
8888
|
+
unexpandedTypeResult.type =
|
8889
|
+
(_b = inferTypeArgFromExpectedEntryType(entryInferenceContext, [unexpandedTypeResult.type], !isValueTypeInvariant)) !== null && _b !== void 0 ? _b : unexpandedTypeResult.type;
|
8890
|
+
}
|
8876
8891
|
if (unexpandedTypeResult.isIncomplete) {
|
8877
8892
|
isIncomplete = true;
|
8878
8893
|
}
|
@@ -8927,7 +8942,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8927
8942
|
}
|
8928
8943
|
// The result should be a tuple.
|
8929
8944
|
if ((0, types_1.isClassInstance)(dictEntryType) && (0, typeUtils_1.isTupleClass)(dictEntryType)) {
|
8930
|
-
const typeArgs = (
|
8945
|
+
const typeArgs = (_c = dictEntryType.tupleTypeArguments) === null || _c === void 0 ? void 0 : _c.map((t) => t.type);
|
8931
8946
|
if (typeArgs && typeArgs.length === 2) {
|
8932
8947
|
if (forceStrictInference || index < maxEntriesToUseForInference) {
|
8933
8948
|
keyTypes.push({ node: entryNode, type: typeArgs[0] });
|
@@ -9122,7 +9137,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9122
9137
|
if ((0, types_1.isAnyOrUnknown)(inferenceContext.expectedType)) {
|
9123
9138
|
return inferenceContext.expectedType;
|
9124
9139
|
}
|
9125
|
-
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
9140
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(inferenceContext.expectedType));
|
9126
9141
|
const expectedType = inferenceContext.expectedType;
|
9127
9142
|
let isCompatible = true;
|
9128
9143
|
entryTypes.forEach((entryType) => {
|
@@ -9139,7 +9154,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9139
9154
|
? combinedTypes
|
9140
9155
|
: stripLiteralValue(combinedTypes);
|
9141
9156
|
}
|
9142
|
-
return (0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true })
|
9157
|
+
return (0, typeUtils_1.mapSubtypes)((0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true }), (subtype) => {
|
9158
|
+
if (entryTypes.length !== 1) {
|
9159
|
+
return subtype;
|
9160
|
+
}
|
9161
|
+
const entryType = entryTypes[0];
|
9162
|
+
// If the entry type is a TypedDict instance, clone it with additional information.
|
9163
|
+
if ((0, types_1.isTypeSame)(subtype, entryType, { ignoreTypedDictNarrowEntries: true }) &&
|
9164
|
+
(0, types_1.isClass)(subtype) &&
|
9165
|
+
(0, types_1.isClass)(entryType) &&
|
9166
|
+
types_1.ClassType.isTypedDictClass(entryType)) {
|
9167
|
+
return types_1.ClassType.cloneForNarrowedTypedDictEntries(subtype, entryType.typedDictNarrowedEntries);
|
9168
|
+
}
|
9169
|
+
return subtype;
|
9170
|
+
});
|
9143
9171
|
}
|
9144
9172
|
function getTypeOfYield(node) {
|
9145
9173
|
let expectedYieldType;
|
@@ -9229,13 +9257,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9229
9257
|
// For now, use only the first expected type.
|
9230
9258
|
const expectedFunctionType = expectedFunctionTypes.length > 0 ? expectedFunctionTypes[0] : undefined;
|
9231
9259
|
let paramsArePositionOnly = true;
|
9260
|
+
const expectedParamDetails = expectedFunctionType ? (0, parameterUtils_1.getParameterListDetails)(expectedFunctionType) : undefined;
|
9232
9261
|
node.parameters.forEach((param, index) => {
|
9233
|
-
let paramType
|
9234
|
-
if (
|
9235
|
-
|
9262
|
+
let paramType;
|
9263
|
+
if (expectedParamDetails) {
|
9264
|
+
if (index < expectedParamDetails.params.length) {
|
9265
|
+
paramType = expectedParamDetails.params[index].type;
|
9266
|
+
}
|
9267
|
+
else if (param.defaultValue) {
|
9268
|
+
// If the lambda param has a default value but there is no associated
|
9269
|
+
// parameter in the expected type, assume that the default value is
|
9270
|
+
// being used to explicitly capture a value from an outer scope. Infer
|
9271
|
+
// its type from the default value expression.
|
9272
|
+
paramType = getTypeOfExpression(param.defaultValue, undefined, inferenceContext).type;
|
9273
|
+
}
|
9236
9274
|
}
|
9237
9275
|
if (param.name) {
|
9238
|
-
writeTypeCache(param.name, { type: transformVariadicParamType(node, param.category, paramType) }, 0 /* None */);
|
9276
|
+
writeTypeCache(param.name, { type: transformVariadicParamType(node, param.category, paramType !== null && paramType !== void 0 ? paramType : types_1.UnknownType.create()) }, 0 /* None */);
|
9239
9277
|
}
|
9240
9278
|
if (param.defaultValue) {
|
9241
9279
|
// Evaluate the default value if it's present.
|
@@ -9273,7 +9311,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9273
9311
|
hasDefault: !!param.defaultValue,
|
9274
9312
|
defaultValueExpression: param.defaultValue,
|
9275
9313
|
hasDeclaredType: true,
|
9276
|
-
type: paramType,
|
9314
|
+
type: paramType !== null && paramType !== void 0 ? paramType : types_1.UnknownType.create(),
|
9277
9315
|
};
|
9278
9316
|
types_1.FunctionType.addParameter(functionType, functionParam);
|
9279
9317
|
});
|
@@ -9579,11 +9617,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9579
9617
|
hasDeclaredType: true,
|
9580
9618
|
});
|
9581
9619
|
});
|
9582
|
-
|
9583
|
-
|
9584
|
-
|
9585
|
-
|
9586
|
-
|
9620
|
+
if (typeList.length > 0) {
|
9621
|
+
// Add a positional-only separator to the end of the parameter list.
|
9622
|
+
types_1.FunctionType.addParameter(functionType, {
|
9623
|
+
category: 0 /* Simple */,
|
9624
|
+
isNameSynthesized: false,
|
9625
|
+
type: types_1.UnknownType.create(),
|
9626
|
+
});
|
9627
|
+
}
|
9587
9628
|
}
|
9588
9629
|
else if ((0, typeUtils_1.isEllipsisType)(typeArgs[0].type)) {
|
9589
9630
|
types_1.FunctionType.addDefaultParameters(functionType);
|
@@ -9842,7 +9883,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9842
9883
|
}
|
9843
9884
|
const enclosingFunction = ParseTreeUtils.getEnclosingFunction(errorNode);
|
9844
9885
|
if (enclosingFunction) {
|
9845
|
-
const functionFlags = getFunctionFlagsFromDecorators(enclosingFunction,
|
9886
|
+
const functionFlags = (0, decorators_1.getFunctionFlagsFromDecorators)(evaluatorInterface, enclosingFunction,
|
9887
|
+
/* isInClass */ true);
|
9846
9888
|
const isInnerFunction = !!ParseTreeUtils.getEnclosingFunction(enclosingFunction);
|
9847
9889
|
if (!isInnerFunction) {
|
9848
9890
|
// Check for static methods.
|
@@ -10426,7 +10468,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10426
10468
|
}
|
10427
10469
|
if (isDeclaredTypeAlias(node.leftExpression)) {
|
10428
10470
|
flags |=
|
10429
|
-
128 /*
|
10471
|
+
128 /* ExpectingInstantiableType */ |
|
10430
10472
|
256 /* ExpectingTypeAnnotation */ |
|
10431
10473
|
8 /* EvaluateStringLiteralAsType */ |
|
10432
10474
|
32 /* DisallowParamSpec */ |
|
@@ -10712,7 +10754,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10712
10754
|
let protocolTypeParameters;
|
10713
10755
|
const initSubclassArgs = [];
|
10714
10756
|
let metaclassNode;
|
10715
|
-
let exprFlags = 128 /*
|
10757
|
+
let exprFlags = 128 /* ExpectingInstantiableType */ |
|
10716
10758
|
1024 /* AllowGenericClassType */ |
|
10717
10759
|
262144 /* DisallowNakedGeneric */ |
|
10718
10760
|
2048 /* DisallowTypeVarsWithScopeId */ |
|
@@ -11047,7 +11089,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11047
11089
|
let foundUnknown = false;
|
11048
11090
|
for (let i = node.decorators.length - 1; i >= 0; i--) {
|
11049
11091
|
const decorator = node.decorators[i];
|
11050
|
-
const newDecoratedType = applyClassDecorator(decoratedType, classType, decorator);
|
11092
|
+
const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
|
11051
11093
|
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
11052
11094
|
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
11053
11095
|
// Report this error only on the first unknown type.
|
@@ -11315,95 +11357,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11315
11357
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarsNotInGenericOrProtocol() + diag.getString(), errorNode);
|
11316
11358
|
}
|
11317
11359
|
}
|
11318
|
-
function applyClassDecorator(inputClassType, originalClassType, decoratorNode) {
|
11319
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(decoratorNode);
|
11320
|
-
let flags = fileInfo.isStubFile ? 4 /* AllowForwardReferences */ : 0 /* None */;
|
11321
|
-
if (decoratorNode.expression.nodeType !== 9 /* Call */) {
|
11322
|
-
flags |= 2 /* DoNotSpecialize */;
|
11323
|
-
}
|
11324
|
-
const decoratorType = getTypeOfExpression(decoratorNode.expression, flags).type;
|
11325
|
-
if (decoratorNode.expression.nodeType === 9 /* Call */) {
|
11326
|
-
const decoratorCallType = getTypeOfExpression(decoratorNode.expression.leftExpression, flags | 2 /* DoNotSpecialize */).type;
|
11327
|
-
if ((0, types_1.isFunction)(decoratorCallType)) {
|
11328
|
-
if (decoratorCallType.details.name === '__dataclass_transform__' ||
|
11329
|
-
decoratorCallType.details.builtInName === 'dataclass_transform') {
|
11330
|
-
originalClassType.details.classDataClassTransform = (0, dataClasses_1.validateDataClassTransformDecorator)(evaluatorInterface, decoratorNode.expression);
|
11331
|
-
}
|
11332
|
-
else if (decoratorCallType.details.builtInName === 'deprecated') {
|
11333
|
-
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
11334
|
-
return inputClassType;
|
11335
|
-
}
|
11336
|
-
}
|
11337
|
-
if ((0, types_1.isOverloadedFunction)(decoratorCallType)) {
|
11338
|
-
if (decoratorCallType.overloads.length > 0 &&
|
11339
|
-
decoratorCallType.overloads[0].details.builtInName === 'deprecated') {
|
11340
|
-
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
11341
|
-
return inputClassType;
|
11342
|
-
}
|
11343
|
-
}
|
11344
|
-
}
|
11345
|
-
if ((0, types_1.isOverloadedFunction)(decoratorType)) {
|
11346
|
-
const dataclassBehaviors = (0, dataClasses_1.getDataclassDecoratorBehaviors)(decoratorType);
|
11347
|
-
if (dataclassBehaviors) {
|
11348
|
-
(0, dataClasses_1.applyDataClassDecorator)(evaluatorInterface, decoratorNode, originalClassType, dataclassBehaviors,
|
11349
|
-
/* callNode */ undefined);
|
11350
|
-
return inputClassType;
|
11351
|
-
}
|
11352
|
-
if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') {
|
11353
|
-
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
11354
|
-
return inputClassType;
|
11355
|
-
}
|
11356
|
-
}
|
11357
|
-
else if ((0, types_1.isFunction)(decoratorType)) {
|
11358
|
-
if (decoratorType.details.builtInName === 'final') {
|
11359
|
-
originalClassType.details.flags |= 4096 /* Final */;
|
11360
|
-
// Don't call getTypeOfDecorator for final. We'll hard-code its
|
11361
|
-
// behavior because its function definition results in a cyclical
|
11362
|
-
// dependency between builtins, typing and _typeshed stubs.
|
11363
|
-
return inputClassType;
|
11364
|
-
}
|
11365
|
-
if (decoratorType.details.builtInName === 'deprecated') {
|
11366
|
-
originalClassType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
11367
|
-
return inputClassType;
|
11368
|
-
}
|
11369
|
-
if (decoratorType.details.builtInName === 'runtime_checkable') {
|
11370
|
-
originalClassType.details.flags |= 32768 /* RuntimeCheckable */;
|
11371
|
-
// Don't call getTypeOfDecorator for runtime_checkable. It appears
|
11372
|
-
// frequently in stubs, and it's a waste of time to validate its
|
11373
|
-
// parameters.
|
11374
|
-
return inputClassType;
|
11375
|
-
}
|
11376
|
-
// Is this a dataclass decorator?
|
11377
|
-
let dataclassBehaviors;
|
11378
|
-
let callNode;
|
11379
|
-
if (decoratorNode.expression.nodeType === 9 /* Call */) {
|
11380
|
-
callNode = decoratorNode.expression;
|
11381
|
-
const decoratorCallType = getTypeOfExpression(callNode.leftExpression, flags | 2 /* DoNotSpecialize */).type;
|
11382
|
-
dataclassBehaviors = (0, dataClasses_1.getDataclassDecoratorBehaviors)(decoratorCallType);
|
11383
|
-
}
|
11384
|
-
else {
|
11385
|
-
const decoratorType = getTypeOfExpression(decoratorNode.expression, flags).type;
|
11386
|
-
dataclassBehaviors = (0, dataClasses_1.getDataclassDecoratorBehaviors)(decoratorType);
|
11387
|
-
}
|
11388
|
-
if (dataclassBehaviors) {
|
11389
|
-
(0, dataClasses_1.applyDataClassDecorator)(evaluatorInterface, decoratorNode, originalClassType, dataclassBehaviors, callNode);
|
11390
|
-
return inputClassType;
|
11391
|
-
}
|
11392
|
-
}
|
11393
|
-
return getTypeOfDecorator(decoratorNode, inputClassType);
|
11394
|
-
}
|
11395
|
-
// Given a @typing.deprecated decorator node, returns either '' or a custom
|
11396
|
-
// deprecation message if one is provided.
|
11397
|
-
function getCustomDeprecationMessage(decorator) {
|
11398
|
-
if (decorator.expression.nodeType === 9 /* Call */ &&
|
11399
|
-
decorator.expression.arguments.length > 0 &&
|
11400
|
-
decorator.expression.arguments[0].argumentCategory === 0 /* Simple */ &&
|
11401
|
-
decorator.expression.arguments[0].valueExpression.nodeType === 48 /* StringList */ &&
|
11402
|
-
decorator.expression.arguments[0].valueExpression.strings.length === 1) {
|
11403
|
-
return decorator.expression.arguments[0].valueExpression.strings[0].value;
|
11404
|
-
}
|
11405
|
-
return '';
|
11406
|
-
}
|
11407
11360
|
// Runs any registered "callback hooks" that depend on the specified class type.
|
11408
11361
|
// This allows us to complete any work that requires dependent classes to be
|
11409
11362
|
// completed.
|
@@ -11550,7 +11503,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11550
11503
|
}
|
11551
11504
|
containingClassType = classInfo.classType;
|
11552
11505
|
}
|
11553
|
-
let functionFlags = getFunctionFlagsFromDecorators(node, !!containingClassNode);
|
11506
|
+
let functionFlags = (0, decorators_1.getFunctionFlagsFromDecorators)(evaluatorInterface, node, !!containingClassNode);
|
11554
11507
|
if (functionDecl === null || functionDecl === void 0 ? void 0 : functionDecl.isGenerator) {
|
11555
11508
|
functionFlags |= 16 /* Generator */;
|
11556
11509
|
}
|
@@ -11876,7 +11829,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11876
11829
|
let foundUnknown = false;
|
11877
11830
|
for (let i = node.decorators.length - 1; i >= 0; i--) {
|
11878
11831
|
const decorator = node.decorators[i];
|
11879
|
-
const newDecoratedType = applyFunctionDecorator(decoratedType, functionType, decorator, node);
|
11832
|
+
const newDecoratedType = (0, decorators_1.applyFunctionDecorator)(evaluatorInterface, decoratedType, functionType, decorator, node);
|
11880
11833
|
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
11881
11834
|
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
11882
11835
|
// Report this error only on the first unknown type.
|
@@ -11898,7 +11851,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11898
11851
|
markParamAccessed(param);
|
11899
11852
|
});
|
11900
11853
|
}
|
11901
|
-
decoratedType = addOverloadsToFunctionType(node, decoratedType);
|
11854
|
+
decoratedType = (0, decorators_1.addOverloadsToFunctionType)(evaluatorInterface, node, decoratedType);
|
11902
11855
|
}
|
11903
11856
|
writeTypeCache(node.name, { type: functionType }, 0 /* None */);
|
11904
11857
|
writeTypeCache(node, { type: decoratedType }, 0 /* None */);
|
@@ -11979,6 +11932,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11979
11932
|
const baseClassParamAnnotation = (_a = baseClassParam.typeAnnotation) !== null && _a !== void 0 ? _a : baseClassParam.typeAnnotationComment;
|
11980
11933
|
if (baseClassParamAnnotation) {
|
11981
11934
|
let inferredParamType = getTypeOfParameterAnnotation(baseClassParamAnnotation, functionNode.parameters[paramIndex].category);
|
11935
|
+
// If the parameter type is generic, specialize it in the context
|
11936
|
+
// of the child class.
|
11937
|
+
if ((0, typeUtils_1.requiresSpecialization)(inferredParamType) && (0, types_1.isClass)(baseClassMemberInfo.classType)) {
|
11938
|
+
const typeVarContext = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(baseClassMemberInfo.classType);
|
11939
|
+
inferredParamType = (0, typeUtils_1.applySolvedTypeVars)(inferredParamType, typeVarContext);
|
11940
|
+
}
|
11982
11941
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(functionNode);
|
11983
11942
|
if (fileInfo.isInPyTypedPackage && !fileInfo.isStubFile) {
|
11984
11943
|
inferredParamType = types_1.TypeBase.cloneForAmbiguousType(inferredParamType);
|
@@ -12004,10 +11963,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12004
11963
|
inferredParamType = (0, types_1.combineTypes)([defaultValueType, types_1.UnknownType.create()]);
|
12005
11964
|
}
|
12006
11965
|
else {
|
12007
|
-
|
12008
|
-
|
12009
|
-
|
12010
|
-
|
11966
|
+
let skipInference = false;
|
11967
|
+
if ((0, types_1.isFunction)(defaultValueType) || (0, types_1.isOverloadedFunction)(defaultValueType)) {
|
11968
|
+
// Do not infer parameter types that use a lambda or another function as a
|
11969
|
+
// default value. We're likely to generate false positives in this case.
|
11970
|
+
// It's not clear whether parameters should be positional-only or not.
|
11971
|
+
skipInference = true;
|
11972
|
+
}
|
11973
|
+
else if ((0, types_1.isClassInstance)(defaultValueType) &&
|
11974
|
+
types_1.ClassType.isBuiltIn(defaultValueType, ['tuple', 'list', 'set', 'dict'])) {
|
11975
|
+
// Do not infer certain types like tuple because it's likely to be
|
11976
|
+
// more restrictive (narrower) than intended.
|
11977
|
+
skipInference = true;
|
11978
|
+
}
|
11979
|
+
if (!skipInference) {
|
12011
11980
|
inferredParamType = stripLiteralValue(defaultValueType);
|
12012
11981
|
}
|
12013
11982
|
}
|
@@ -12061,268 +12030,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12061
12030
|
}
|
12062
12031
|
}
|
12063
12032
|
}
|
12064
|
-
// Scans through the decorators to find a few built-in decorators
|
12065
|
-
// that affect the function flags.
|
12066
|
-
function getFunctionFlagsFromDecorators(node, isInClass) {
|
12067
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
12068
|
-
let flags = 0 /* None */;
|
12069
|
-
if (isInClass) {
|
12070
|
-
// The "__new__" magic method is not an instance method.
|
12071
|
-
// It acts as a static method instead.
|
12072
|
-
if (node.name.value === '__new__') {
|
12073
|
-
flags |= 1 /* ConstructorMethod */;
|
12074
|
-
}
|
12075
|
-
// Several magic methods are treated as class methods implicitly
|
12076
|
-
// by the runtime. Check for these here.
|
12077
|
-
const implicitClassMethods = ['__init_subclass__', '__class_getitem__'];
|
12078
|
-
if (implicitClassMethods.some((name) => node.name.value === name)) {
|
12079
|
-
flags |= 2 /* ClassMethod */;
|
12080
|
-
}
|
12081
|
-
}
|
12082
|
-
for (const decoratorNode of node.decorators) {
|
12083
|
-
// Some stub files (e.g. builtins.pyi) rely on forward declarations of decorators.
|
12084
|
-
let evaluatorFlags = fileInfo.isStubFile ? 4 /* AllowForwardReferences */ : 0 /* None */;
|
12085
|
-
if (decoratorNode.expression.nodeType !== 9 /* Call */) {
|
12086
|
-
evaluatorFlags |= 2 /* DoNotSpecialize */;
|
12087
|
-
}
|
12088
|
-
const decoratorTypeResult = getTypeOfExpression(decoratorNode.expression, evaluatorFlags);
|
12089
|
-
const decoratorType = decoratorTypeResult.type;
|
12090
|
-
if ((0, types_1.isFunction)(decoratorType)) {
|
12091
|
-
if (decoratorType.details.builtInName === 'abstractmethod') {
|
12092
|
-
if (isInClass) {
|
12093
|
-
flags |= 8 /* AbstractMethod */;
|
12094
|
-
}
|
12095
|
-
}
|
12096
|
-
else if (decoratorType.details.builtInName === 'final') {
|
12097
|
-
flags |= 8192 /* Final */;
|
12098
|
-
}
|
12099
|
-
else if (decoratorType.details.builtInName === 'override') {
|
12100
|
-
flags |= 262144 /* Overridden */;
|
12101
|
-
}
|
12102
|
-
}
|
12103
|
-
else if ((0, types_1.isInstantiableClass)(decoratorType)) {
|
12104
|
-
if (types_1.ClassType.isBuiltIn(decoratorType, 'staticmethod')) {
|
12105
|
-
if (isInClass) {
|
12106
|
-
flags |= 4 /* StaticMethod */;
|
12107
|
-
}
|
12108
|
-
}
|
12109
|
-
else if (types_1.ClassType.isBuiltIn(decoratorType, 'classmethod')) {
|
12110
|
-
if (isInClass) {
|
12111
|
-
flags |= 2 /* ClassMethod */;
|
12112
|
-
}
|
12113
|
-
}
|
12114
|
-
}
|
12115
|
-
}
|
12116
|
-
return flags;
|
12117
|
-
}
|
12118
|
-
// Transforms the input function type into an output type based on the
|
12119
|
-
// decorator function described by the decoratorNode.
|
12120
|
-
function applyFunctionDecorator(inputFunctionType, undecoratedType, decoratorNode, functionNode) {
|
12121
|
-
const fileInfo = AnalyzerNodeInfo.getFileInfo(decoratorNode);
|
12122
|
-
// Some stub files (e.g. builtins.pyi) rely on forward declarations of decorators.
|
12123
|
-
let evaluatorFlags = fileInfo.isStubFile ? 4 /* AllowForwardReferences */ : 0 /* None */;
|
12124
|
-
if (decoratorNode.expression.nodeType !== 9 /* Call */) {
|
12125
|
-
evaluatorFlags |= 2 /* DoNotSpecialize */;
|
12126
|
-
}
|
12127
|
-
const decoratorTypeResult = getTypeOfExpression(decoratorNode.expression, evaluatorFlags);
|
12128
|
-
const decoratorType = decoratorTypeResult.type;
|
12129
|
-
// Special-case the "overload" because it has no definition. Older versions of typeshed
|
12130
|
-
// defined "overload" as an object, but newer versions define it as a function.
|
12131
|
-
if (((0, types_1.isInstantiableClass)(decoratorType) && types_1.ClassType.isSpecialBuiltIn(decoratorType, 'overload')) ||
|
12132
|
-
((0, types_1.isFunction)(decoratorType) && decoratorType.details.builtInName === 'overload')) {
|
12133
|
-
if ((0, types_1.isFunction)(inputFunctionType)) {
|
12134
|
-
inputFunctionType.details.flags |= 256 /* Overloaded */;
|
12135
|
-
undecoratedType.details.flags |= 256 /* Overloaded */;
|
12136
|
-
return inputFunctionType;
|
12137
|
-
}
|
12138
|
-
}
|
12139
|
-
if (decoratorNode.expression.nodeType === 9 /* Call */) {
|
12140
|
-
const decoratorCallType = getTypeOfExpression(decoratorNode.expression.leftExpression, evaluatorFlags | 2 /* DoNotSpecialize */).type;
|
12141
|
-
if ((0, types_1.isFunction)(decoratorCallType)) {
|
12142
|
-
if (decoratorCallType.details.name === '__dataclass_transform__' ||
|
12143
|
-
decoratorCallType.details.builtInName === 'dataclass_transform') {
|
12144
|
-
undecoratedType.details.decoratorDataClassBehaviors = (0, dataClasses_1.validateDataClassTransformDecorator)(evaluatorInterface, decoratorNode.expression);
|
12145
|
-
return inputFunctionType;
|
12146
|
-
}
|
12147
|
-
if (decoratorCallType.details.builtInName === 'deprecated') {
|
12148
|
-
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12149
|
-
return inputFunctionType;
|
12150
|
-
}
|
12151
|
-
}
|
12152
|
-
if ((0, types_1.isOverloadedFunction)(decoratorCallType)) {
|
12153
|
-
if (decoratorCallType.overloads.length > 0 &&
|
12154
|
-
decoratorCallType.overloads[0].details.builtInName === 'deprecated') {
|
12155
|
-
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12156
|
-
return inputFunctionType;
|
12157
|
-
}
|
12158
|
-
}
|
12159
|
-
}
|
12160
|
-
let returnType = getTypeOfDecorator(decoratorNode, inputFunctionType);
|
12161
|
-
// Check for some built-in decorator types with known semantics.
|
12162
|
-
if ((0, types_1.isFunction)(decoratorType)) {
|
12163
|
-
if (decoratorType.details.builtInName === 'abstractmethod') {
|
12164
|
-
return inputFunctionType;
|
12165
|
-
}
|
12166
|
-
if (decoratorType.details.builtInName === 'deprecated') {
|
12167
|
-
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12168
|
-
return inputFunctionType;
|
12169
|
-
}
|
12170
|
-
// Handle property setters and deleters.
|
12171
|
-
if (decoratorNode.expression.nodeType === 35 /* MemberAccess */) {
|
12172
|
-
const baseType = getTypeOfExpression(decoratorNode.expression.leftExpression, evaluatorFlags | 2 /* DoNotSpecialize */).type;
|
12173
|
-
if ((0, typeUtils_1.isProperty)(baseType)) {
|
12174
|
-
const memberName = decoratorNode.expression.memberName.value;
|
12175
|
-
if (memberName === 'setter') {
|
12176
|
-
if ((0, types_1.isFunction)(inputFunctionType)) {
|
12177
|
-
(0, properties_1.validatePropertyMethod)(evaluatorInterface, inputFunctionType, decoratorNode);
|
12178
|
-
return (0, properties_1.clonePropertyWithSetter)(evaluatorInterface, baseType, inputFunctionType, functionNode);
|
12179
|
-
}
|
12180
|
-
else {
|
12181
|
-
return inputFunctionType;
|
12182
|
-
}
|
12183
|
-
}
|
12184
|
-
else if (memberName === 'deleter') {
|
12185
|
-
if ((0, types_1.isFunction)(inputFunctionType)) {
|
12186
|
-
(0, properties_1.validatePropertyMethod)(evaluatorInterface, inputFunctionType, decoratorNode);
|
12187
|
-
return (0, properties_1.clonePropertyWithDeleter)(evaluatorInterface, baseType, inputFunctionType, functionNode);
|
12188
|
-
}
|
12189
|
-
else {
|
12190
|
-
return inputFunctionType;
|
12191
|
-
}
|
12192
|
-
}
|
12193
|
-
}
|
12194
|
-
}
|
12195
|
-
}
|
12196
|
-
else if ((0, types_1.isOverloadedFunction)(decoratorType)) {
|
12197
|
-
if (decoratorType.overloads.length > 0 && decoratorType.overloads[0].details.builtInName === 'deprecated') {
|
12198
|
-
undecoratedType.details.deprecatedMessage = getCustomDeprecationMessage(decoratorNode);
|
12199
|
-
return inputFunctionType;
|
12200
|
-
}
|
12201
|
-
}
|
12202
|
-
else if ((0, types_1.isInstantiableClass)(decoratorType)) {
|
12203
|
-
if (types_1.ClassType.isBuiltIn(decoratorType)) {
|
12204
|
-
switch (decoratorType.details.name) {
|
12205
|
-
case 'classmethod':
|
12206
|
-
case 'staticmethod': {
|
12207
|
-
const requiredFlag = decoratorType.details.name === 'classmethod'
|
12208
|
-
? 2 /* ClassMethod */
|
12209
|
-
: 4 /* StaticMethod */;
|
12210
|
-
// If the function isn't currently a class method or static method
|
12211
|
-
// (which can happen if the function was wrapped in a decorator),
|
12212
|
-
// add the appropriate flag.
|
12213
|
-
if ((0, types_1.isFunction)(inputFunctionType) && (inputFunctionType.details.flags & requiredFlag) === 0) {
|
12214
|
-
const newFunction = types_1.FunctionType.clone(inputFunctionType);
|
12215
|
-
newFunction.details.flags &= ~(1 /* ConstructorMethod */ |
|
12216
|
-
4 /* StaticMethod */ |
|
12217
|
-
2 /* ClassMethod */);
|
12218
|
-
newFunction.details.flags |= requiredFlag;
|
12219
|
-
return newFunction;
|
12220
|
-
}
|
12221
|
-
return inputFunctionType;
|
12222
|
-
}
|
12223
|
-
}
|
12224
|
-
}
|
12225
|
-
// Handle properties and subclasses of properties specially.
|
12226
|
-
if (types_1.ClassType.isPropertyClass(decoratorType)) {
|
12227
|
-
if ((0, types_1.isFunction)(inputFunctionType)) {
|
12228
|
-
(0, properties_1.validatePropertyMethod)(evaluatorInterface, inputFunctionType, decoratorNode);
|
12229
|
-
return (0, properties_1.createProperty)(evaluatorInterface, decoratorNode, decoratorType, inputFunctionType);
|
12230
|
-
}
|
12231
|
-
else if ((0, types_1.isClassInstance)(inputFunctionType)) {
|
12232
|
-
const boundMethod = getBoundMethod(inputFunctionType, '__call__');
|
12233
|
-
if (boundMethod && (0, types_1.isFunction)(boundMethod)) {
|
12234
|
-
return (0, properties_1.createProperty)(evaluatorInterface, decoratorNode, decoratorType, boundMethod);
|
12235
|
-
}
|
12236
|
-
return types_1.UnknownType.create();
|
12237
|
-
}
|
12238
|
-
}
|
12239
|
-
}
|
12240
|
-
if ((0, types_1.isFunction)(inputFunctionType) && (0, types_1.isFunction)(returnType)) {
|
12241
|
-
returnType = types_1.FunctionType.clone(returnType);
|
12242
|
-
// Copy the overload flag from the input function type.
|
12243
|
-
if (types_1.FunctionType.isOverloaded(inputFunctionType)) {
|
12244
|
-
returnType.details.flags |= 256 /* Overloaded */;
|
12245
|
-
}
|
12246
|
-
// Copy the docstrings from the input function type if the
|
12247
|
-
// decorator didn't have its own docstring.
|
12248
|
-
if (!returnType.details.docString) {
|
12249
|
-
returnType.details.docString = inputFunctionType.details.docString;
|
12250
|
-
}
|
12251
|
-
}
|
12252
|
-
return returnType;
|
12253
|
-
}
|
12254
|
-
// Given a function node and the function type associated with it, this
|
12255
|
-
// method searches for prior function nodes that are marked as @overload
|
12256
|
-
// and creates an OverloadedFunctionType that includes this function and
|
12257
|
-
// all previous ones.
|
12258
|
-
function addOverloadsToFunctionType(node, type) {
|
12259
|
-
let functionDecl;
|
12260
|
-
const decl = AnalyzerNodeInfo.getDeclaration(node);
|
12261
|
-
if (decl) {
|
12262
|
-
functionDecl = decl;
|
12263
|
-
}
|
12264
|
-
const symbolWithScope = lookUpSymbolRecursive(node, node.name.value, /* honorCodeFlow */ false);
|
12265
|
-
if (symbolWithScope) {
|
12266
|
-
const decls = symbolWithScope.symbol.getDeclarations();
|
12267
|
-
// Find this function's declaration.
|
12268
|
-
const declIndex = decls.findIndex((decl) => decl === functionDecl);
|
12269
|
-
if (declIndex > 0) {
|
12270
|
-
// Evaluate all of the previous function declarations. They will
|
12271
|
-
// be cached. We do it in this order to avoid a stack overflow due
|
12272
|
-
// to recursion if there is a large number (1000's) of overloads.
|
12273
|
-
for (let i = 0; i < declIndex; i++) {
|
12274
|
-
const decl = decls[i];
|
12275
|
-
if (decl.type === 5 /* Function */) {
|
12276
|
-
getTypeOfFunction(decl.node);
|
12277
|
-
}
|
12278
|
-
}
|
12279
|
-
let overloadedTypes = [];
|
12280
|
-
// Look at the previous declaration's type.
|
12281
|
-
const prevDecl = decls[declIndex - 1];
|
12282
|
-
if (prevDecl.type === 5 /* Function */) {
|
12283
|
-
const prevDeclDeclTypeInfo = getTypeOfFunction(prevDecl.node);
|
12284
|
-
if (prevDeclDeclTypeInfo) {
|
12285
|
-
if ((0, types_1.isFunction)(prevDeclDeclTypeInfo.decoratedType)) {
|
12286
|
-
if (types_1.FunctionType.isOverloaded(prevDeclDeclTypeInfo.decoratedType)) {
|
12287
|
-
overloadedTypes.push(prevDeclDeclTypeInfo.decoratedType);
|
12288
|
-
}
|
12289
|
-
}
|
12290
|
-
else if ((0, types_1.isOverloadedFunction)(prevDeclDeclTypeInfo.decoratedType)) {
|
12291
|
-
// If the previous declaration was itself an overloaded function,
|
12292
|
-
// copy the entries from it.
|
12293
|
-
(0, collectionUtils_1.appendArray)(overloadedTypes, prevDeclDeclTypeInfo.decoratedType.overloads);
|
12294
|
-
}
|
12295
|
-
}
|
12296
|
-
}
|
12297
|
-
overloadedTypes.push(type);
|
12298
|
-
if (overloadedTypes.length === 1) {
|
12299
|
-
return overloadedTypes[0];
|
12300
|
-
}
|
12301
|
-
// Apply the implementation's docstring to any overloads that don't
|
12302
|
-
// have their own docstrings.
|
12303
|
-
const implementation = overloadedTypes.find((signature) => !types_1.FunctionType.isOverloaded(signature));
|
12304
|
-
if (implementation === null || implementation === void 0 ? void 0 : implementation.details.docString) {
|
12305
|
-
overloadedTypes = overloadedTypes.map((overload) => {
|
12306
|
-
if (types_1.FunctionType.isOverloaded(overload) && !overload.details.docString) {
|
12307
|
-
return types_1.FunctionType.cloneWithDocString(overload, implementation.details.docString);
|
12308
|
-
}
|
12309
|
-
return overload;
|
12310
|
-
});
|
12311
|
-
}
|
12312
|
-
// Create a new overloaded type that copies the contents of the previous
|
12313
|
-
// one and adds a new function.
|
12314
|
-
const newOverload = types_1.OverloadedFunctionType.create(overloadedTypes);
|
12315
|
-
const prevOverload = overloadedTypes[overloadedTypes.length - 2];
|
12316
|
-
const isPrevOverloadAbstract = types_1.FunctionType.isAbstractMethod(prevOverload);
|
12317
|
-
const isCurrentOverloadAbstract = types_1.FunctionType.isAbstractMethod(type);
|
12318
|
-
if (isPrevOverloadAbstract !== isCurrentOverloadAbstract) {
|
12319
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.overloadAbstractMismatch().format({ name: node.name.value }), node.name);
|
12320
|
-
}
|
12321
|
-
return newOverload;
|
12322
|
-
}
|
12323
|
-
}
|
12324
|
-
return type;
|
12325
|
-
}
|
12326
12033
|
function createAsyncFunction(node, functionType) {
|
12327
12034
|
// Clone the original function and replace its return type with an
|
12328
12035
|
// Awaitable[<returnType>].
|
@@ -13228,7 +12935,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13228
12935
|
// See if the function is a method in a child class. We may be able to
|
13229
12936
|
// infer the type of the parameter from a method of the same name in
|
13230
12937
|
// a parent class if it has an annotated type.
|
13231
|
-
const functionFlags = getFunctionFlagsFromDecorators(functionNode, /* isInClass */ true);
|
12938
|
+
const functionFlags = (0, decorators_1.getFunctionFlagsFromDecorators)(evaluatorInterface, functionNode, /* isInClass */ true);
|
13232
12939
|
const inferredParamType = inferParameterType(functionNode, functionFlags, paramIndex, classInfo === null || classInfo === void 0 ? void 0 : classInfo.classType);
|
13233
12940
|
writeTypeCache(node.name, { type: transformVariadicParamType(node, node.category, inferredParamType !== null && inferredParamType !== void 0 ? inferredParamType : types_1.UnknownType.create()) }, 0 /* None */);
|
13234
12941
|
}
|
@@ -13737,7 +13444,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13737
13444
|
const specializedClass = types_1.ClassType.cloneForSpecialization(classType, typeArgTypes, typeArgs !== undefined);
|
13738
13445
|
return { type: specializedClass };
|
13739
13446
|
}
|
13740
|
-
function getTypeOfArgument(arg) {
|
13447
|
+
function getTypeOfArgument(arg, inferenceContext) {
|
13741
13448
|
if (arg.typeResult) {
|
13742
13449
|
return { type: arg.typeResult.type, isIncomplete: arg.typeResult.isIncomplete };
|
13743
13450
|
}
|
@@ -13747,7 +13454,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13747
13454
|
}
|
13748
13455
|
// If there was no defined type provided, there should always
|
13749
13456
|
// be a value expression from which we can retrieve the type.
|
13750
|
-
return getTypeOfExpression(arg.valueExpression);
|
13457
|
+
return getTypeOfExpression(arg.valueExpression, /* flags */ undefined, inferenceContext);
|
13751
13458
|
}
|
13752
13459
|
// This function is like getTypeOfArgument except that it is
|
13753
13460
|
// used in cases where the argument is expected to be a type
|
@@ -13762,7 +13469,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13762
13469
|
return getTypeOfExpressionExpectingType(arg.valueExpression);
|
13763
13470
|
}
|
13764
13471
|
function getTypeOfExpressionExpectingType(node, options) {
|
13765
|
-
let flags = 128 /*
|
13472
|
+
let flags = 128 /* ExpectingInstantiableType */ |
|
13473
|
+
8 /* EvaluateStringLiteralAsType */ |
|
13474
|
+
131072 /* DisallowClassVar */;
|
13766
13475
|
if (!(options === null || options === void 0 ? void 0 : options.allowTypeVarsWithoutScopeId)) {
|
13767
13476
|
flags |= 4096 /* DisallowTypeVarsWithoutScopeId */;
|
13768
13477
|
}
|
@@ -15334,34 +15043,39 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15334
15043
|
let isAssignable = true;
|
15335
15044
|
destType.details.fields.forEach((symbol, name) => {
|
15336
15045
|
var _a;
|
15337
|
-
if (isAssignable
|
15338
|
-
|
15339
|
-
|
15340
|
-
|
15341
|
-
|
15342
|
-
|
15343
|
-
|
15344
|
-
|
15345
|
-
|
15346
|
-
|
15347
|
-
|
15348
|
-
|
15349
|
-
|
15350
|
-
|
15351
|
-
|
15352
|
-
|
15046
|
+
if (!isAssignable || !symbol.isClassMember() || symbol.isIgnoredForProtocolMatch()) {
|
15047
|
+
return;
|
15048
|
+
}
|
15049
|
+
// Constructor methods are exempt from variance calculations.
|
15050
|
+
if (name === '__new__' || name === '__init__') {
|
15051
|
+
return;
|
15052
|
+
}
|
15053
|
+
const memberInfo = (0, typeUtils_1.lookUpClassMember)(srcType, name);
|
15054
|
+
(0, debug_1.assert)(memberInfo !== undefined);
|
15055
|
+
let destMemberType = (_a = getDeclaredTypeOfSymbol(symbol)) === null || _a === void 0 ? void 0 : _a.type;
|
15056
|
+
if (destMemberType) {
|
15057
|
+
const srcMemberType = getTypeOfMember(memberInfo);
|
15058
|
+
destMemberType = (0, typeUtils_1.partiallySpecializeType)(destMemberType, destType);
|
15059
|
+
// Properties require special processing.
|
15060
|
+
if ((0, types_1.isClassInstance)(destMemberType) &&
|
15061
|
+
types_1.ClassType.isPropertyClass(destMemberType) &&
|
15062
|
+
(0, types_1.isClassInstance)(srcMemberType) &&
|
15063
|
+
types_1.ClassType.isPropertyClass(srcMemberType)) {
|
15064
|
+
if (!(0, properties_1.assignProperty)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destMemberType), types_1.ClassType.cloneAsInstantiable(srcMemberType), destType, srcType, diag, typeVarContext,
|
15065
|
+
/* selfTypeVarContext */ undefined, recursionCount)) {
|
15066
|
+
isAssignable = false;
|
15353
15067
|
}
|
15354
|
-
|
15355
|
-
|
15356
|
-
|
15357
|
-
|
15358
|
-
|
15359
|
-
|
15360
|
-
|
15361
|
-
|
15362
|
-
|
15363
|
-
|
15364
|
-
|
15068
|
+
}
|
15069
|
+
else {
|
15070
|
+
const primaryDecl = symbol.getDeclarations()[0];
|
15071
|
+
// Class and instance variables that are mutable need to
|
15072
|
+
// enforce invariance.
|
15073
|
+
const flags = (primaryDecl === null || primaryDecl === void 0 ? void 0 : primaryDecl.type) === 1 /* Variable */ && !isFinalVariableDeclaration(primaryDecl)
|
15074
|
+
? 1 /* EnforceInvariance */
|
15075
|
+
: 0 /* Default */;
|
15076
|
+
if (!assignType(destMemberType, srcMemberType, diag, typeVarContext,
|
15077
|
+
/* srcTypeVarContext */ undefined, flags, recursionCount)) {
|
15078
|
+
isAssignable = false;
|
15365
15079
|
}
|
15366
15080
|
}
|
15367
15081
|
}
|
@@ -15458,7 +15172,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15458
15172
|
}
|
15459
15173
|
}
|
15460
15174
|
}
|
15461
|
-
function
|
15175
|
+
function assignTupleTypeArguments(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
|
15462
15176
|
var _a, _b;
|
15463
15177
|
const destTypeArgs = [...((_a = destType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [])];
|
15464
15178
|
const srcTypeArgs = [...((_b = srcType.tupleTypeArguments) !== null && _b !== void 0 ? _b : [])];
|
@@ -15500,32 +15214,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15500
15214
|
function assignClassWithTypeArgs(destType, srcType, inheritanceChain, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
|
15501
15215
|
let curSrcType = srcType;
|
15502
15216
|
let prevSrcType;
|
15503
|
-
let curDestTypeVarContext = destTypeVarContext;
|
15504
|
-
let effectiveFlags = flags;
|
15505
15217
|
inferTypeParameterVarianceForClass(destType);
|
15506
|
-
|
15507
|
-
if (
|
15508
|
-
|
15509
|
-
|
15218
|
+
// If we're enforcing invariance, literal types must match.
|
15219
|
+
if ((flags & 1 /* EnforceInvariance */) !== 0) {
|
15220
|
+
const srcIsLiteral = srcType.literalValue !== undefined;
|
15221
|
+
const destIsLiteral = destType.literalValue !== undefined;
|
15222
|
+
if (srcIsLiteral !== destIsLiteral) {
|
15223
|
+
return false;
|
15224
|
+
}
|
15510
15225
|
}
|
15511
15226
|
else {
|
15512
|
-
// If
|
15513
|
-
|
15514
|
-
|
15515
|
-
|
15227
|
+
// If the dest is an 'object', it's assignable.
|
15228
|
+
if (types_1.ClassType.isBuiltIn(destType, 'object')) {
|
15229
|
+
return true;
|
15230
|
+
}
|
15516
15231
|
}
|
15517
15232
|
for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) {
|
15518
15233
|
const ancestorType = inheritanceChain[ancestorIndex];
|
15519
|
-
const curSrcTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(curSrcType));
|
15520
15234
|
// If we've hit an "unknown", all bets are off, and we need to assume
|
15521
15235
|
// that the type is assignable.
|
15522
15236
|
if ((0, types_1.isUnknown)(ancestorType)) {
|
15523
15237
|
return true;
|
15524
15238
|
}
|
15525
|
-
// If we've hit an 'object', it's assignable.
|
15526
|
-
if (types_1.ClassType.isBuiltIn(ancestorType, 'object')) {
|
15527
|
-
return true;
|
15528
|
-
}
|
15529
15239
|
// If this isn't the first time through the loop, specialize
|
15530
15240
|
// for the next ancestor in the chain.
|
15531
15241
|
if (ancestorIndex < inheritanceChain.length - 1) {
|
@@ -15540,11 +15250,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15540
15250
|
}
|
15541
15251
|
curSrcType = (0, typeUtils_1.specializeForBaseClass)(effectiveCurSrcType, ancestorType);
|
15542
15252
|
}
|
15543
|
-
// Handle built-in types that support arbitrary numbers
|
15544
|
-
// of type parameters like Tuple.
|
15545
|
-
if (ancestorIndex === 0 && destType.tupleTypeArguments && curSrcType.tupleTypeArguments) {
|
15546
|
-
return assignTupleTypeArgs(destType, curSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
|
15547
|
-
}
|
15548
15253
|
// If there are no type parameters on this class, we're done.
|
15549
15254
|
const ancestorTypeParams = types_1.ClassType.getTypeParameters(ancestorType);
|
15550
15255
|
if (ancestorTypeParams.length === 0) {
|
@@ -15554,26 +15259,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15554
15259
|
if (!ancestorType.typeArguments) {
|
15555
15260
|
return true;
|
15556
15261
|
}
|
15557
|
-
|
15558
|
-
|
15262
|
+
prevSrcType = curSrcType;
|
15263
|
+
}
|
15264
|
+
// If we're enforcing invariance, literal types must match as well.
|
15265
|
+
if ((flags & 1 /* EnforceInvariance */) !== 0) {
|
15266
|
+
const srcIsLiteral = srcType.literalValue !== undefined;
|
15267
|
+
const destIsLiteral = destType.literalValue !== undefined;
|
15268
|
+
if (srcIsLiteral !== destIsLiteral) {
|
15559
15269
|
return false;
|
15560
15270
|
}
|
15561
|
-
|
15562
|
-
|
15563
|
-
|
15564
|
-
|
15271
|
+
}
|
15272
|
+
// Handle tuple, which supports a variable number of type arguments.
|
15273
|
+
if (destType.tupleTypeArguments && curSrcType.tupleTypeArguments) {
|
15274
|
+
return assignTupleTypeArguments(destType, curSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
|
15565
15275
|
}
|
15566
15276
|
if (destType.typeArguments) {
|
15567
15277
|
// If the dest type is specialized, make sure the specialized source
|
15568
15278
|
// type arguments are assignable to the dest type arguments.
|
15569
|
-
|
15570
|
-
return false;
|
15571
|
-
}
|
15279
|
+
return assignTypeArguments(destType, curSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
|
15572
15280
|
}
|
15573
|
-
|
15574
|
-
destType.details.typeParameters.length > 0 &&
|
15575
|
-
curSrcType.typeArguments &&
|
15576
|
-
!destTypeVarContext.isLocked()) {
|
15281
|
+
if (destTypeVarContext && curSrcType.typeArguments && !destTypeVarContext.isLocked()) {
|
15577
15282
|
// Populate the typeVar map with type arguments of the source.
|
15578
15283
|
const srcTypeArgs = curSrcType.typeArguments;
|
15579
15284
|
for (let i = 0; i < destType.details.typeParameters.length; i++) {
|
@@ -15599,7 +15304,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15599
15304
|
}
|
15600
15305
|
return undefined;
|
15601
15306
|
}
|
15602
|
-
function
|
15307
|
+
function assignTypeArguments(destType, srcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount) {
|
15603
15308
|
var _a, _b, _c;
|
15604
15309
|
(0, debug_1.assert)(types_1.ClassType.isSameGenericClass(destType, srcType));
|
15605
15310
|
inferTypeParameterVarianceForClass(destType);
|
@@ -15660,7 +15365,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15660
15365
|
}
|
15661
15366
|
}
|
15662
15367
|
else {
|
15663
|
-
if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 1 /* EnforceInvariance */, recursionCount)) {
|
15368
|
+
if (!assignType(destTypeArg, srcTypeArg, assignmentDiag, destTypeVarContext, srcTypeVarContext, flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */, recursionCount)) {
|
15664
15369
|
// Don't report errors with type variables in "pseudo-random"
|
15665
15370
|
// classes since these type variables are not real.
|
15666
15371
|
if (!types_1.ClassType.isPseudoGenericClass(destType)) {
|
@@ -16168,7 +15873,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16168
15873
|
return true;
|
16169
15874
|
}
|
16170
15875
|
if ((0, types_1.isFunction)(concreteSrcType)) {
|
16171
|
-
if (assignFunction(destType, concreteSrcType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext !== null && destTypeVarContext !== void 0 ? destTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(destType)), srcTypeVarContext !== null && srcTypeVarContext !== void 0 ? srcTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.
|
15876
|
+
if (assignFunction(destType, concreteSrcType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext !== null && destTypeVarContext !== void 0 ? destTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(destType)), srcTypeVarContext !== null && srcTypeVarContext !== void 0 ? srcTypeVarContext : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(concreteSrcType)), flags, recursionCount)) {
|
16172
15877
|
return true;
|
16173
15878
|
}
|
16174
15879
|
}
|
@@ -16625,9 +16330,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16625
16330
|
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
|
16626
16331
|
if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
|
16627
16332
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16628
|
-
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
16629
|
-
512 /* IgnoreTypeVarScope */ |
|
16630
|
-
128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16333
|
+
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16631
16334
|
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext);
|
16632
16335
|
}
|
16633
16336
|
}
|
@@ -16635,9 +16338,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16635
16338
|
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
|
16636
16339
|
if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
|
16637
16340
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16638
|
-
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
16639
|
-
512 /* IgnoreTypeVarScope */ |
|
16640
|
-
128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16341
|
+
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16641
16342
|
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext);
|
16642
16343
|
}
|
16643
16344
|
if (reverseMatchingFailed) {
|
@@ -17103,9 +16804,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17103
16804
|
});
|
17104
16805
|
const srcParamSpec = effectiveSrcType.details.paramSpec;
|
17105
16806
|
const destParamSpec = effectiveDestType.details.paramSpec;
|
17106
|
-
|
17107
|
-
|
17108
|
-
|
16807
|
+
// If there are remaining parameters and the source and dest do not contain
|
16808
|
+
// the same ParamSpec, synthesize a function for the remaining parameters.
|
16809
|
+
if (remainingParams.length > 0 ||
|
16810
|
+
!srcParamSpec ||
|
16811
|
+
!(0, types_1.isTypeSame)(srcParamSpec, destParamSpec, { ignoreTypeFlags: true })) {
|
17109
16812
|
const remainingFunction = types_1.FunctionType.createInstance('', '', '', effectiveSrcType.details.flags | 64 /* SynthesizedMethod */, effectiveSrcType.details.docString);
|
17110
16813
|
remainingFunction.details.typeVarScopeId = effectiveSrcType.details.typeVarScopeId;
|
17111
16814
|
remainingParams.forEach((param) => {
|
@@ -17114,28 +16817,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17114
16817
|
remainingFunction.details.paramSpec = srcParamSpec
|
17115
16818
|
? (0, typeUtils_1.convertToInstance)(srcParamSpec)
|
17116
16819
|
: undefined;
|
17117
|
-
if (!(
|
17118
|
-
/* diag */ undefined,
|
16820
|
+
if (!assignType(destParamSpec, remainingFunction,
|
16821
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
|
17119
16822
|
// If we couldn't assign the function to the ParamSpec, see if we can
|
17120
16823
|
// assign only the ParamSpec. This is possible if there were no
|
17121
16824
|
// remaining parameters.
|
17122
16825
|
if (remainingParams.length > 0 ||
|
17123
16826
|
!srcParamSpec ||
|
17124
|
-
!(
|
17125
|
-
/* diag */ undefined,
|
16827
|
+
!assignType(destParamSpec, (0, typeUtils_1.convertToInstance)(srcParamSpec),
|
16828
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
|
17126
16829
|
canAssign = false;
|
17127
16830
|
}
|
17128
16831
|
}
|
17129
16832
|
}
|
17130
|
-
else {
|
17131
|
-
// If there are any remaining parameters or the source doesn't include the
|
17132
|
-
// dest param spec itself, it is not assignable in this case.
|
17133
|
-
if (!srcParamSpec ||
|
17134
|
-
!(0, types_1.isTypeSame)(srcParamSpec, destParamSpec, { ignoreTypeFlags: true }) ||
|
17135
|
-
remainingParams.length > 0) {
|
17136
|
-
canAssign = false;
|
17137
|
-
}
|
17138
|
-
}
|
17139
16833
|
}
|
17140
16834
|
}
|
17141
16835
|
// Match the return parameter.
|
@@ -17293,7 +16987,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17293
16987
|
}
|
17294
16988
|
return narrowedType;
|
17295
16989
|
}
|
17296
|
-
function validateOverrideMethod(baseMethod, overrideMethod, diag, enforceParamNames = true) {
|
16990
|
+
function validateOverrideMethod(baseMethod, overrideMethod, baseClass, diag, enforceParamNames = true) {
|
17297
16991
|
// If we're overriding a non-method with a method, report it as an error.
|
17298
16992
|
// This occurs when a non-property overrides a property.
|
17299
16993
|
if (!(0, types_1.isFunction)(baseMethod) && !(0, types_1.isOverloadedFunction)(baseMethod)) {
|
@@ -17319,17 +17013,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17319
17013
|
// For a non-overloaded method overriding an overloaded method, the
|
17320
17014
|
// override must match all of the overloads.
|
17321
17015
|
if ((0, types_1.isFunction)(overrideMethod)) {
|
17322
|
-
return types_1.OverloadedFunctionType.getOverloads(baseMethod).every((overload) =>
|
17016
|
+
return types_1.OverloadedFunctionType.getOverloads(baseMethod).every((overload) => {
|
17017
|
+
// If the override isn't applicable for this base class, skip the check.
|
17018
|
+
if (baseClass && !isOverrideMethodApplicable(overload, baseClass)) {
|
17019
|
+
return true;
|
17020
|
+
}
|
17021
|
+
return validateOverrideMethodInternal(overload, overrideMethod, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), enforceParamNames);
|
17022
|
+
});
|
17323
17023
|
}
|
17324
17024
|
// For an overloaded method overriding an overloaded method, the overrides
|
17325
17025
|
// must all match and be in the correct order. It is OK if the base method
|
17326
17026
|
// has additional overloads that are not present in the override.
|
17327
17027
|
let previousMatchIndex = -1;
|
17328
17028
|
let overrideOverloadIndex = 0;
|
17029
|
+
const baseOverloads = types_1.OverloadedFunctionType.getOverloads(baseMethod);
|
17329
17030
|
for (const overrideOverload of types_1.OverloadedFunctionType.getOverloads(overrideMethod)) {
|
17330
|
-
const matchIndex =
|
17031
|
+
const matchIndex = baseOverloads.findIndex((baseOverload) => {
|
17032
|
+
// If the override isn't applicable for this base class, skip the check.
|
17033
|
+
if (baseClass && !isOverrideMethodApplicable(baseOverload, baseClass)) {
|
17034
|
+
return false;
|
17035
|
+
}
|
17331
17036
|
return validateOverrideMethodInternal(baseOverload, overrideOverload,
|
17332
|
-
/* diag */ undefined, enforceParamNames
|
17037
|
+
/* diag */ undefined, enforceParamNames,
|
17038
|
+
/* exemptSelfClsParam */ false);
|
17333
17039
|
});
|
17334
17040
|
if (matchIndex < 0) {
|
17335
17041
|
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch().format({ index: overrideOverloadIndex }));
|
@@ -17344,7 +17050,46 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17344
17050
|
}
|
17345
17051
|
return true;
|
17346
17052
|
}
|
17347
|
-
|
17053
|
+
// Determines whether a child class override is applicable to a parent
|
17054
|
+
// class method signature. This is important in cases where the parent
|
17055
|
+
// class defines an overload where some of the overload signatures supply
|
17056
|
+
// explicit type annotations for the "self" or "cls" parameter and some
|
17057
|
+
// of these do not apply to the child class.
|
17058
|
+
function isOverrideMethodApplicable(baseMethod, childClass) {
|
17059
|
+
if (!types_1.FunctionType.isInstanceMethod(baseMethod) &&
|
17060
|
+
!types_1.FunctionType.isClassMethod(baseMethod) &&
|
17061
|
+
!types_1.FunctionType.isConstructorMethod(baseMethod)) {
|
17062
|
+
return true;
|
17063
|
+
}
|
17064
|
+
const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
|
17065
|
+
if (baseParamDetails.params.length === 0) {
|
17066
|
+
return true;
|
17067
|
+
}
|
17068
|
+
const baseParamType = baseParamDetails.params[0].param;
|
17069
|
+
if (baseParamType.category !== 0 /* Simple */ || !baseParamType.hasDeclaredType) {
|
17070
|
+
return true;
|
17071
|
+
}
|
17072
|
+
// If this is a self or cls parameter, determine whether the override
|
17073
|
+
// class can be assigned to the base parameter type. If not, then this
|
17074
|
+
// override doesn't apply. This is important for overloads where the
|
17075
|
+
// base class contains some overload signatures that are not applicable
|
17076
|
+
// to the child class.
|
17077
|
+
const childSelfOrClsType = types_1.FunctionType.isInstanceMethod(baseMethod)
|
17078
|
+
? types_1.ClassType.cloneAsInstance(childClass)
|
17079
|
+
: childClass;
|
17080
|
+
return assignType(baseParamType.type, childSelfOrClsType,
|
17081
|
+
/* diag */ undefined,
|
17082
|
+
/* destTypeVarContext */ undefined,
|
17083
|
+
/* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */);
|
17084
|
+
}
|
17085
|
+
// Determines whether the override method is compatible with the overridden method.
|
17086
|
+
// This is used both for parent/child overrides and implicit overrides for peer
|
17087
|
+
// classes in a multi-inheritance case. If enforceParamNames is true, the parameter
|
17088
|
+
// names of non-positional-only parameters are enforced. If exemptSelfClsParam
|
17089
|
+
// is true, the "self" and "cls" parameters are exempted from type checks.
|
17090
|
+
// This is normally the case except with overloaded method overrides where the
|
17091
|
+
// "self" or "cls" parameter type must be honored to differentiate between overloads.
|
17092
|
+
function validateOverrideMethodInternal(baseMethod, overrideMethod, diag, enforceParamNames, exemptSelfClsParam = true) {
|
17348
17093
|
var _a, _b;
|
17349
17094
|
const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
|
17350
17095
|
const overrideParamDetails = (0, parameterUtils_1.getParameterListDetails)(overrideMethod);
|
@@ -17365,7 +17110,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17365
17110
|
canOverride = false;
|
17366
17111
|
}
|
17367
17112
|
}
|
17368
|
-
if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
|
17113
|
+
else if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
|
17369
17114
|
if (!types_1.FunctionType.isInstanceMethod(overrideMethod)) {
|
17370
17115
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
|
17371
17116
|
canOverride = false;
|
@@ -17417,7 +17162,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17417
17162
|
// If the first parameter is a "self" or "cls" parameter, skip the
|
17418
17163
|
// test because these are allowed to violate the Liskov substitution
|
17419
17164
|
// principle.
|
17420
|
-
if (i === 0) {
|
17165
|
+
if (i === 0 && exemptSelfClsParam) {
|
17421
17166
|
if (types_1.FunctionType.isInstanceMethod(overrideMethod) ||
|
17422
17167
|
types_1.FunctionType.isClassMethod(overrideMethod) ||
|
17423
17168
|
types_1.FunctionType.isConstructorMethod(overrideMethod)) {
|
@@ -17465,7 +17210,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17465
17210
|
const overrideParamType = overrideParamDetails.params[i].type;
|
17466
17211
|
const baseIsSynthesizedTypeVar = (0, types_1.isTypeVar)(baseParamType) && baseParamType.details.isSynthesized;
|
17467
17212
|
const overrideIsSynthesizedTypeVar = (0, types_1.isTypeVar)(overrideParamType) && overrideParamType.details.isSynthesized;
|
17468
|
-
if (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar) {
|
17213
|
+
if (!exemptSelfClsParam || (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar)) {
|
17469
17214
|
if (baseParam.category !== overrideParam.category ||
|
17470
17215
|
!assignType(overrideParamType, baseParamType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overrideMethod)), new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(baseMethod)), 8 /* SkipSolveTypeVars */)) {
|
17471
17216
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
|
@@ -17510,11 +17255,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17510
17255
|
// Now check any keyword-only parameters.
|
17511
17256
|
const baseKwOnlyParams = baseParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
|
17512
17257
|
paramInfo.param.category === 0 /* Simple */);
|
17513
|
-
const
|
17258
|
+
const overrideKwOnlyParams = overrideParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
|
17514
17259
|
paramInfo.param.category === 0 /* Simple */);
|
17515
17260
|
baseKwOnlyParams.forEach((paramInfo) => {
|
17516
17261
|
var _a, _b, _c;
|
17517
|
-
const overrideParamInfo =
|
17262
|
+
const overrideParamInfo = overrideKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
|
17518
17263
|
if (!overrideParamInfo && overrideParamDetails.kwargsIndex === undefined) {
|
17519
17264
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
|
17520
17265
|
name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
|
@@ -17547,7 +17292,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17547
17292
|
});
|
17548
17293
|
// Verify that any keyword-only parameters added by the overload are compatible
|
17549
17294
|
// with the **kwargs in the base.
|
17550
|
-
|
17295
|
+
overrideKwOnlyParams.forEach((paramInfo) => {
|
17551
17296
|
var _a;
|
17552
17297
|
const baseParamInfo = baseKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
|
17553
17298
|
if (!baseParamInfo) {
|
@@ -17699,7 +17444,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17699
17444
|
let isAbstract;
|
17700
17445
|
const decl = (0, symbolUtils_1.getLastTypedDeclaredForSymbol)(symbol);
|
17701
17446
|
if (decl && decl.type === 5 /* Function */) {
|
17702
|
-
const functionFlags = getFunctionFlagsFromDecorators(decl.node, true);
|
17447
|
+
const functionFlags = (0, decorators_1.getFunctionFlagsFromDecorators)(evaluatorInterface, decl.node, true);
|
17703
17448
|
isAbstract = !!(functionFlags & 8 /* AbstractMethod */);
|
17704
17449
|
}
|
17705
17450
|
else {
|
@@ -17830,7 +17575,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17830
17575
|
}
|
17831
17576
|
}
|
17832
17577
|
else if (!assignType(memberTypeFirstParamType, firstParamType, diag, typeVarContext,
|
17833
|
-
/* srcTypeVarContext */ undefined,
|
17578
|
+
/* srcTypeVarContext */ undefined, 2048 /* AllowUnspecifiedTypeArguments */, recursionCount)) {
|
17834
17579
|
if (memberTypeFirstParam.name &&
|
17835
17580
|
!memberTypeFirstParam.isNameSynthesized &&
|
17836
17581
|
memberTypeFirstParam.hasDeclaredType) {
|
@@ -17932,6 +17677,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17932
17677
|
if (options === null || options === void 0 ? void 0 : options.printUnknownWithAny) {
|
17933
17678
|
flags |= 1 /* PrintUnknownWithAny */;
|
17934
17679
|
}
|
17680
|
+
if (options === null || options === void 0 ? void 0 : options.printTypeVarVariance) {
|
17681
|
+
flags |= 2048 /* PrintTypeVarVariance */;
|
17682
|
+
}
|
17935
17683
|
if (options === null || options === void 0 ? void 0 : options.omitTypeArgumentsIfUnknown) {
|
17936
17684
|
flags |= 2 /* OmitTypeArgumentsIfUnknown */;
|
17937
17685
|
}
|
@@ -18074,7 +17822,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18074
17822
|
getObjectType,
|
18075
17823
|
getBuiltInObject,
|
18076
17824
|
getTypingType,
|
18077
|
-
|
17825
|
+
assignTypeArguments,
|
18078
17826
|
reportMissingTypeArguments,
|
18079
17827
|
inferReturnTypeIfNecessary,
|
18080
17828
|
inferTypeParameterVarianceForClass,
|