@zzzen/pyright-internal 1.2.0-dev.20230604 → 1.2.0-dev.20230618
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 +53 -32
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +17 -11
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructors.js +3 -2
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.js +1 -1
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +2 -0
- package/dist/analyzer/importResolver.js +57 -35
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/operations.js +2 -0
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/program.d.ts +2 -2
- package/dist/analyzer/program.js +12 -33
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +1 -1
- package/dist/analyzer/protocols.js +225 -205
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.d.ts +2 -2
- package/dist/analyzer/service.js +15 -7
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +272 -137
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +5 -2
- package/dist/analyzer/typeEvaluatorTypes.js +2 -0
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +1 -1
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +20 -21
- package/dist/analyzer/typeUtils.js +162 -107
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/types.d.ts +2 -0
- package/dist/analyzer/types.js +7 -3
- package/dist/analyzer/types.js.map +1 -1
- package/dist/backgroundAnalysisBase.d.ts +1 -1
- package/dist/backgroundAnalysisBase.js +2 -2
- package/dist/backgroundAnalysisBase.js.map +1 -1
- package/dist/backgroundThreadBase.d.ts +12 -9
- package/dist/backgroundThreadBase.js +28 -20
- package/dist/backgroundThreadBase.js.map +1 -1
- package/dist/common/charCodes.d.ts +147 -0
- package/dist/common/charCodes.js +164 -0
- package/dist/common/charCodes.js.map +1 -0
- package/dist/common/extensibility.d.ts +6 -2
- package/dist/common/extensibility.js.map +1 -1
- package/dist/common/fileSystem.d.ts +1 -0
- package/dist/common/fileSystem.js.map +1 -1
- package/dist/common/pathUtils.js.map +1 -1
- package/dist/common/realFileSystem.js +3 -0
- package/dist/common/realFileSystem.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 +51 -3
- package/dist/languageServerBase.js +5 -5
- 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/definitionProvider.d.ts +2 -0
- package/dist/languageService/definitionProvider.js +82 -74
- package/dist/languageService/definitionProvider.js.map +1 -1
- package/dist/languageService/hoverProvider.d.ts +16 -8
- package/dist/languageService/hoverProvider.js +53 -53
- package/dist/languageService/hoverProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +7 -6
- package/dist/localization/localize.js +3 -3
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +3 -3
- package/dist/parser/characterStream.js.map +1 -1
- package/dist/parser/characters.js.map +1 -1
- package/dist/parser/parser.js +5 -2
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/stringTokenUtils.js.map +1 -1
- package/dist/parser/tokenizer.js +10 -1
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/pyright.js +1 -1
- package/dist/pyright.js.map +1 -1
- package/dist/pyrightFileSystem.d.ts +1 -0
- package/dist/pyrightFileSystem.js +3 -0
- package/dist/pyrightFileSystem.js.map +1 -1
- package/dist/readonlyAugmentedFileSystem.d.ts +1 -0
- package/dist/readonlyAugmentedFileSystem.js +3 -0
- package/dist/readonlyAugmentedFileSystem.js.map +1 -1
- package/dist/tests/checker.test.js +1 -1
- package/dist/tests/harness/fourslash/testLanguageService.d.ts +1 -0
- package/dist/tests/harness/fourslash/testLanguageService.js +3 -0
- package/dist/tests/harness/fourslash/testLanguageService.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.js +2 -2
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/harness/vfs/filesystem.d.ts +12 -1
- package/dist/tests/harness/vfs/filesystem.js +33 -6
- package/dist/tests/harness/vfs/filesystem.js.map +1 -1
- package/dist/tests/tokenizer.test.js +13 -2
- package/dist/tests/tokenizer.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +5 -1
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +17 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +10 -2
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +1 -1
- package/dist/tests/typeEvaluator5.test.js +1 -1
- package/dist/tests/workspaceEditUtils.test.js +2 -3
- package/dist/tests/workspaceEditUtils.test.js.map +1 -1
- package/dist/workspaceFactory.d.ts +2 -0
- package/dist/workspaceFactory.js +11 -2
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +1 -2
@@ -651,10 +651,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
651
651
|
!(0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) &&
|
652
652
|
!(0, types_1.isNever)(inferenceContext.expectedType)) {
|
653
653
|
expectedTypeCache.set(node.id, inferenceContext.expectedType);
|
654
|
+
// If this is a generic function and there is a signature tracker,
|
655
|
+
// make sure the signature is unique.
|
656
|
+
if (inferenceContext.signatureTracker && (0, types_1.isFunction)(typeResult.type)) {
|
657
|
+
typeResult.type = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(typeResult.type, inferenceContext.signatureTracker, node.start);
|
658
|
+
}
|
654
659
|
if (!typeResult.isIncomplete && !typeResult.expectedTypeDiagAddendum) {
|
655
660
|
const diag = new diagnostic_1.DiagnosticAddendum();
|
656
661
|
// Make sure the resulting type is assignable to the expected type.
|
657
|
-
if (!assignType(inferenceContext.expectedType, typeResult.type, diag
|
662
|
+
if (!assignType(inferenceContext.expectedType, typeResult.type, diag,
|
663
|
+
/* destTypeVarContext */ undefined,
|
664
|
+
/* srcTypeVarContext */ undefined, 512 /* IgnoreTypeVarScope */)) {
|
658
665
|
typeResult.typeErrors = true;
|
659
666
|
typeResult.expectedTypeDiagAddendum = diag;
|
660
667
|
diag.addTextRange(node);
|
@@ -979,6 +986,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
979
986
|
flags |= 2 /* DoNotSpecialize */;
|
980
987
|
}
|
981
988
|
const decoratorTypeResult = getTypeOfExpression(node.expression, flags);
|
989
|
+
// Special-case typing.type_check_only. It's used in many stdlib
|
990
|
+
// functions, and pyright treats it as a no-op, so don't waste
|
991
|
+
// time evaluating it.
|
992
|
+
if ((0, types_1.isFunction)(decoratorTypeResult.type) &&
|
993
|
+
decoratorTypeResult.type.details.builtInName === 'type_check_only') {
|
994
|
+
return functionOrClassType;
|
995
|
+
}
|
982
996
|
// Special-case the combination of a classmethod decorator applied
|
983
997
|
// to a property. This is allowed in Python 3.9, but it's not reflected
|
984
998
|
// in the builtins.pyi stub for classmethod.
|
@@ -3092,11 +3106,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3092
3106
|
}
|
3093
3107
|
// Is this a generic class that needs to be specialized?
|
3094
3108
|
if ((0, types_1.isInstantiableClass)(type)) {
|
3095
|
-
if ((flags & 128 /* ExpectingType */) !== 0) {
|
3096
|
-
if ((0, typeUtils_1.requiresTypeArguments)(type)
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3109
|
+
if ((flags & 128 /* ExpectingType */) !== 0 && (flags & 512 /* AllowMissingTypeArgs */) === 0) {
|
3110
|
+
if (!type.typeAliasInfo && (0, typeUtils_1.requiresTypeArguments)(type)) {
|
3111
|
+
if (!type.typeArguments || !type.isTypeArgumentExplicit) {
|
3112
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportMissingTypeArgument, diagnosticRules_1.DiagnosticRule.reportMissingTypeArgument, localize_1.Localizer.Diagnostic.typeArgsMissingForClass().format({
|
3113
|
+
name: type.aliasName || type.details.name,
|
3114
|
+
}), node);
|
3115
|
+
}
|
3100
3116
|
}
|
3101
3117
|
}
|
3102
3118
|
if (!type.typeArguments) {
|
@@ -5130,7 +5146,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5130
5146
|
}
|
5131
5147
|
let expectedTypeDiagAddendum;
|
5132
5148
|
if (effectiveExpectedType) {
|
5133
|
-
const result = getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType
|
5149
|
+
const result = getTypeOfTupleWithContext(node, (0, typeUtils_1.makeInferenceContext)(effectiveExpectedType,
|
5150
|
+
/* isTypeIncomplete */ false, inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.signatureTracker));
|
5134
5151
|
if (result && !result.typeErrors) {
|
5135
5152
|
return result;
|
5136
5153
|
}
|
@@ -5183,7 +5200,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5183
5200
|
}
|
5184
5201
|
}
|
5185
5202
|
const entryTypeResults = node.expressions.map((expr, index) => getTypeOfExpression(expr,
|
5186
|
-
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(index < expectedTypes.length ? expectedTypes[index] : undefined)));
|
5203
|
+
/* flags */ undefined, (0, typeUtils_1.makeInferenceContext)(index < expectedTypes.length ? expectedTypes[index] : undefined, inferenceContext.isTypeIncomplete, inferenceContext.signatureTracker)));
|
5187
5204
|
const isIncomplete = entryTypeResults.some((result) => result.isIncomplete);
|
5188
5205
|
const type = (0, typeUtils_1.convertToInstance)((0, typeUtils_1.specializeTupleClass)(tupleClassType, buildTupleTypesList(entryTypeResults),
|
5189
5206
|
/* isTypeArgumentExplicit */ true));
|
@@ -5275,6 +5292,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5275
5292
|
return functionArg;
|
5276
5293
|
});
|
5277
5294
|
let typeResult = { type: types_1.UnknownType.create() };
|
5295
|
+
// If the inference context has an associated signature tracker, make sure
|
5296
|
+
// the base type of this call is not the same as one of the tracked signatures.
|
5297
|
+
// This is important for nested generic calls (e.g. "foo(foo(x))").
|
5298
|
+
if (inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.signatureTracker) {
|
5299
|
+
baseTypeResult.type = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(baseTypeResult.type, inferenceContext.signatureTracker, node.leftExpression.start);
|
5300
|
+
}
|
5278
5301
|
if (!(0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
|
5279
5302
|
if (node.leftExpression.nodeType === 38 /* Name */ && node.leftExpression.value === 'super') {
|
5280
5303
|
// Handle the built-in "super" call specially.
|
@@ -5537,9 +5560,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5537
5560
|
return types_1.NoneType.createInstance();
|
5538
5561
|
}
|
5539
5562
|
function getTypeOfSuperCall(node) {
|
5563
|
+
var _a;
|
5540
5564
|
if (node.arguments.length > 2) {
|
5541
5565
|
addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
|
5542
5566
|
}
|
5567
|
+
const enclosingClass = ParseTreeUtils.getEnclosingClass(node);
|
5568
|
+
const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
|
5543
5569
|
// Determine which class the "super" call is applied to. If
|
5544
5570
|
// there is no first argument, then the class is implicit.
|
5545
5571
|
let targetClassType;
|
@@ -5551,10 +5577,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5551
5577
|
}
|
5552
5578
|
}
|
5553
5579
|
else {
|
5554
|
-
|
5555
|
-
|
5556
|
-
const classTypeInfo = getTypeOfClass(enclosingClass);
|
5557
|
-
targetClassType = classTypeInfo ? classTypeInfo.classType : types_1.UnknownType.create();
|
5580
|
+
if (enclosingClassType) {
|
5581
|
+
targetClassType = enclosingClassType !== null && enclosingClassType !== void 0 ? enclosingClassType : types_1.UnknownType.create();
|
5558
5582
|
}
|
5559
5583
|
else {
|
5560
5584
|
addError(localize_1.Localizer.Diagnostic.superCallZeroArgForm(), node.leftExpression);
|
@@ -5594,33 +5618,28 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5594
5618
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.superCallSecondArg().format({ type: printType(targetClassType) }), node.arguments[1].valueExpression);
|
5595
5619
|
}
|
5596
5620
|
}
|
5597
|
-
else {
|
5621
|
+
else if (enclosingClassType) {
|
5622
|
+
bindToType = types_1.ClassType.cloneAsInstance(enclosingClassType);
|
5623
|
+
// Get the type from the self or cls parameter if it is explicitly annotated.
|
5624
|
+
// If it's a TypeVar, change the bindToType into a conditional type.
|
5598
5625
|
const enclosingMethod = ParseTreeUtils.getEnclosingFunction(node);
|
5599
5626
|
let implicitBindToType;
|
5600
|
-
// Get the type from the self or cls parameter if it is explicitly annotated.
|
5601
5627
|
if (enclosingMethod) {
|
5602
5628
|
const methodTypeInfo = getTypeOfFunction(enclosingMethod);
|
5603
5629
|
if (methodTypeInfo) {
|
5604
5630
|
const methodType = methodTypeInfo.functionType;
|
5605
|
-
if (types_1.FunctionType.isClassMethod(methodType)
|
5631
|
+
if (types_1.FunctionType.isClassMethod(methodType) ||
|
5632
|
+
types_1.FunctionType.isConstructorMethod(methodType) ||
|
5633
|
+
types_1.FunctionType.isInstanceMethod(methodType)) {
|
5606
5634
|
if (methodType.details.parameters.length > 0 &&
|
5607
5635
|
methodType.details.parameters[0].hasDeclaredType) {
|
5608
5636
|
implicitBindToType = makeTopLevelTypeVarsConcrete(methodType.details.parameters[0].type);
|
5609
5637
|
}
|
5610
5638
|
}
|
5611
|
-
else if (types_1.FunctionType.isInstanceMethod(methodType)) {
|
5612
|
-
if (methodType.details.parameters.length > 0 &&
|
5613
|
-
methodType.details.parameters[0].hasDeclaredType) {
|
5614
|
-
implicitBindToType = makeTopLevelTypeVarsConcrete((0, typeUtils_1.convertToInstantiable)(methodType.details.parameters[0].type));
|
5615
|
-
}
|
5616
|
-
}
|
5617
5639
|
}
|
5618
5640
|
}
|
5619
|
-
if (
|
5620
|
-
bindToType = implicitBindToType;
|
5621
|
-
}
|
5622
|
-
else if ((0, types_1.isInstantiableClass)(targetClassType)) {
|
5623
|
-
bindToType = targetClassType;
|
5641
|
+
if (bindToType && implicitBindToType) {
|
5642
|
+
bindToType = (0, typeUtils_1.addConditionToType)(bindToType, (0, typeUtils_1.getTypeCondition)(implicitBindToType));
|
5624
5643
|
}
|
5625
5644
|
}
|
5626
5645
|
// Determine whether super() should return an instance of the class or
|
@@ -5645,7 +5664,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5645
5664
|
const parentNode = node.parent;
|
5646
5665
|
if (parentNode.nodeType === 35 /* MemberAccess */) {
|
5647
5666
|
const memberName = parentNode.memberName.value;
|
5648
|
-
const
|
5667
|
+
const effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
|
5668
|
+
const lookupResults = bindToType
|
5669
|
+
? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
|
5670
|
+
: undefined;
|
5649
5671
|
if (lookupResults && (0, types_1.isInstantiableClass)(lookupResults.classType)) {
|
5650
5672
|
return {
|
5651
5673
|
type: resultIsInstance
|
@@ -5685,7 +5707,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5685
5707
|
// (one for each argument) will be undefined. On subsequent calls, this
|
5686
5708
|
// list will grow to include union expansions.
|
5687
5709
|
function validateOverloadsWithExpandedTypes(errorNode, expandedArgTypes, argParamMatches, typeVarContext, skipUnknownArgCheck, inferenceContext) {
|
5688
|
-
var _a, _b
|
5710
|
+
var _a, _b;
|
5689
5711
|
const returnTypes = [];
|
5690
5712
|
const matchedOverloads = [];
|
5691
5713
|
let isTypeIncomplete = false;
|
@@ -5812,12 +5834,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5812
5834
|
effectiveReturnType = types_1.AnyType.create();
|
5813
5835
|
}
|
5814
5836
|
else {
|
5815
|
-
|
5816
|
-
// replace the type arguments with Unknown. Otherwise return
|
5817
|
-
// an Unknown type that has associated "possible types" to aid
|
5818
|
-
// with completion suggestions.
|
5819
|
-
effectiveReturnType =
|
5820
|
-
(_c = (0, typeUtils_1.getCommonErasedType)(dedupedMatchResults)) !== null && _c !== void 0 ? _c : types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
5837
|
+
effectiveReturnType = types_1.UnknownType.createPossibleType(combinedTypes, possibleMatchInvolvesIncompleteUnknown);
|
5821
5838
|
}
|
5822
5839
|
}
|
5823
5840
|
returnTypes.push(effectiveReturnType);
|
@@ -5875,24 +5892,33 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5875
5892
|
if (!firstArgResults) {
|
5876
5893
|
return matches;
|
5877
5894
|
}
|
5895
|
+
let foundAmbiguousAnyArg = false;
|
5878
5896
|
for (let i = 0; i < firstArgResults.length; i++) {
|
5879
|
-
// If the arg
|
5897
|
+
// If the arg is Any or Unknown, see if the corresponding
|
5880
5898
|
// parameter types differ in any way.
|
5881
|
-
|
5882
|
-
if (anyOrUnknownInArg) {
|
5899
|
+
if ((0, types_1.isAnyOrUnknown)(firstArgResults[i].argType)) {
|
5883
5900
|
const paramTypes = matches.map((match) => i < match.matchResults.argParams.length
|
5884
5901
|
? match.matchResults.argParams[i].paramType
|
5885
5902
|
: types_1.UnknownType.create());
|
5886
5903
|
if (!(0, typeUtils_1.areTypesSame)(paramTypes, { treatAnySameAsUnknown: true })) {
|
5887
|
-
|
5904
|
+
foundAmbiguousAnyArg = true;
|
5888
5905
|
}
|
5889
5906
|
}
|
5890
5907
|
}
|
5908
|
+
// If the first overload has a different number of effective arguments
|
5909
|
+
// than latter overloads, don't filter any of them. This typically means
|
5910
|
+
// that one of the arguments is an unpacked iterator, and it maps to
|
5911
|
+
// an indeterminate number of parameters, which means that the overload
|
5912
|
+
// selection is ambiguous.
|
5913
|
+
if (foundAmbiguousAnyArg || matches.some((match) => match.argResults.length !== firstArgResults.length)) {
|
5914
|
+
return matches;
|
5915
|
+
}
|
5891
5916
|
return [matches[0]];
|
5892
5917
|
}
|
5893
5918
|
function getBestOverloadForArguments(errorNode, typeResult, argList) {
|
5894
5919
|
let overloadIndex = 0;
|
5895
5920
|
let matches = [];
|
5921
|
+
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
5896
5922
|
// Create a list of potential overload matches based on arguments.
|
5897
5923
|
types_1.OverloadedFunctionType.getOverloads(typeResult.type).forEach((overload) => {
|
5898
5924
|
useSpeculativeMode(errorNode, () => {
|
@@ -5908,7 +5934,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5908
5934
|
matches.forEach((match, matchIndex) => {
|
5909
5935
|
if (winningOverloadIndex === undefined) {
|
5910
5936
|
useSpeculativeMode(errorNode, () => {
|
5911
|
-
const callResult = validateFunctionArgumentTypes(errorNode, match, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(match.overload)),
|
5937
|
+
const callResult = validateFunctionArgumentTypes(errorNode, match, new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(match.overload)), signatureTracker,
|
5912
5938
|
/* skipUnknownArgCheck */ true);
|
5913
5939
|
if (callResult && !callResult.argumentErrors) {
|
5914
5940
|
winningOverloadIndex = matchIndex;
|
@@ -5963,9 +5989,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5963
5989
|
}
|
5964
5990
|
return { argumentErrors: true, isTypeIncomplete: false, overloadsUsedForCall: [] };
|
5965
5991
|
}
|
5966
|
-
// Create a helper
|
5992
|
+
// Create a helper function that evaluates the overload that matches
|
5967
5993
|
// the arg/param lists.
|
5968
|
-
|
5994
|
+
function evaluateUsingLastMatchingOverload(skipUnknownArgCheck) {
|
5969
5995
|
// Find the match with the largest overload index (i.e. the last overload
|
5970
5996
|
// that was in the overload list).
|
5971
5997
|
const lastMatch = filteredMatchResults.reduce((previous, current) => {
|
@@ -5975,7 +6001,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5975
6001
|
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(lastMatch.overload));
|
5976
6002
|
effectiveTypeVarContext.unlock();
|
5977
6003
|
return validateFunctionArgumentTypesWithContext(errorNode, lastMatch, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
5978
|
-
}
|
6004
|
+
}
|
5979
6005
|
// If there is only one possible arg/param match among the overloads,
|
5980
6006
|
// use the normal type matching mechanism because it is faster and
|
5981
6007
|
// will provide a clearer error message.
|
@@ -6467,7 +6493,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6467
6493
|
const combinedArgType = (0, typeUtils_1.combineSameSizedTuples)(makeTopLevelTypeVarsConcrete(argType), tupleClassType);
|
6468
6494
|
if ((0, types_1.isClassInstance)(combinedArgType) && (0, typeUtils_1.isTupleClass)(combinedArgType)) {
|
6469
6495
|
const tupleTypeArgs = (_a = combinedArgType.tupleTypeArguments) !== null && _a !== void 0 ? _a : [];
|
6470
|
-
if (tupleTypeArgs.length !== 1) {
|
6496
|
+
if (tupleTypeArgs.length !== 1 || !tupleTypeArgs[0].isUnbounded) {
|
6471
6497
|
for (const tupleTypeArg of tupleTypeArgs) {
|
6472
6498
|
if (tupleTypeArg.isUnbounded) {
|
6473
6499
|
expandedArgList.push({
|
@@ -6993,6 +7019,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6993
7019
|
unpackedDictionaryArgType = types_1.UnknownType.create();
|
6994
7020
|
}
|
6995
7021
|
}
|
7022
|
+
if (paramDetails.kwargsIndex !== undefined && unpackedDictionaryArgType) {
|
7023
|
+
const paramType = paramDetails.params[paramDetails.kwargsIndex].type;
|
7024
|
+
validateArgTypeParams.push({
|
7025
|
+
paramCategory: 0 /* Simple */,
|
7026
|
+
paramType,
|
7027
|
+
requiresTypeVarMatching: (0, typeUtils_1.requiresSpecialization)(paramType),
|
7028
|
+
argType: unpackedDictionaryArgType,
|
7029
|
+
argument: argList[argIndex],
|
7030
|
+
errorNode: argList[argIndex].valueExpression || errorNode,
|
7031
|
+
paramName: paramDetails.params[paramDetails.kwargsIndex].param.name,
|
7032
|
+
});
|
7033
|
+
}
|
6996
7034
|
if (!isValidMappingType) {
|
6997
7035
|
if (!isDiagnosticSuppressedForNode(errorNode)) {
|
6998
7036
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet
|
@@ -7110,7 +7148,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7110
7148
|
if (paramIndex >= paramDetails.firstPositionOrKeywordIndex &&
|
7111
7149
|
param.category === 0 /* Simple */ &&
|
7112
7150
|
param.name &&
|
7113
|
-
!param.hasDefault &&
|
7114
7151
|
paramMap.has(param.name) &&
|
7115
7152
|
paramMap.get(param.name).argsReceived === 0) {
|
7116
7153
|
const paramType = paramDetails.params[paramIndex].type;
|
@@ -7266,7 +7303,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7266
7303
|
// Special-case the builtin isinstance and issubclass functions.
|
7267
7304
|
if (['isinstance', 'issubclass'].some((name) => name === typeResult.type.details.builtInName) &&
|
7268
7305
|
validateArgTypeParams.length === 2) {
|
7269
|
-
validateArgTypeParams[1].
|
7306
|
+
validateArgTypeParams[1].isinstanceParam = true;
|
7270
7307
|
}
|
7271
7308
|
return {
|
7272
7309
|
overload: typeResult.type,
|
@@ -7284,16 +7321,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7284
7321
|
// types of each argument expression and validates that the resulting type is
|
7285
7322
|
// compatible with the declared type of the corresponding parameter.
|
7286
7323
|
function validateFunctionArgumentTypesWithContext(errorNode, matchResults, typeVarContext, skipUnknownArgCheck = false, inferenceContext) {
|
7287
|
-
var _a;
|
7324
|
+
var _a, _b;
|
7288
7325
|
const type = matchResults.overload;
|
7326
|
+
const signatureTracker = (_a = inferenceContext === null || inferenceContext === void 0 ? void 0 : inferenceContext.signatureTracker) !== null && _a !== void 0 ? _a : new typeUtils_1.UniqueSignatureTracker();
|
7327
|
+
matchResults.overload = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(matchResults.overload, signatureTracker, errorNode.start);
|
7289
7328
|
// Can we safely ignore the inference context (either because it's not provided
|
7290
7329
|
// or will have no effect)? If so, we can eliminate a bunch of extra work.
|
7291
7330
|
if (!inferenceContext ||
|
7292
7331
|
(0, types_1.isAnyOrUnknown)(inferenceContext.expectedType) ||
|
7293
7332
|
(0, types_1.isNever)(inferenceContext.expectedType) ||
|
7294
7333
|
!type.details.declaredReturnType ||
|
7295
|
-
!(0, typeUtils_1.requiresSpecialization)((
|
7296
|
-
return validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, skipUnknownArgCheck);
|
7334
|
+
!(0, typeUtils_1.requiresSpecialization)((_b = types_1.FunctionType.getSpecializedReturnType(type)) !== null && _b !== void 0 ? _b : types_1.UnknownType.create())) {
|
7335
|
+
return validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, signatureTracker, skipUnknownArgCheck);
|
7297
7336
|
}
|
7298
7337
|
const effectiveReturnType = getFunctionEffectiveReturnType(type);
|
7299
7338
|
let effectiveExpectedType = inferenceContext.expectedType;
|
@@ -7310,7 +7349,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7310
7349
|
assignType(effectiveReturnType, effectiveExpectedType,
|
7311
7350
|
/* diag */ undefined, typeVarContextCopy,
|
7312
7351
|
/* srcTypeVarContext */ undefined, effectiveFlags | 1024 /* PopulatingExpectedType */);
|
7313
|
-
const speculativeResults = validateFunctionArgumentTypes(errorNode, matchResults, typeVarContextCopy, skipUnknownArgCheck);
|
7352
|
+
const speculativeResults = validateFunctionArgumentTypes(errorNode, matchResults, typeVarContextCopy, signatureTracker, skipUnknownArgCheck);
|
7314
7353
|
if (speculativeResults === null || speculativeResults === void 0 ? void 0 : speculativeResults.argumentErrors) {
|
7315
7354
|
effectiveExpectedType = undefined;
|
7316
7355
|
}
|
@@ -7323,13 +7362,23 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7323
7362
|
// the expected type if possible.
|
7324
7363
|
// Determine which type arguments are needed to match the expected type.
|
7325
7364
|
if ((0, types_1.isClassInstance)(effectiveReturnType)) {
|
7326
|
-
// If the return type is a class and the expected type is a union
|
7327
|
-
// that
|
7365
|
+
// If the return type is a class and the expected type is a union
|
7366
|
+
// that is type compatible with that class, filter the subtypes in
|
7367
|
+
// the union to see if we can find one that is potentially compatible.
|
7328
7368
|
if ((0, types_1.isUnion)(effectiveExpectedType)) {
|
7329
7369
|
const filteredType = (0, typeUtils_1.mapSubtypes)(effectiveExpectedType, (subtype) => {
|
7330
|
-
|
7331
|
-
|
7332
|
-
|
7370
|
+
if (!(0, types_1.isClassInstance)(subtype) || subtype.details.typeParameters.length === 0) {
|
7371
|
+
return undefined;
|
7372
|
+
}
|
7373
|
+
if (types_1.ClassType.isProtocolClass(subtype) ||
|
7374
|
+
subtype.details.mro.some((mroClass) => {
|
7375
|
+
return ((0, types_1.isClassInstance)(mroClass) &&
|
7376
|
+
mroClass.details.typeParameters.length > 0 &&
|
7377
|
+
types_1.ClassType.isSameGenericClass(effectiveReturnType, mroClass));
|
7378
|
+
})) {
|
7379
|
+
return subtype;
|
7380
|
+
}
|
7381
|
+
return undefined;
|
7333
7382
|
});
|
7334
7383
|
if ((0, types_1.isClassInstance)(filteredType)) {
|
7335
7384
|
effectiveExpectedType = filteredType;
|
@@ -7358,14 +7407,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7358
7407
|
/* diag */ undefined, typeVarContext,
|
7359
7408
|
/* srcTypeVarContext */ undefined, effectiveFlags | 1024 /* PopulatingExpectedType */);
|
7360
7409
|
}
|
7361
|
-
return validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, skipUnknownArgCheck);
|
7410
|
+
return validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, signatureTracker, skipUnknownArgCheck);
|
7362
7411
|
}
|
7363
|
-
function validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, skipUnknownArgCheck = false) {
|
7412
|
+
function validateFunctionArgumentTypes(errorNode, matchResults, typeVarContext, signatureTracker, skipUnknownArgCheck = false) {
|
7364
7413
|
const type = matchResults.overload;
|
7365
7414
|
let isTypeIncomplete = matchResults.isTypeIncomplete;
|
7366
7415
|
let argumentErrors = false;
|
7367
7416
|
let specializedInitSelfType;
|
7368
|
-
let
|
7417
|
+
let anyOrUnknownArgument;
|
7369
7418
|
const typeCondition = (0, typeUtils_1.getTypeCondition)(type);
|
7370
7419
|
if (type.boundTypeVarScopeId) {
|
7371
7420
|
// If the function was bound to a class or object and was a constructor, a
|
@@ -7422,8 +7471,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7422
7471
|
// where more than two passes are needed.
|
7423
7472
|
let passCount = Math.min(typeVarMatchingCount, 2);
|
7424
7473
|
for (let i = 0; i < passCount; i++) {
|
7425
|
-
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
7426
|
-
signatureTracker.addSignature(type);
|
7427
7474
|
useSpeculativeMode(errorNode, () => {
|
7428
7475
|
matchResults.argParams.forEach((argParam) => {
|
7429
7476
|
if (!argParam.requiresTypeVarMatching) {
|
@@ -7467,8 +7514,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7467
7514
|
let sawParamSpecKwargs = false;
|
7468
7515
|
let condition = [];
|
7469
7516
|
const argResults = [];
|
7470
|
-
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
7471
|
-
signatureTracker.addSignature(type);
|
7472
7517
|
matchResults.argParams.forEach((argParam) => {
|
7473
7518
|
var _a;
|
7474
7519
|
const argResult = validateArgType(argParam, typeVarContext, signatureTracker, { type, isIncomplete: matchResults.isTypeIncomplete }, {
|
@@ -7485,13 +7530,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7485
7530
|
if (argResult.condition) {
|
7486
7531
|
condition = (_a = types_1.TypeCondition.combine(condition, argResult.condition)) !== null && _a !== void 0 ? _a : [];
|
7487
7532
|
}
|
7488
|
-
|
7489
|
-
|
7490
|
-
|
7491
|
-
|
7492
|
-
accumulatedAnyOrUnknownArg = accumulatedAnyOrUnknownArg
|
7493
|
-
? (0, typeUtils_1.preserveUnknown)(anyOrUnknownInArg, accumulatedAnyOrUnknownArg)
|
7494
|
-
: anyOrUnknownInArg;
|
7533
|
+
if ((0, types_1.isAnyOrUnknown)(argResult.argType)) {
|
7534
|
+
anyOrUnknownArgument = anyOrUnknownArgument
|
7535
|
+
? (0, typeUtils_1.preserveUnknown)(argResult.argType, anyOrUnknownArgument)
|
7536
|
+
: argResult.argType;
|
7495
7537
|
}
|
7496
7538
|
if (type.details.paramSpec) {
|
7497
7539
|
if (argParam.argument.argumentCategory === 1 /* UnpackedList */) {
|
@@ -7602,7 +7644,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7602
7644
|
return {
|
7603
7645
|
argumentErrors,
|
7604
7646
|
argResults,
|
7605
|
-
anyOrUnknownArgument
|
7647
|
+
anyOrUnknownArgument,
|
7606
7648
|
returnType: specializedReturnType,
|
7607
7649
|
isTypeIncomplete,
|
7608
7650
|
activeParam: matchResults.activeParam,
|
@@ -7855,17 +7897,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7855
7897
|
argType = argParam.argType;
|
7856
7898
|
}
|
7857
7899
|
else {
|
7858
|
-
const flags = argParam.
|
7859
|
-
?
|
7900
|
+
const flags = argParam.isinstanceParam
|
7901
|
+
? 512 /* AllowMissingTypeArgs */ |
|
7902
|
+
8 /* EvaluateStringLiteralAsType */ |
|
7860
7903
|
32 /* DisallowParamSpec */ |
|
7861
7904
|
64 /* DisallowTypeVarTuple */
|
7862
7905
|
: 0 /* None */;
|
7863
|
-
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedType, !!(typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete)));
|
7906
|
+
const exprTypeResult = getTypeOfExpression(argParam.argument.valueExpression, flags, (0, typeUtils_1.makeInferenceContext)(expectedType, !!(typeResult === null || typeResult === void 0 ? void 0 : typeResult.isIncomplete), signatureTracker));
|
7864
7907
|
argType = exprTypeResult.type;
|
7865
7908
|
// If the type includes multiple instances of a generic function
|
7866
7909
|
// signature, force the type arguments for the duplicates to have
|
7867
7910
|
// unique names.
|
7868
|
-
argType = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(argType, signatureTracker);
|
7911
|
+
argType = (0, typeUtils_1.ensureFunctionSignaturesAreUnique)(argType, signatureTracker, argParam.argument.valueExpression.start);
|
7869
7912
|
if (exprTypeResult.isIncomplete) {
|
7870
7913
|
isTypeIncomplete = true;
|
7871
7914
|
}
|
@@ -7894,7 +7937,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7894
7937
|
if (argParam.argType) {
|
7895
7938
|
argType = argParam.argType;
|
7896
7939
|
}
|
7897
|
-
else if (argParam.
|
7940
|
+
else if (argParam.isinstanceParam && !argParam.argument.typeResult && argParam.argument.valueExpression) {
|
7898
7941
|
const argTypeResult = getTypeOfExpression(argParam.argument.valueExpression, 8 /* EvaluateStringLiteralAsType */ |
|
7899
7942
|
32 /* DisallowParamSpec */ |
|
7900
7943
|
64 /* DisallowTypeVarTuple */);
|
@@ -8720,6 +8763,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8720
8763
|
// Infer the key and value types if possible.
|
8721
8764
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8722
8765
|
/* forceStrictInference */ true,
|
8766
|
+
/* isValueTypeInvariant */ true,
|
8723
8767
|
/* expectedKeyType */ undefined,
|
8724
8768
|
/* expectedValueType */ undefined, expectedTypedDictEntries, expectedDiagAddendum)) {
|
8725
8769
|
isIncomplete = true;
|
@@ -8752,17 +8796,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8752
8796
|
}
|
8753
8797
|
const expectedKeyType = specializedDict.typeArguments[0];
|
8754
8798
|
const expectedValueType = specializedDict.typeArguments[1];
|
8755
|
-
// Infer the key and value types if possible.
|
8756
|
-
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8757
|
-
/* forceStrictInference */ true, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
8758
|
-
isIncomplete = true;
|
8759
|
-
}
|
8760
8799
|
// Dict and MutableMapping types have invariant value types, so they
|
8761
8800
|
// cannot be narrowed further. Other super-types like Mapping, Collection,
|
8762
8801
|
// and Iterable use covariant value types, so they can be narrowed.
|
8763
8802
|
const isValueTypeInvariant = (0, types_1.isClassInstance)(inferenceContext.expectedType) &&
|
8764
8803
|
(types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'dict') ||
|
8765
8804
|
types_1.ClassType.isBuiltIn(inferenceContext.expectedType, 'MutableMapping'));
|
8805
|
+
// Infer the key and value types if possible.
|
8806
|
+
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
8807
|
+
/* forceStrictInference */ true, isValueTypeInvariant, expectedKeyType, expectedValueType, undefined, expectedDiagAddendum)) {
|
8808
|
+
isIncomplete = true;
|
8809
|
+
}
|
8766
8810
|
const specializedKeyType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedKeyType), keyTypes.map((result) => result.type),
|
8767
8811
|
/* isNarrowable */ false);
|
8768
8812
|
const specializedValueType = inferTypeArgFromExpectedEntryType((0, typeUtils_1.makeInferenceContext)(expectedValueType), valueTypes.map((result) => result.type), !isValueTypeInvariant);
|
@@ -8784,7 +8828,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8784
8828
|
let isIncomplete = false;
|
8785
8829
|
// Infer the key and value types if possible.
|
8786
8830
|
if (getKeyAndValueTypesFromDictionary(node, keyTypeResults, valueTypeResults,
|
8787
|
-
/* forceStrictInference */ hasExpectedType
|
8831
|
+
/* forceStrictInference */ hasExpectedType,
|
8832
|
+
/* isValueTypeInvariant */ false)) {
|
8788
8833
|
isIncomplete = true;
|
8789
8834
|
}
|
8790
8835
|
// Strip any literal values.
|
@@ -8822,11 +8867,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8822
8867
|
}
|
8823
8868
|
return { type, isIncomplete };
|
8824
8869
|
}
|
8825
|
-
function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
|
8870
|
+
function getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes, forceStrictInference, isValueTypeInvariant, expectedKeyType, expectedValueType, expectedTypedDictEntries, expectedDiagAddendum) {
|
8826
8871
|
let isIncomplete = false;
|
8827
8872
|
// Infer the key and value types if possible.
|
8828
8873
|
node.entries.forEach((entryNode, index) => {
|
8829
|
-
var _a;
|
8874
|
+
var _a, _b, _c;
|
8830
8875
|
let addUnknown = true;
|
8831
8876
|
if (entryNode.nodeType === 17 /* DictionaryKeyEntry */) {
|
8832
8877
|
const keyTypeResult = getTypeOfExpression(entryNode.keyExpression,
|
@@ -8842,19 +8887,26 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8842
8887
|
expectedDiagAddendum.addAddendum(keyTypeResult.expectedTypeDiagAddendum);
|
8843
8888
|
}
|
8844
8889
|
let valueTypeResult;
|
8890
|
+
let entryInferenceContext;
|
8845
8891
|
if (expectedTypedDictEntries &&
|
8846
8892
|
(0, types_1.isClassInstance)(keyType) &&
|
8847
8893
|
types_1.ClassType.isBuiltIn(keyType, 'str') &&
|
8848
8894
|
(0, typeUtils_1.isLiteralType)(keyType) &&
|
8849
8895
|
expectedTypedDictEntries.has(keyType.literalValue)) {
|
8850
8896
|
const effectiveValueType = expectedTypedDictEntries.get(keyType.literalValue).valueType;
|
8897
|
+
entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
|
8851
8898
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
8852
|
-
/* flags */ undefined,
|
8899
|
+
/* flags */ undefined, entryInferenceContext);
|
8853
8900
|
}
|
8854
8901
|
else {
|
8855
8902
|
const effectiveValueType = expectedValueType !== null && expectedValueType !== void 0 ? expectedValueType : (forceStrictInference ? types_1.NeverType.createNever() : undefined);
|
8903
|
+
entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(effectiveValueType);
|
8856
8904
|
valueTypeResult = getTypeOfExpression(entryNode.valueExpression,
|
8857
|
-
/* flags */ undefined,
|
8905
|
+
/* flags */ undefined, entryInferenceContext);
|
8906
|
+
}
|
8907
|
+
if (entryInferenceContext && !valueTypeResult.typeErrors) {
|
8908
|
+
valueTypeResult.type =
|
8909
|
+
(_a = inferTypeArgFromExpectedEntryType(entryInferenceContext, [valueTypeResult.type], !isValueTypeInvariant)) !== null && _a !== void 0 ? _a : valueTypeResult.type;
|
8858
8910
|
}
|
8859
8911
|
if (expectedDiagAddendum && valueTypeResult.expectedTypeDiagAddendum) {
|
8860
8912
|
expectedDiagAddendum.addAddendum(valueTypeResult.expectedTypeDiagAddendum);
|
@@ -8877,8 +8929,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8877
8929
|
/* isTypeArgumentExplicit */ true));
|
8878
8930
|
}
|
8879
8931
|
}
|
8932
|
+
const entryInferenceContext = (0, typeUtils_1.makeInferenceContext)(expectedType);
|
8880
8933
|
const unexpandedTypeResult = getTypeOfExpression(entryNode.expandExpression,
|
8881
|
-
/* flags */ undefined,
|
8934
|
+
/* flags */ undefined, entryInferenceContext);
|
8935
|
+
if (entryInferenceContext && !unexpandedTypeResult.typeErrors) {
|
8936
|
+
unexpandedTypeResult.type =
|
8937
|
+
(_b = inferTypeArgFromExpectedEntryType(entryInferenceContext, [unexpandedTypeResult.type], !isValueTypeInvariant)) !== null && _b !== void 0 ? _b : unexpandedTypeResult.type;
|
8938
|
+
}
|
8882
8939
|
if (unexpandedTypeResult.isIncomplete) {
|
8883
8940
|
isIncomplete = true;
|
8884
8941
|
}
|
@@ -8933,7 +8990,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8933
8990
|
}
|
8934
8991
|
// The result should be a tuple.
|
8935
8992
|
if ((0, types_1.isClassInstance)(dictEntryType) && (0, typeUtils_1.isTupleClass)(dictEntryType)) {
|
8936
|
-
const typeArgs = (
|
8993
|
+
const typeArgs = (_c = dictEntryType.tupleTypeArguments) === null || _c === void 0 ? void 0 : _c.map((t) => t.type);
|
8937
8994
|
if (typeArgs && typeArgs.length === 2) {
|
8938
8995
|
if (forceStrictInference || index < maxEntriesToUseForInference) {
|
8939
8996
|
keyTypes.push({ node: entryNode, type: typeArgs[0] });
|
@@ -9128,7 +9185,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9128
9185
|
if ((0, types_1.isAnyOrUnknown)(inferenceContext.expectedType)) {
|
9129
9186
|
return inferenceContext.expectedType;
|
9130
9187
|
}
|
9131
|
-
const typeVarContext = new typeVarContext_1.TypeVarContext();
|
9188
|
+
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(inferenceContext.expectedType));
|
9132
9189
|
const expectedType = inferenceContext.expectedType;
|
9133
9190
|
let isCompatible = true;
|
9134
9191
|
entryTypes.forEach((entryType) => {
|
@@ -9145,7 +9202,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9145
9202
|
? combinedTypes
|
9146
9203
|
: stripLiteralValue(combinedTypes);
|
9147
9204
|
}
|
9148
|
-
return (0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true })
|
9205
|
+
return (0, typeUtils_1.mapSubtypes)((0, typeUtils_1.applySolvedTypeVars)(inferenceContext.expectedType, typeVarContext, { applyInScopePlaceholders: true }), (subtype) => {
|
9206
|
+
if (entryTypes.length !== 1) {
|
9207
|
+
return subtype;
|
9208
|
+
}
|
9209
|
+
const entryType = entryTypes[0];
|
9210
|
+
// If the entry type is a TypedDict instance, clone it with additional information.
|
9211
|
+
if ((0, types_1.isTypeSame)(subtype, entryType, { ignoreTypedDictNarrowEntries: true }) &&
|
9212
|
+
(0, types_1.isClass)(subtype) &&
|
9213
|
+
(0, types_1.isClass)(entryType) &&
|
9214
|
+
types_1.ClassType.isTypedDictClass(entryType)) {
|
9215
|
+
return types_1.ClassType.cloneForNarrowedTypedDictEntries(subtype, entryType.typedDictNarrowedEntries);
|
9216
|
+
}
|
9217
|
+
return subtype;
|
9218
|
+
});
|
9149
9219
|
}
|
9150
9220
|
function getTypeOfYield(node) {
|
9151
9221
|
let expectedYieldType;
|
@@ -10718,7 +10788,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10718
10788
|
let protocolTypeParameters;
|
10719
10789
|
const initSubclassArgs = [];
|
10720
10790
|
let metaclassNode;
|
10721
|
-
let isMetaclassDeferred = false;
|
10722
10791
|
let exprFlags = 128 /* ExpectingType */ |
|
10723
10792
|
1024 /* AllowGenericClassType */ |
|
10724
10793
|
262144 /* DisallowNakedGeneric */ |
|
@@ -10773,7 +10842,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10773
10842
|
dependency: argType,
|
10774
10843
|
callback: () => completeClassTypeDeferred(classType, node, node.name),
|
10775
10844
|
});
|
10776
|
-
isMetaclassDeferred = true;
|
10777
10845
|
}
|
10778
10846
|
if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
|
10779
10847
|
if (!fileInfo.isStubFile &&
|
@@ -11144,11 +11212,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11144
11212
|
writeTypeCache(node.name, { type: classType }, 0 /* None */);
|
11145
11213
|
// Update the decorated class type.
|
11146
11214
|
writeTypeCache(node, { type: decoratedType }, 0 /* None */);
|
11147
|
-
// Validate that arguments passed to `__init_subclass__` are of the correct type.
|
11148
|
-
// Defer this if the metaclass calculation is deferred.
|
11149
|
-
if (!isMetaclassDeferred) {
|
11150
|
-
validateInitSubclassArgs(node, classType);
|
11151
|
-
}
|
11152
11215
|
return { classType, decoratedType };
|
11153
11216
|
}
|
11154
11217
|
// Determines whether the type parameters has a default that refers to another
|
@@ -11438,7 +11501,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11438
11501
|
}
|
11439
11502
|
// Recompute the effective metaclass.
|
11440
11503
|
computeEffectiveMetaclass(type, errorNode);
|
11441
|
-
validateInitSubclassArgs(node, type);
|
11442
11504
|
}
|
11443
11505
|
function validateInitSubclassArgs(node, classType) {
|
11444
11506
|
// Collect arguments that will be passed to the `__init_subclass__`
|
@@ -12018,10 +12080,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12018
12080
|
inferredParamType = (0, types_1.combineTypes)([defaultValueType, types_1.UnknownType.create()]);
|
12019
12081
|
}
|
12020
12082
|
else {
|
12021
|
-
|
12022
|
-
|
12023
|
-
|
12024
|
-
|
12083
|
+
let skipInference = false;
|
12084
|
+
if ((0, types_1.isFunction)(defaultValueType) || (0, types_1.isOverloadedFunction)(defaultValueType)) {
|
12085
|
+
// Do not infer parameter types that use a lambda or another function as a
|
12086
|
+
// default value. We're likely to generate false positives in this case.
|
12087
|
+
// It's not clear whether parameters should be positional-only or not.
|
12088
|
+
skipInference = true;
|
12089
|
+
}
|
12090
|
+
else if ((0, types_1.isClassInstance)(defaultValueType) &&
|
12091
|
+
types_1.ClassType.isBuiltIn(defaultValueType, ['tuple', 'list', 'set', 'dict'])) {
|
12092
|
+
// Do not infer certain types like tuple because it's likely to be
|
12093
|
+
// more restrictive (narrower) than intended.
|
12094
|
+
skipInference = true;
|
12095
|
+
}
|
12096
|
+
if (!skipInference) {
|
12025
12097
|
inferredParamType = stripLiteralValue(defaultValueType);
|
12026
12098
|
}
|
12027
12099
|
}
|
@@ -14025,7 +14097,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14025
14097
|
return undefined;
|
14026
14098
|
}
|
14027
14099
|
function getDeclarationsForNameNode(node, skipUnreachableCode = true) {
|
14028
|
-
var _a;
|
14100
|
+
var _a, _b, _c;
|
14029
14101
|
if (skipUnreachableCode && AnalyzerNodeInfo.isCodeUnreachable(node)) {
|
14030
14102
|
return undefined;
|
14031
14103
|
}
|
@@ -14126,7 +14198,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14126
14198
|
// the corresponding named parameter can be determined from the context.
|
14127
14199
|
const argNode = node.parent;
|
14128
14200
|
const paramName = node.value;
|
14129
|
-
if (argNode.parent
|
14201
|
+
if (((_a = argNode.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 9 /* Call */) {
|
14130
14202
|
const baseType = getType(argNode.parent.leftExpression);
|
14131
14203
|
if (baseType) {
|
14132
14204
|
if ((0, types_1.isFunction)(baseType) && baseType.details.declaration) {
|
@@ -14144,8 +14216,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14144
14216
|
});
|
14145
14217
|
}
|
14146
14218
|
else if ((0, types_1.isInstantiableClass)(baseType)) {
|
14147
|
-
const initMethodType = (
|
14148
|
-
/* diag */ undefined, 4 /* SkipObjectBaseClass */)) === null ||
|
14219
|
+
const initMethodType = (_b = getTypeOfObjectMember(argNode.parent.leftExpression, types_1.ClassType.cloneAsInstance(baseType), '__init__', { method: 'get' },
|
14220
|
+
/* diag */ undefined, 4 /* SkipObjectBaseClass */)) === null || _b === void 0 ? void 0 : _b.type;
|
14149
14221
|
if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
|
14150
14222
|
const paramDecl = getDeclarationFromFunctionNamedParameter(initMethodType, paramName);
|
14151
14223
|
if (paramDecl) {
|
@@ -14161,6 +14233,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14161
14233
|
}
|
14162
14234
|
}
|
14163
14235
|
}
|
14236
|
+
else if (((_c = argNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 10 /* Class */) {
|
14237
|
+
const classTypeResult = getTypeOfClass(argNode.parent);
|
14238
|
+
// Validate the init subclass args for this class so we can properly
|
14239
|
+
// evaluate its custom keyword parameters.
|
14240
|
+
if (classTypeResult) {
|
14241
|
+
validateInitSubclassArgs(argNode.parent, classTypeResult.classType);
|
14242
|
+
}
|
14243
|
+
}
|
14164
14244
|
}
|
14165
14245
|
else {
|
14166
14246
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
@@ -15569,6 +15649,14 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15569
15649
|
effectiveFlags &= ~8 /* SkipSolveTypeVars */;
|
15570
15650
|
prevSrcType = curSrcType;
|
15571
15651
|
}
|
15652
|
+
// If we're enforcing invariance, literal types must match as well.
|
15653
|
+
if ((flags & 1 /* EnforceInvariance */) !== 0) {
|
15654
|
+
const srcIsLiteral = srcType.literalValue !== undefined;
|
15655
|
+
const destIsLiteral = destType.literalValue !== undefined;
|
15656
|
+
if (srcIsLiteral !== destIsLiteral) {
|
15657
|
+
return false;
|
15658
|
+
}
|
15659
|
+
}
|
15572
15660
|
if (destType.typeArguments) {
|
15573
15661
|
// If the dest type is specialized, make sure the specialized source
|
15574
15662
|
// type arguments are assignable to the dest type arguments.
|
@@ -15743,6 +15831,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15743
15831
|
(transformedSrcType !== srcType && (0, types_1.isUnion)(transformedSrcType))) {
|
15744
15832
|
// Use a smaller recursive limit in this case to prevent runaway recursion.
|
15745
15833
|
if (recursionCount > maxRecursiveTypeAliasRecursionCount) {
|
15834
|
+
// Add a special case for when the source is a str, which is itself
|
15835
|
+
// a recursive type (since it derives from Sequence[str]).
|
15836
|
+
if ((0, types_1.isClassInstance)(srcType) && types_1.ClassType.isBuiltIn(srcType, 'str') && (0, types_1.isUnion)(transformedDestType)) {
|
15837
|
+
return transformedDestType.subtypes.some((subtype) => (0, types_1.isClassInstance)(subtype) && types_1.ClassType.isBuiltIn(subtype, ['object', 'str']));
|
15838
|
+
}
|
15746
15839
|
return true;
|
15747
15840
|
}
|
15748
15841
|
}
|
@@ -16626,9 +16719,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16626
16719
|
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext, { useNarrowBoundOnly: true });
|
16627
16720
|
if ((0, typeUtils_1.requiresSpecialization)(specializedDestType)) {
|
16628
16721
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16629
|
-
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
16630
|
-
512 /* IgnoreTypeVarScope */ |
|
16631
|
-
128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16722
|
+
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16632
16723
|
specializedDestType = (0, typeUtils_1.applySolvedTypeVars)(destType, destTypeVarContext);
|
16633
16724
|
}
|
16634
16725
|
}
|
@@ -16636,9 +16727,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16636
16727
|
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext, { useNarrowBoundOnly: true });
|
16637
16728
|
if ((0, typeUtils_1.requiresSpecialization)(specializedSrcType)) {
|
16638
16729
|
reverseMatchingFailed = !assignType(specializedSrcType, specializedDestType,
|
16639
|
-
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) |
|
16640
|
-
512 /* IgnoreTypeVarScope */ |
|
16641
|
-
128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16730
|
+
/* diag */ undefined, srcTypeVarContext, destTypeVarContext, (flags ^ 2 /* ReverseTypeVarMatching */) | 128 /* RetainLiteralsForTypeVar */, recursionCount);
|
16642
16731
|
specializedSrcType = (0, typeUtils_1.applySolvedTypeVars)(srcType, srcTypeVarContext);
|
16643
16732
|
}
|
16644
16733
|
if (reverseMatchingFailed) {
|
@@ -17104,9 +17193,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17104
17193
|
});
|
17105
17194
|
const srcParamSpec = effectiveSrcType.details.paramSpec;
|
17106
17195
|
const destParamSpec = effectiveDestType.details.paramSpec;
|
17107
|
-
|
17108
|
-
|
17109
|
-
|
17196
|
+
// If there are remaining parameters and the source and dest do not contain
|
17197
|
+
// the same ParamSpec, synthesize a function for the remaining parameters.
|
17198
|
+
if (remainingParams.length > 0 ||
|
17199
|
+
!srcParamSpec ||
|
17200
|
+
!(0, types_1.isTypeSame)(srcParamSpec, destParamSpec, { ignoreTypeFlags: true })) {
|
17110
17201
|
const remainingFunction = types_1.FunctionType.createInstance('', '', '', effectiveSrcType.details.flags | 64 /* SynthesizedMethod */, effectiveSrcType.details.docString);
|
17111
17202
|
remainingFunction.details.typeVarScopeId = effectiveSrcType.details.typeVarScopeId;
|
17112
17203
|
remainingParams.forEach((param) => {
|
@@ -17115,28 +17206,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17115
17206
|
remainingFunction.details.paramSpec = srcParamSpec
|
17116
17207
|
? (0, typeUtils_1.convertToInstance)(srcParamSpec)
|
17117
17208
|
: undefined;
|
17118
|
-
if (!(
|
17119
|
-
/* diag */ undefined,
|
17209
|
+
if (!assignType(destParamSpec, remainingFunction,
|
17210
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
|
17120
17211
|
// If we couldn't assign the function to the ParamSpec, see if we can
|
17121
17212
|
// assign only the ParamSpec. This is possible if there were no
|
17122
17213
|
// remaining parameters.
|
17123
17214
|
if (remainingParams.length > 0 ||
|
17124
17215
|
!srcParamSpec ||
|
17125
|
-
!(
|
17126
|
-
/* diag */ undefined,
|
17216
|
+
!assignType(destParamSpec, (0, typeUtils_1.convertToInstance)(srcParamSpec),
|
17217
|
+
/* diag */ undefined, destTypeVarContext, srcTypeVarContext, flags)) {
|
17127
17218
|
canAssign = false;
|
17128
17219
|
}
|
17129
17220
|
}
|
17130
17221
|
}
|
17131
|
-
else {
|
17132
|
-
// If there are any remaining parameters or the source doesn't include the
|
17133
|
-
// dest param spec itself, it is not assignable in this case.
|
17134
|
-
if (!srcParamSpec ||
|
17135
|
-
!(0, types_1.isTypeSame)(srcParamSpec, destParamSpec, { ignoreTypeFlags: true }) ||
|
17136
|
-
remainingParams.length > 0) {
|
17137
|
-
canAssign = false;
|
17138
|
-
}
|
17139
|
-
}
|
17140
17222
|
}
|
17141
17223
|
}
|
17142
17224
|
// Match the return parameter.
|
@@ -17294,7 +17376,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17294
17376
|
}
|
17295
17377
|
return narrowedType;
|
17296
17378
|
}
|
17297
|
-
function validateOverrideMethod(baseMethod, overrideMethod, diag, enforceParamNames = true) {
|
17379
|
+
function validateOverrideMethod(baseMethod, overrideMethod, baseClass, diag, enforceParamNames = true) {
|
17298
17380
|
// If we're overriding a non-method with a method, report it as an error.
|
17299
17381
|
// This occurs when a non-property overrides a property.
|
17300
17382
|
if (!(0, types_1.isFunction)(baseMethod) && !(0, types_1.isOverloadedFunction)(baseMethod)) {
|
@@ -17320,17 +17402,29 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17320
17402
|
// For a non-overloaded method overriding an overloaded method, the
|
17321
17403
|
// override must match all of the overloads.
|
17322
17404
|
if ((0, types_1.isFunction)(overrideMethod)) {
|
17323
|
-
return types_1.OverloadedFunctionType.getOverloads(baseMethod).every((overload) =>
|
17405
|
+
return types_1.OverloadedFunctionType.getOverloads(baseMethod).every((overload) => {
|
17406
|
+
// If the override isn't applicable for this base class, skip the check.
|
17407
|
+
if (baseClass && !isOverrideMethodApplicable(overload, baseClass)) {
|
17408
|
+
return true;
|
17409
|
+
}
|
17410
|
+
return validateOverrideMethodInternal(overload, overrideMethod, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), enforceParamNames);
|
17411
|
+
});
|
17324
17412
|
}
|
17325
17413
|
// For an overloaded method overriding an overloaded method, the overrides
|
17326
17414
|
// must all match and be in the correct order. It is OK if the base method
|
17327
17415
|
// has additional overloads that are not present in the override.
|
17328
17416
|
let previousMatchIndex = -1;
|
17329
17417
|
let overrideOverloadIndex = 0;
|
17418
|
+
const baseOverloads = types_1.OverloadedFunctionType.getOverloads(baseMethod);
|
17330
17419
|
for (const overrideOverload of types_1.OverloadedFunctionType.getOverloads(overrideMethod)) {
|
17331
|
-
const matchIndex =
|
17420
|
+
const matchIndex = baseOverloads.findIndex((baseOverload) => {
|
17421
|
+
// If the override isn't applicable for this base class, skip the check.
|
17422
|
+
if (baseClass && !isOverrideMethodApplicable(baseOverload, baseClass)) {
|
17423
|
+
return false;
|
17424
|
+
}
|
17332
17425
|
return validateOverrideMethodInternal(baseOverload, overrideOverload,
|
17333
|
-
/* diag */ undefined, enforceParamNames
|
17426
|
+
/* diag */ undefined, enforceParamNames,
|
17427
|
+
/* exemptSelfClsParam */ false);
|
17334
17428
|
});
|
17335
17429
|
if (matchIndex < 0) {
|
17336
17430
|
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch().format({ index: overrideOverloadIndex }));
|
@@ -17345,7 +17439,46 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17345
17439
|
}
|
17346
17440
|
return true;
|
17347
17441
|
}
|
17348
|
-
|
17442
|
+
// Determines whether a child class override is applicable to a parent
|
17443
|
+
// class method signature. This is important in cases where the parent
|
17444
|
+
// class defines an overload where some of the overload signatures supply
|
17445
|
+
// explicit type annotations for the "self" or "cls" parameter and some
|
17446
|
+
// of these do not apply to the child class.
|
17447
|
+
function isOverrideMethodApplicable(baseMethod, childClass) {
|
17448
|
+
if (!types_1.FunctionType.isInstanceMethod(baseMethod) &&
|
17449
|
+
!types_1.FunctionType.isClassMethod(baseMethod) &&
|
17450
|
+
!types_1.FunctionType.isConstructorMethod(baseMethod)) {
|
17451
|
+
return true;
|
17452
|
+
}
|
17453
|
+
const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
|
17454
|
+
if (baseParamDetails.params.length === 0) {
|
17455
|
+
return true;
|
17456
|
+
}
|
17457
|
+
const baseParamType = baseParamDetails.params[0].param;
|
17458
|
+
if (baseParamType.category !== 0 /* Simple */ || !baseParamType.hasDeclaredType) {
|
17459
|
+
return true;
|
17460
|
+
}
|
17461
|
+
// If this is a self or cls parameter, determine whether the override
|
17462
|
+
// class can be assigned to the base parameter type. If not, then this
|
17463
|
+
// override doesn't apply. This is important for overloads where the
|
17464
|
+
// base class contains some overload signatures that are not applicable
|
17465
|
+
// to the child class.
|
17466
|
+
const childSelfOrClsType = types_1.FunctionType.isInstanceMethod(baseMethod)
|
17467
|
+
? types_1.ClassType.cloneAsInstance(childClass)
|
17468
|
+
: childClass;
|
17469
|
+
return assignType(baseParamType.type, childSelfOrClsType,
|
17470
|
+
/* diag */ undefined,
|
17471
|
+
/* destTypeVarContext */ undefined,
|
17472
|
+
/* srcTypeVarContext */ undefined, 8 /* SkipSolveTypeVars */);
|
17473
|
+
}
|
17474
|
+
// Determines whether the override method is compatible with the overridden method.
|
17475
|
+
// This is used both for parent/child overrides and implicit overrides for peer
|
17476
|
+
// classes in a multi-inheritance case. If enforceParamNames is true, the parameter
|
17477
|
+
// names of non-positional-only parameters are enforced. If exemptSelfClsParam
|
17478
|
+
// is true, the "self" and "cls" parameters are exempted from type checks.
|
17479
|
+
// This is normally the case except with overloaded method overrides where the
|
17480
|
+
// "self" or "cls" parameter type must be honored to differentiate between overloads.
|
17481
|
+
function validateOverrideMethodInternal(baseMethod, overrideMethod, diag, enforceParamNames, exemptSelfClsParam = true) {
|
17349
17482
|
var _a, _b;
|
17350
17483
|
const baseParamDetails = (0, parameterUtils_1.getParameterListDetails)(baseMethod);
|
17351
17484
|
const overrideParamDetails = (0, parameterUtils_1.getParameterListDetails)(overrideMethod);
|
@@ -17366,7 +17499,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17366
17499
|
canOverride = false;
|
17367
17500
|
}
|
17368
17501
|
}
|
17369
|
-
if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
|
17502
|
+
else if (types_1.FunctionType.isInstanceMethod(baseMethod)) {
|
17370
17503
|
if (!types_1.FunctionType.isInstanceMethod(overrideMethod)) {
|
17371
17504
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideNotInstanceMethod());
|
17372
17505
|
canOverride = false;
|
@@ -17418,7 +17551,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17418
17551
|
// If the first parameter is a "self" or "cls" parameter, skip the
|
17419
17552
|
// test because these are allowed to violate the Liskov substitution
|
17420
17553
|
// principle.
|
17421
|
-
if (i === 0) {
|
17554
|
+
if (i === 0 && exemptSelfClsParam) {
|
17422
17555
|
if (types_1.FunctionType.isInstanceMethod(overrideMethod) ||
|
17423
17556
|
types_1.FunctionType.isClassMethod(overrideMethod) ||
|
17424
17557
|
types_1.FunctionType.isConstructorMethod(overrideMethod)) {
|
@@ -17466,7 +17599,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17466
17599
|
const overrideParamType = overrideParamDetails.params[i].type;
|
17467
17600
|
const baseIsSynthesizedTypeVar = (0, types_1.isTypeVar)(baseParamType) && baseParamType.details.isSynthesized;
|
17468
17601
|
const overrideIsSynthesizedTypeVar = (0, types_1.isTypeVar)(overrideParamType) && overrideParamType.details.isSynthesized;
|
17469
|
-
if (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar) {
|
17602
|
+
if (!exemptSelfClsParam || (!baseIsSynthesizedTypeVar && !overrideIsSynthesizedTypeVar)) {
|
17470
17603
|
if (baseParam.category !== overrideParam.category ||
|
17471
17604
|
!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 */)) {
|
17472
17605
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamType().format({
|
@@ -17511,11 +17644,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17511
17644
|
// Now check any keyword-only parameters.
|
17512
17645
|
const baseKwOnlyParams = baseParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
|
17513
17646
|
paramInfo.param.category === 0 /* Simple */);
|
17514
|
-
const
|
17647
|
+
const overrideKwOnlyParams = overrideParamDetails.params.filter((paramInfo) => paramInfo.source === parameterUtils_1.ParameterSource.KeywordOnly &&
|
17515
17648
|
paramInfo.param.category === 0 /* Simple */);
|
17516
17649
|
baseKwOnlyParams.forEach((paramInfo) => {
|
17517
17650
|
var _a, _b, _c;
|
17518
|
-
const overrideParamInfo =
|
17651
|
+
const overrideParamInfo = overrideKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
|
17519
17652
|
if (!overrideParamInfo && overrideParamDetails.kwargsIndex === undefined) {
|
17520
17653
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideParamNameMissing().format({
|
17521
17654
|
name: (_a = paramInfo.param.name) !== null && _a !== void 0 ? _a : '?',
|
@@ -17548,7 +17681,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17548
17681
|
});
|
17549
17682
|
// Verify that any keyword-only parameters added by the overload are compatible
|
17550
17683
|
// with the **kwargs in the base.
|
17551
|
-
|
17684
|
+
overrideKwOnlyParams.forEach((paramInfo) => {
|
17552
17685
|
var _a;
|
17553
17686
|
const baseParamInfo = baseKwOnlyParams.find((pi) => paramInfo.param.name === pi.param.name);
|
17554
17687
|
if (!baseParamInfo) {
|
@@ -18028,6 +18161,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18028
18161
|
verifyRaiseExceptionType,
|
18029
18162
|
verifyDeleteExpression,
|
18030
18163
|
validateOverloadedFunctionArguments,
|
18164
|
+
validateInitSubclassArgs,
|
18031
18165
|
isAfterNodeReachable,
|
18032
18166
|
isNodeReachable,
|
18033
18167
|
isAsymmetricDescriptorAssignment: isAsymmetricAccessorAssignment,
|
@@ -18075,6 +18209,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18075
18209
|
getBuiltInObject,
|
18076
18210
|
getTypingType,
|
18077
18211
|
verifyTypeArgumentsAssignable,
|
18212
|
+
reportMissingTypeArguments,
|
18078
18213
|
inferReturnTypeIfNecessary,
|
18079
18214
|
inferTypeParameterVarianceForClass,
|
18080
18215
|
isFinalVariable,
|