@zzzen/pyright-internal 1.2.0-dev.20230813 → 1.2.0-dev.20230827
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/binder.js +8 -2
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.d.ts +1 -0
- package/dist/analyzer/checker.js +123 -70
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +23 -1
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +2 -1
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +1 -1
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/dataClasses.js +242 -236
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/decorators.js +11 -6
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/deprecatedSymbols.d.ts +9 -0
- package/dist/analyzer/deprecatedSymbols.js +292 -0
- package/dist/analyzer/deprecatedSymbols.js.map +1 -0
- package/dist/analyzer/docStringConversion.js +7 -1
- package/dist/analyzer/docStringConversion.js.map +1 -1
- package/dist/analyzer/enums.js +12 -0
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importResolver.js +8 -1
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/namedTuples.js +6 -0
- package/dist/analyzer/namedTuples.js.map +1 -1
- package/dist/analyzer/operations.d.ts +1 -1
- package/dist/analyzer/operations.js +2 -2
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/parameterUtils.d.ts +2 -1
- package/dist/analyzer/parameterUtils.js +15 -0
- package/dist/analyzer/parameterUtils.js.map +1 -1
- package/dist/analyzer/program.d.ts +3 -3
- package/dist/analyzer/program.js +5 -9
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/protocols.js +14 -0
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.js +2 -2
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.js +1 -0
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +713 -529
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
- package/dist/analyzer/typeEvaluatorTypes.js +2 -2
- package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
- package/dist/analyzer/typeGuards.js +18 -4
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typePrinter.js +3 -0
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +3 -2
- package/dist/analyzer/typeUtils.js +30 -7
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.js +3 -1
- package/dist/analyzer/typeVarContext.js.map +1 -1
- package/dist/analyzer/types.d.ts +6 -1
- package/dist/analyzer/types.js +20 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/cancellationUtils.d.ts +2 -1
- package/dist/common/cancellationUtils.js +3 -0
- package/dist/common/cancellationUtils.js.map +1 -1
- package/dist/common/configOptions.d.ts +1 -0
- package/dist/common/configOptions.js +5 -1
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/diagnosticRules.d.ts +1 -0
- package/dist/common/diagnosticRules.js +1 -0
- package/dist/common/diagnosticRules.js.map +1 -1
- package/dist/common/serviceProvider.d.ts +4 -3
- package/dist/languageServerBase.d.ts +2 -2
- package/dist/languageServerBase.js +4 -2
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/completionProvider.js +9 -3
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +25 -4
- package/dist/localization/localize.js +8 -2
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +15 -12
- package/dist/localization/package.nls.de.json +15 -12
- package/dist/localization/package.nls.en-us.json +18 -12
- package/dist/localization/package.nls.es.json +15 -12
- package/dist/localization/package.nls.fr.json +15 -12
- package/dist/localization/package.nls.it.json +15 -12
- package/dist/localization/package.nls.ja.json +15 -12
- package/dist/localization/package.nls.ko.json +15 -12
- package/dist/localization/package.nls.pl.json +15 -12
- package/dist/localization/package.nls.pt-br.json +15 -12
- package/dist/localization/package.nls.qps-ploc.json +15 -12
- package/dist/localization/package.nls.ru.json +15 -12
- package/dist/localization/package.nls.tr.json +15 -12
- package/dist/localization/package.nls.zh-cn.json +15 -12
- package/dist/localization/package.nls.zh-tw.json +14 -11
- package/dist/parser/parser.d.ts +1 -0
- package/dist/parser/parser.js +80 -18
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.d.ts +1 -1
- package/dist/parser/tokenizer.js +9 -5
- package/dist/parser/tokenizer.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tests/checker.test.js +34 -13
- package/dist/tests/checker.test.js.map +1 -1
- package/dist/tests/completions.test.js +39 -2
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/docStringConversion.test.js +23 -0
- package/dist/tests/docStringConversion.test.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.d.ts +1 -1
- package/dist/tests/harness/fourslash/testState.js +2 -2
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +8 -4
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +13 -1
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +21 -23
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +21 -1
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +33 -1
- package/dist/tests/typeEvaluator5.test.js.map +1 -1
- package/dist/workspaceFactory.d.ts +1 -1
- package/dist/workspaceFactory.js +3 -3
- package/dist/workspaceFactory.js.map +1 -1
- package/package.json +1 -1
@@ -683,10 +683,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
683
683
|
}
|
684
684
|
return typeResult;
|
685
685
|
}
|
686
|
+
// Reports the case where a function or class has been decorated with
|
687
|
+
// @type_check_only and is used in a value expression.
|
688
|
+
function reportUseOfTypeCheckOnly(type, node) {
|
689
|
+
let isTypeCheckingOnly = false;
|
690
|
+
let name = '';
|
691
|
+
if ((0, types_1.isInstantiableClass)(type) && !type.includeSubclasses) {
|
692
|
+
isTypeCheckingOnly = types_1.ClassType.isTypeCheckOnly(type);
|
693
|
+
name = type.details.name;
|
694
|
+
}
|
695
|
+
else if ((0, types_1.isFunction)(type)) {
|
696
|
+
isTypeCheckingOnly = types_1.FunctionType.isTypeCheckOnly(type);
|
697
|
+
name = type.details.name;
|
698
|
+
}
|
699
|
+
if (isTypeCheckingOnly) {
|
700
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
701
|
+
if (!fileInfo.isStubFile) {
|
702
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeCheckOnly().format({ name }), node);
|
703
|
+
}
|
704
|
+
}
|
705
|
+
}
|
686
706
|
function reportInvalidUseOfPep695TypeAlias(type, node) {
|
687
707
|
var _a;
|
688
708
|
// PEP 695 type aliases cannot be used as instantiable classes.
|
689
|
-
if (((_a = type.typeAliasInfo) === null || _a === void 0 ? void 0 : _a.name) && type.typeAliasInfo.isPep695Syntax) {
|
709
|
+
if (((_a = type.typeAliasInfo) === null || _a === void 0 ? void 0 : _a.name) && type.typeAliasInfo.isPep695Syntax && types_1.TypeBase.isSpecialForm(type)) {
|
690
710
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasNotAllowed().format({ name: type.typeAliasInfo.name }), node);
|
691
711
|
return true;
|
692
712
|
}
|
@@ -980,9 +1000,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
980
1000
|
if (options === null || options === void 0 ? void 0 : options.associateTypeVarsWithScope) {
|
981
1001
|
evaluatorFlags |= 8192 /* AssociateTypeVarsWithCurrentScope */;
|
982
1002
|
}
|
983
|
-
else {
|
984
|
-
evaluatorFlags |= 4096 /* DisallowTypeVarsWithoutScopeId */;
|
985
|
-
}
|
986
1003
|
if (options === null || options === void 0 ? void 0 : options.allowUnpackedTypedDict) {
|
987
1004
|
evaluatorFlags |= 8388608 /* AllowUnpackedTypedDict */;
|
988
1005
|
}
|
@@ -1237,11 +1254,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1237
1254
|
let memberInfo;
|
1238
1255
|
const classDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
1239
1256
|
const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
1257
|
+
let considerMetaclassOnly = (memberAccessFlags & 32 /* ConsiderMetaclassOnly */) !== 0;
|
1240
1258
|
if (types_1.ClassType.isPartiallyEvaluated(classType)) {
|
1241
1259
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), errorNode);
|
1242
1260
|
return { type: types_1.UnknownType.create() };
|
1243
1261
|
}
|
1244
|
-
|
1262
|
+
const metaclass = classType.details.effectiveMetaclass;
|
1263
|
+
// Look up the attribute in the metaclass first. If the member is a descriptor
|
1264
|
+
// (an object with a __get__ method) and the access is a 'get', the Python runtime
|
1265
|
+
// uses this metaclass descriptor to satisfy the lookup. Skip this costly lookup
|
1266
|
+
// in the common case where the metaclass is 'type' since we know that `type` doesn't
|
1267
|
+
// have any attributes that are descriptors.
|
1268
|
+
if (usage.method === 'get' &&
|
1269
|
+
metaclass &&
|
1270
|
+
(0, types_1.isInstantiableClass)(metaclass) &&
|
1271
|
+
!types_1.ClassType.isBuiltIn(metaclass, 'type') &&
|
1272
|
+
!types_1.ClassType.isSameGenericClass(metaclass, classType)) {
|
1273
|
+
const metaclassMemberInfo = getTypeOfClassMemberName(errorNode, metaclass,
|
1274
|
+
/* isAccessedThroughObject */ false, memberName, usage, metaclassDiag, memberAccessFlags, classType);
|
1275
|
+
if (metaclassMemberInfo && (0, typeUtils_1.isDescriptorInstance)(metaclassMemberInfo.type)) {
|
1276
|
+
considerMetaclassOnly = true;
|
1277
|
+
}
|
1278
|
+
}
|
1279
|
+
// Look up the attribute in the class object.
|
1280
|
+
if (!memberInfo && !considerMetaclassOnly) {
|
1245
1281
|
memberInfo = getTypeOfClassMemberName(errorNode, classType,
|
1246
1282
|
/* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
|
1247
1283
|
}
|
@@ -2507,14 +2543,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2507
2543
|
(types_1.ClassType.isBuiltIn(callType, 'TypeVar') ||
|
2508
2544
|
types_1.ClassType.isBuiltIn(callType, 'TypeVarTuple') ||
|
2509
2545
|
types_1.ClassType.isBuiltIn(callType, 'ParamSpec'))) {
|
2510
|
-
|
2546
|
+
const typeVarTarget = target.nodeType === 54 /* TypeAnnotation */ ? target.valueExpression : target;
|
2547
|
+
if (typeVarTarget.nodeType !== 38 /* Name */ || typeVarTarget.value !== type.details.name) {
|
2511
2548
|
addError(type.details.isParamSpec
|
2512
2549
|
? localize_1.Localizer.Diagnostic.paramSpecAssignedName().format({
|
2513
2550
|
name: types_1.TypeVarType.getReadableName(type),
|
2514
2551
|
})
|
2515
2552
|
: localize_1.Localizer.Diagnostic.typeVarAssignedName().format({
|
2516
2553
|
name: types_1.TypeVarType.getReadableName(type),
|
2517
|
-
}),
|
2554
|
+
}), typeVarTarget);
|
2518
2555
|
}
|
2519
2556
|
}
|
2520
2557
|
}
|
@@ -2922,6 +2959,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2922
2959
|
}
|
2923
2960
|
}
|
2924
2961
|
}
|
2962
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
|
2963
|
+
reportUseOfTypeCheckOnly(type, node);
|
2964
|
+
}
|
2925
2965
|
if ((flags & 16777216 /* DisallowPep695TypeAlias */) !== 0) {
|
2926
2966
|
if (reportInvalidUseOfPep695TypeAlias(type, node)) {
|
2927
2967
|
type = types_1.UnknownType.create();
|
@@ -3079,7 +3119,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3079
3119
|
}
|
3080
3120
|
}
|
3081
3121
|
}
|
3082
|
-
else if ((flags & 4096 /*
|
3122
|
+
else if ((flags & 4096 /* AllowTypeVarsWithoutScopeId */) === 0) {
|
3083
3123
|
if ((type.scopeId === undefined || scopedTypeVarInfo.foundInterveningClass) &&
|
3084
3124
|
!type.details.isSynthesized) {
|
3085
3125
|
let message;
|
@@ -3271,7 +3311,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3271
3311
|
4 /* AllowForwardReferences */ |
|
3272
3312
|
524288 /* NotParsedByInterpreter */ |
|
3273
3313
|
2048 /* DisallowTypeVarsWithScopeId */ |
|
3274
|
-
4096 /* DisallowTypeVarsWithoutScopeId */ |
|
3275
3314
|
8192 /* AssociateTypeVarsWithCurrentScope */));
|
3276
3315
|
const baseTypeResult = getTypeOfExpression(node.leftExpression, baseTypeFlags);
|
3277
3316
|
if ((0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
|
@@ -3392,7 +3431,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3392
3431
|
}
|
3393
3432
|
return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
|
3394
3433
|
}
|
3395
|
-
if (flags & 256 /* ExpectingTypeAnnotation */) {
|
3434
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
3396
3435
|
if (!isIncomplete) {
|
3397
3436
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
|
3398
3437
|
type: printType(baseType),
|
@@ -3616,6 +3655,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3616
3655
|
// additional reportUnknownMemberType diagnostics.
|
3617
3656
|
type = isFunctionRule ? types_1.AnyType.create() : types_1.UnknownType.create();
|
3618
3657
|
}
|
3658
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
|
3659
|
+
reportUseOfTypeCheckOnly(type, node.memberName);
|
3660
|
+
}
|
3619
3661
|
// Should we specialize the class?
|
3620
3662
|
if ((flags & 2 /* DoNotSpecialize */) === 0) {
|
3621
3663
|
if ((0, types_1.isInstantiableClass)(type) && !type.typeArguments) {
|
@@ -3708,13 +3750,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3708
3750
|
}
|
3709
3751
|
}
|
3710
3752
|
if (!type) {
|
3753
|
+
let selfClass = classType;
|
3711
3754
|
// Determine whether to replace Self variables with a specific
|
3712
3755
|
// class. Avoid doing this if there's a "bindToType" specified
|
3713
3756
|
// because that case is used for super() calls where we want
|
3714
3757
|
// to leave the Self type generic (not specialized). We'll also
|
3715
3758
|
// skip this for __new__ methods because they are not bound
|
3716
3759
|
// to the class but rather assume the type of the cls argument.
|
3717
|
-
|
3760
|
+
if (bindToType) {
|
3761
|
+
if ((0, types_1.isTypeVar)(bindToType) && bindToType.details.isSynthesizedSelf) {
|
3762
|
+
selfClass = bindToType;
|
3763
|
+
}
|
3764
|
+
else {
|
3765
|
+
selfClass = undefined;
|
3766
|
+
}
|
3767
|
+
}
|
3768
|
+
else if (memberName === '__new__') {
|
3769
|
+
selfClass = undefined;
|
3770
|
+
}
|
3718
3771
|
const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
|
3719
3772
|
if (typeResult) {
|
3720
3773
|
type = typeResult.type;
|
@@ -3888,10 +3941,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3888
3941
|
},
|
3889
3942
|
];
|
3890
3943
|
if (usage.method === 'get') {
|
3891
|
-
// Provide "
|
3944
|
+
// Provide "owner" argument.
|
3892
3945
|
argList.push({
|
3893
3946
|
argumentCategory: 0 /* Simple */,
|
3894
|
-
typeResult: {
|
3947
|
+
typeResult: {
|
3948
|
+
type: baseTypeClass,
|
3949
|
+
},
|
3895
3950
|
});
|
3896
3951
|
}
|
3897
3952
|
else if (usage.method === 'set') {
|
@@ -4248,14 +4303,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4248
4303
|
function getTypeOfIndex(node, flags = 0 /* None */) {
|
4249
4304
|
const baseTypeResult = getTypeOfExpression(node.baseExpression, flags | 2 /* IndexBaseDefaults */);
|
4250
4305
|
// If this is meant to be a type and the base expression is a string expression,
|
4251
|
-
// emit an error because this
|
4252
|
-
//
|
4306
|
+
// emit an error because this is an illegal annotation form and will generate a
|
4307
|
+
// runtime exception.
|
4253
4308
|
if (flags & 128 /* ExpectingInstantiableType */) {
|
4254
4309
|
if (node.baseExpression.nodeType === 48 /* StringList */) {
|
4255
|
-
|
4256
|
-
if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
|
4257
|
-
addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
|
4258
|
-
}
|
4310
|
+
addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
|
4259
4311
|
}
|
4260
4312
|
}
|
4261
4313
|
// Check for builtin classes that will generate runtime exceptions if subscripted.
|
@@ -4487,6 +4539,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4487
4539
|
if ((0, types_1.isParamSpec)(typeArg)) {
|
4488
4540
|
functionType.details.paramSpec = typeArg;
|
4489
4541
|
}
|
4542
|
+
else if ((0, typeUtils_1.isEllipsisType)(typeArg)) {
|
4543
|
+
types_1.FunctionType.addDefaultParameters(functionType);
|
4544
|
+
functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
|
4545
|
+
}
|
4490
4546
|
}
|
4491
4547
|
else {
|
4492
4548
|
types_1.FunctionType.addParameter(functionType, {
|
@@ -4601,7 +4657,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4601
4657
|
const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
|
4602
4658
|
/* usage */ undefined,
|
4603
4659
|
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 32 /* ConsiderMetaclassOnly */);
|
4604
|
-
if (flags & 256 /* ExpectingTypeAnnotation */) {
|
4660
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
4605
4661
|
// If the class doesn't derive from Generic, a type argument should not be allowed.
|
4606
4662
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
|
4607
4663
|
name: printType(types_1.ClassType.cloneAsInstance(concreteSubtype)),
|
@@ -4653,9 +4709,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4653
4709
|
// Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
|
4654
4710
|
// This feature is currently experimental.
|
4655
4711
|
const supportsTypedDictTypeArg = AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
|
4656
|
-
|
4657
|
-
types_1.ClassType.isBuiltIn(concreteSubtype, '
|
4658
|
-
!concreteSubtype.aliasName;
|
4712
|
+
types_1.ClassType.isBuiltIn(concreteSubtype, ['dict', 'TypedDict']) &&
|
4713
|
+
!types_1.ClassType.isBuiltIn(concreteSubtype, 'Dict');
|
4659
4714
|
let typeArgs = getTypeArgs(node, flags, {
|
4660
4715
|
isAnnotatedClass,
|
4661
4716
|
hasCustomClassGetItem: hasCustomClassGetItem || !isGenericClass,
|
@@ -4866,14 +4921,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4866
4921
|
typeof valueType.literalValue === 'number') {
|
4867
4922
|
const indexValue = valueType.literalValue;
|
4868
4923
|
const tupleType = (0, typeUtils_1.getSpecializedTupleType)(baseType);
|
4869
|
-
if (tupleType && tupleType.tupleTypeArguments
|
4870
|
-
if (
|
4871
|
-
|
4872
|
-
|
4873
|
-
|
4874
|
-
|
4875
|
-
|
4876
|
-
|
4924
|
+
if (tupleType && tupleType.tupleTypeArguments) {
|
4925
|
+
if ((0, typeUtils_1.isTupleIndexUnambiguous)(tupleType, indexValue)) {
|
4926
|
+
if (indexValue >= 0 && indexValue < tupleType.tupleTypeArguments.length) {
|
4927
|
+
return { type: tupleType.tupleTypeArguments[indexValue].type };
|
4928
|
+
}
|
4929
|
+
else if (indexValue < 0 && tupleType.tupleTypeArguments.length + indexValue >= 0) {
|
4930
|
+
return {
|
4931
|
+
type: tupleType.tupleTypeArguments[tupleType.tupleTypeArguments.length + indexValue]
|
4932
|
+
.type,
|
4933
|
+
};
|
4934
|
+
}
|
4877
4935
|
}
|
4878
4936
|
}
|
4879
4937
|
}
|
@@ -5623,7 +5681,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5623
5681
|
if (node.arguments.length > 2) {
|
5624
5682
|
addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
|
5625
5683
|
}
|
5626
|
-
const
|
5684
|
+
const enclosingFunction = ParseTreeUtils.getEnclosingFunction(node);
|
5685
|
+
const enclosingClass = enclosingFunction
|
5686
|
+
? ParseTreeUtils.getEnclosingClass(enclosingFunction, /* stopAtFunction */ true)
|
5687
|
+
: undefined;
|
5627
5688
|
const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
|
5628
5689
|
// Determine which class the "super" call is applied to. If
|
5629
5690
|
// there is no first argument, then the class is implicit.
|
@@ -5663,7 +5724,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5663
5724
|
}
|
5664
5725
|
else if ((0, types_1.isInstantiableClass)(secondArgType)) {
|
5665
5726
|
if ((0, types_1.isInstantiableClass)(targetClassType)) {
|
5666
|
-
if (!
|
5727
|
+
if (!types_1.ClassType.isBuiltIn(targetClassType, 'type') &&
|
5728
|
+
!(0, typeUtils_1.derivesFromClassRecursive)(secondArgType, targetClassType, /* ignoreUnknown */ true)) {
|
5667
5729
|
reportError = true;
|
5668
5730
|
}
|
5669
5731
|
}
|
@@ -5793,13 +5855,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5793
5855
|
return argParamCopy;
|
5794
5856
|
});
|
5795
5857
|
}
|
5796
|
-
// Clone the typeVarContext so we don't modify the original.
|
5797
|
-
|
5798
|
-
// from the previous successful match.
|
5799
|
-
const typeVarContextToClone = matchedOverloads.length > 0
|
5800
|
-
? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
|
5801
|
-
: typeVarContext;
|
5802
|
-
const effectiveTypeVarContext = (_a = typeVarContextToClone === null || typeVarContextToClone === void 0 ? void 0 : typeVarContextToClone.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
|
5858
|
+
// Clone the typeVarContext so we don't modify the original.
|
5859
|
+
const effectiveTypeVarContext = (_a = typeVarContext === null || typeVarContext === void 0 ? void 0 : typeVarContext.clone()) !== null && _a !== void 0 ? _a : new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(overload));
|
5803
5860
|
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
|
5804
5861
|
effectiveTypeVarContext.unlock();
|
5805
5862
|
// Use speculative mode so we don't output any diagnostics or
|
@@ -6294,23 +6351,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6294
6351
|
}
|
6295
6352
|
}
|
6296
6353
|
}
|
6354
|
+
let effectiveTypeVarContext = typeVarContext;
|
6355
|
+
if (!effectiveTypeVarContext) {
|
6356
|
+
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6357
|
+
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
|
6358
|
+
}
|
6297
6359
|
// The stdlib collections/__init__.pyi stub file defines namedtuple
|
6298
6360
|
// as a function rather than a class, so we need to check for it here.
|
6299
6361
|
if (expandedCallType.details.builtInName === 'namedtuple') {
|
6300
6362
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportUntypedNamedTuple, diagnosticRules_1.DiagnosticRule.reportUntypedNamedTuple, localize_1.Localizer.Diagnostic.namedTupleNoTypes(), errorNode);
|
6301
|
-
|
6363
|
+
const result = {
|
6302
6364
|
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ false),
|
6303
6365
|
};
|
6366
|
+
validateFunctionArguments(errorNode, argList, { type: expandedCallType }, effectiveTypeVarContext, skipUnknownArgCheck);
|
6367
|
+
return result;
|
6304
6368
|
}
|
6305
6369
|
// Handle the NewType specially, replacing the normal return type.
|
6306
6370
|
if (expandedCallType.details.builtInName === 'NewType') {
|
6307
6371
|
return { returnType: createNewType(errorNode, argList) };
|
6308
6372
|
}
|
6309
|
-
let effectiveTypeVarContext = typeVarContext;
|
6310
|
-
if (!effectiveTypeVarContext) {
|
6311
|
-
// If a typeVarContext wasn't provided by the caller, allocate one here.
|
6312
|
-
effectiveTypeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeIds)(expandedCallType));
|
6313
|
-
}
|
6314
6373
|
const functionResult = validateFunctionArguments(errorNode, argList, { type: expandedCallType, isIncomplete: isCallTypeIncomplete }, effectiveTypeVarContext, skipUnknownArgCheck, inferenceContext);
|
6315
6374
|
let isTypeIncomplete = !!functionResult.isTypeIncomplete;
|
6316
6375
|
let returnType = functionResult.returnType;
|
@@ -6437,9 +6496,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6437
6496
|
}
|
6438
6497
|
}
|
6439
6498
|
if (className === 'NamedTuple') {
|
6440
|
-
|
6499
|
+
const result = {
|
6441
6500
|
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
|
6442
6501
|
};
|
6502
|
+
const initTypeResult = getTypeOfObjectMember(errorNode, types_1.ClassType.cloneAsInstance(expandedCallType), '__init__');
|
6503
|
+
if (initTypeResult && (0, types_1.isOverloadedFunction)(initTypeResult.type)) {
|
6504
|
+
validateOverloadedFunctionArguments(errorNode, argList, { type: initTypeResult.type },
|
6505
|
+
/* typeVarContext */ undefined, skipUnknownArgCheck,
|
6506
|
+
/* inferenceContext */ undefined);
|
6507
|
+
}
|
6508
|
+
return result;
|
6443
6509
|
}
|
6444
6510
|
if (className === 'NewType') {
|
6445
6511
|
return { returnType: createNewType(errorNode, argList) };
|
@@ -6537,7 +6603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6537
6603
|
var _a, _b;
|
6538
6604
|
const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
|
6539
6605
|
/* usage */ undefined,
|
6540
|
-
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
6606
|
+
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 1 /* AccessClassMembersOnly */)) === null || _a === void 0 ? void 0 : _a.type;
|
6541
6607
|
if (!memberType) {
|
6542
6608
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6543
6609
|
type: printType(expandedCallType),
|
@@ -7940,6 +8006,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7940
8006
|
const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
|
7941
8007
|
const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
|
7942
8008
|
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
8009
|
+
const nestedArgList = [];
|
7943
8010
|
argList.forEach((arg) => {
|
7944
8011
|
var _a;
|
7945
8012
|
if (arg.argumentCategory === 0 /* Simple */) {
|
@@ -7969,6 +8036,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7969
8036
|
else if (argsParam) {
|
7970
8037
|
paramType = argsParam.type;
|
7971
8038
|
}
|
8039
|
+
else if (paramSpecType.details.paramSpec) {
|
8040
|
+
nestedArgList.push(arg);
|
8041
|
+
}
|
7972
8042
|
else {
|
7973
8043
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, paramSpecParams.length === 1
|
7974
8044
|
? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
|
@@ -8014,6 +8084,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8014
8084
|
}
|
8015
8085
|
}
|
8016
8086
|
});
|
8087
|
+
// Handle recursive ParamSpecs.
|
8088
|
+
if (paramSpecType.details.paramSpec) {
|
8089
|
+
const boundTypeForParamSpec = srcTypeVarContext
|
8090
|
+
.getPrimarySignature()
|
8091
|
+
.getParamSpecType(paramSpecType.details.paramSpec);
|
8092
|
+
if (boundTypeForParamSpec) {
|
8093
|
+
const paramSpecArgResult = validateFunctionArgumentsForParamSpec(errorNode, nestedArgList, paramSpecType.details.paramSpec, srcTypeVarContext, conditionFilter);
|
8094
|
+
if (paramSpecArgResult.argumentErrors) {
|
8095
|
+
reportedArgError = true;
|
8096
|
+
}
|
8097
|
+
}
|
8098
|
+
}
|
8017
8099
|
});
|
8018
8100
|
}
|
8019
8101
|
// Report any missing parameters.
|
@@ -8051,10 +8133,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8051
8133
|
let isCompatible = true;
|
8052
8134
|
const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
|
8053
8135
|
let skippedBareTypeVarExpectedType = false;
|
8136
|
+
let skipSolveTypeVars = false;
|
8054
8137
|
if (argParam.argument.valueExpression) {
|
8055
8138
|
let expectedType;
|
8056
|
-
|
8057
|
-
|
8139
|
+
// Is the expected type a "bare" in-scope TypeVar or a union of bare in-scope TypeVars?
|
8140
|
+
let isExpectedTypeBareTypeVar = true;
|
8141
|
+
(0, typeUtils_1.doForEachSubtype)(argParam.paramType, (subtype) => {
|
8142
|
+
if (!(0, types_1.isTypeVar)(subtype) || subtype.scopeId !== (typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.typeVarScopeId)) {
|
8143
|
+
isExpectedTypeBareTypeVar = false;
|
8144
|
+
}
|
8145
|
+
});
|
8146
|
+
if (!options.skipBareTypeVarExpectedType || !isExpectedTypeBareTypeVar) {
|
8058
8147
|
expectedType = argParam.paramType;
|
8059
8148
|
// If the parameter type is a function with a ParamSpec, don't apply
|
8060
8149
|
// the solved TypeVars if the typeVarContext has more than one signature.
|
@@ -8070,6 +8159,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8070
8159
|
}
|
8071
8160
|
else {
|
8072
8161
|
skippedBareTypeVarExpectedType = true;
|
8162
|
+
// If the expected type is a union of bare TypeVars, it's not clear which of the two
|
8163
|
+
// (or both) should be constrained. We'll skip any attempt to solve the TypeVars during
|
8164
|
+
// this pass and hope that subsequent arg assignments will help us establish the correct
|
8165
|
+
// constraints.
|
8166
|
+
if ((0, types_1.isUnion)(argParam.paramType)) {
|
8167
|
+
skipSolveTypeVars = true;
|
8168
|
+
}
|
8073
8169
|
}
|
8074
8170
|
// If the expected type is unknown, don't use an expected type. Instead,
|
8075
8171
|
// use default rules for evaluating the expression type.
|
@@ -8186,7 +8282,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8186
8282
|
}
|
8187
8283
|
}
|
8188
8284
|
if ((0, types_1.isClassInstance)(argType)) {
|
8189
|
-
const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__');
|
8285
|
+
const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 8 /* SkipInstanceVariables */);
|
8190
8286
|
if (callMember) {
|
8191
8287
|
const memberType = getTypeOfMember(callMember);
|
8192
8288
|
if ((0, types_1.isOverloadedFunction)(memberType)) {
|
@@ -8203,7 +8299,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8203
8299
|
}
|
8204
8300
|
}
|
8205
8301
|
}
|
8206
|
-
if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext
|
8302
|
+
if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext,
|
8303
|
+
/* srcTypeVarContext */ undefined, skipSolveTypeVars ? 8 /* SkipSolveTypeVars */ : undefined)) {
|
8207
8304
|
// Mismatching parameter types are common in untyped code; don't bother spending time
|
8208
8305
|
// printing types if the diagnostic is disabled.
|
8209
8306
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(argParam.errorNode);
|
@@ -8637,7 +8734,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8637
8734
|
typeParameters = [];
|
8638
8735
|
let isTypeParamListValid = true;
|
8639
8736
|
typeParamsExpr.expressions.map((expr) => {
|
8640
|
-
let entryType = getTypeOfExpression(expr, 128 /* ExpectingInstantiableType */).type;
|
8737
|
+
let entryType = getTypeOfExpression(expr, 128 /* ExpectingInstantiableType */ | 4096 /* AllowTypeVarsWithoutScopeId */).type;
|
8641
8738
|
if ((0, types_1.isTypeVar)(entryType)) {
|
8642
8739
|
if (entryType.scopeId) {
|
8643
8740
|
isTypeParamListValid = false;
|
@@ -8937,7 +9034,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8937
9034
|
}
|
8938
9035
|
function getTypeOfDictionaryWithContext(node, inferenceContext, expectedDiagAddendum) {
|
8939
9036
|
inferenceContext.expectedType = (0, typeUtils_1.transformPossibleRecursiveTypeAlias)(inferenceContext.expectedType);
|
8940
|
-
|
9037
|
+
let concreteExpectedType = makeTopLevelTypeVarsConcrete(inferenceContext.expectedType);
|
8941
9038
|
if (!(0, types_1.isClassInstance)(concreteExpectedType)) {
|
8942
9039
|
return undefined;
|
8943
9040
|
}
|
@@ -8946,6 +9043,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8946
9043
|
let isIncomplete = false;
|
8947
9044
|
// Handle TypedDict's as a special case.
|
8948
9045
|
if (types_1.ClassType.isTypedDictClass(concreteExpectedType)) {
|
9046
|
+
// Remove any conditions associated with the type so the resulting type isn't
|
9047
|
+
// considered compatible with a bound TypeVar.
|
9048
|
+
concreteExpectedType = types_1.TypeBase.cloneForCondition(concreteExpectedType, undefined);
|
8949
9049
|
const expectedTypedDictEntries = (0, typedDicts_1.getTypedDictMembersForClass)(evaluatorInterface, concreteExpectedType);
|
8950
9050
|
// Infer the key and value types if possible.
|
8951
9051
|
if (getKeyAndValueTypesFromDictionary(node, keyTypes, valueTypes,
|
@@ -8955,17 +9055,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8955
9055
|
/* expectedValueType */ undefined, expectedTypedDictEntries, expectedDiagAddendum)) {
|
8956
9056
|
isIncomplete = true;
|
8957
9057
|
}
|
8958
|
-
|
8959
|
-
|
8960
|
-
|
8961
|
-
|
8962
|
-
|
8963
|
-
|
8964
|
-
|
8965
|
-
|
8966
|
-
|
8967
|
-
};
|
8968
|
-
}
|
9058
|
+
const resultTypedDict = (0, typedDicts_1.assignToTypedDict)(evaluatorInterface, concreteExpectedType, keyTypes, valueTypes,
|
9059
|
+
// Don't overwrite existing expectedDiagAddendum messages if they were
|
9060
|
+
// already provided by getKeyValueTypesFromDictionary.
|
9061
|
+
(expectedDiagAddendum === null || expectedDiagAddendum === void 0 ? void 0 : expectedDiagAddendum.isEmpty()) ? expectedDiagAddendum : undefined);
|
9062
|
+
if (resultTypedDict) {
|
9063
|
+
return {
|
9064
|
+
type: resultTypedDict,
|
9065
|
+
isIncomplete,
|
9066
|
+
};
|
8969
9067
|
}
|
8970
9068
|
return undefined;
|
8971
9069
|
}
|
@@ -9901,6 +9999,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9901
9999
|
if ((0, types_1.isParamSpec)(typeArg)) {
|
9902
10000
|
functionType.details.paramSpec = typeArg;
|
9903
10001
|
}
|
10002
|
+
else if ((0, typeUtils_1.isEllipsisType)(typeArg)) {
|
10003
|
+
types_1.FunctionType.addDefaultParameters(functionType);
|
10004
|
+
functionType.details.flags |= 32768 /* SkipArgsKwargsCompatibilityCheck */;
|
10005
|
+
}
|
9904
10006
|
}
|
9905
10007
|
else {
|
9906
10008
|
types_1.FunctionType.addParameter(functionType, {
|
@@ -10279,7 +10381,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10279
10381
|
else {
|
10280
10382
|
typeArgs.forEach((typeArg, index) => {
|
10281
10383
|
if (index === typeArgs.length - 1) {
|
10282
|
-
if (!(0, types_1.isParamSpec)(typeArg.type)) {
|
10384
|
+
if (!(0, types_1.isParamSpec)(typeArg.type) && !(0, typeUtils_1.isEllipsisType)(typeArg.type)) {
|
10283
10385
|
addError(localize_1.Localizer.Diagnostic.concatenateParamSpecMissing(), typeArg.node);
|
10284
10386
|
}
|
10285
10387
|
}
|
@@ -10337,7 +10439,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10337
10439
|
typeArgs.forEach((typeArg, index) => {
|
10338
10440
|
if ((0, typeUtils_1.isEllipsisType)(typeArg.type)) {
|
10339
10441
|
if (!isTupleTypeParam) {
|
10340
|
-
|
10442
|
+
if (!allowParamSpec) {
|
10443
|
+
addError(localize_1.Localizer.Diagnostic.ellipsisContext(), typeArg.node);
|
10444
|
+
}
|
10341
10445
|
}
|
10342
10446
|
else if (typeArgs.length !== 2 || index !== 1) {
|
10343
10447
|
addError(localize_1.Localizer.Diagnostic.ellipsisSecondArg(), typeArg.node);
|
@@ -10555,7 +10659,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10555
10659
|
names: boundTypeVars.map((t) => `${t.details.name}`).join(', '),
|
10556
10660
|
}), errorNode);
|
10557
10661
|
}
|
10558
|
-
|
10662
|
+
const typeAlias = types_1.TypeBase.cloneForTypeAlias(type, name.value, ParseTreeUtils.getClassFullName(name, fileInfo.moduleName, name.value), typeAliasScopeId, isPep695Syntax, typeParameters.length > 0 ? typeParameters : undefined);
|
10663
|
+
// All PEP 695 type aliases are special forms because they are
|
10664
|
+
// TypeAliasType objects at runtime.
|
10665
|
+
if (isPep695Syntax) {
|
10666
|
+
typeAlias.flags |= 8 /* SpecialForm */;
|
10667
|
+
}
|
10668
|
+
return typeAlias;
|
10559
10669
|
}
|
10560
10670
|
function createSpecialBuiltInClass(node, assignedName, aliasMapEntry) {
|
10561
10671
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
@@ -10583,7 +10693,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10583
10693
|
// methods that are abstract are overridden and shouldn't
|
10584
10694
|
// cause the TypedDict to be marked as abstract.
|
10585
10695
|
if ((0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, '_TypedDict')) {
|
10586
|
-
baseClass.details.flags
|
10696
|
+
baseClass = types_1.ClassType.cloneWithNewFlags(baseClass, baseClass.details.flags &
|
10697
|
+
~(1024 /* SupportsAbstractMethods */ | 134217728 /* TypeCheckOnly */));
|
10587
10698
|
}
|
10588
10699
|
}
|
10589
10700
|
}
|
@@ -10701,7 +10812,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10701
10812
|
return undefined;
|
10702
10813
|
}
|
10703
10814
|
function evaluateTypesForAssignmentStatement(node) {
|
10704
|
-
var _a;
|
10815
|
+
var _a, _b;
|
10705
10816
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
10706
10817
|
// If the entire statement has already been evaluated, don't
|
10707
10818
|
// re-evaluate it.
|
@@ -10800,20 +10911,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10800
10911
|
srcType = types_1.ClassType.cloneWithLiteral(boolType, constExprValue);
|
10801
10912
|
}
|
10802
10913
|
}
|
10803
|
-
// If there was a declared type, make sure the RHS value is compatible.
|
10804
|
-
if (declaredType) {
|
10805
|
-
if (assignType(declaredType, srcType)) {
|
10806
|
-
// Narrow the resulting type if possible.
|
10807
|
-
if (!(0, types_1.isAnyOrUnknown)(srcType)) {
|
10808
|
-
srcType = narrowTypeBasedOnAssignment(node, declaredType, srcType);
|
10809
|
-
}
|
10810
|
-
}
|
10811
|
-
}
|
10812
10914
|
// If this is an enum, transform the type as required.
|
10813
10915
|
rightHandType = srcType;
|
10814
10916
|
if (node.leftExpression.nodeType === 38 /* Name */ && !node.typeAnnotationComment) {
|
10815
10917
|
rightHandType =
|
10816
|
-
(0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, node.leftExpression, () => rightHandType)
|
10918
|
+
(_a = (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, node.leftExpression, () => rightHandType)) !== null && _a !== void 0 ? _a : rightHandType;
|
10817
10919
|
}
|
10818
10920
|
if (typeAliasNameNode) {
|
10819
10921
|
// If this was a speculative type alias, it becomes a real type alias
|
@@ -10834,7 +10936,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10834
10936
|
typeAliasTypeVar.details.boundType = rightHandType;
|
10835
10937
|
// Record the type parameters within the recursive type alias so it
|
10836
10938
|
// can be specialized.
|
10837
|
-
typeAliasTypeVar.details.recursiveTypeParameters = (
|
10939
|
+
typeAliasTypeVar.details.recursiveTypeParameters = (_b = rightHandType.typeAliasInfo) === null || _b === void 0 ? void 0 : _b.typeParameters;
|
10838
10940
|
}
|
10839
10941
|
}
|
10840
10942
|
}
|
@@ -10998,447 +11100,465 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10998
11100
|
setSymbolResolutionPartialType(classSymbol, classDecl, classType);
|
10999
11101
|
}
|
11000
11102
|
classType.details.flags |= 131072 /* PartiallyEvaluated */;
|
11001
|
-
|
11002
|
-
|
11003
|
-
|
11004
|
-
|
11005
|
-
|
11006
|
-
|
11007
|
-
|
11008
|
-
|
11009
|
-
|
11010
|
-
|
11011
|
-
|
11012
|
-
|
11013
|
-
|
11014
|
-
|
11015
|
-
|
11016
|
-
|
11017
|
-
|
11018
|
-
|
11019
|
-
|
11020
|
-
|
11021
|
-
|
11022
|
-
|
11023
|
-
|
11024
|
-
|
11025
|
-
node.arguments.forEach((arg) => {
|
11026
|
-
// Ignore unpacked arguments.
|
11027
|
-
if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
|
11028
|
-
// Evaluate the expression's type so symbols are marked accessed
|
11029
|
-
// and errors are reported.
|
11030
|
-
getTypeOfExpression(arg.valueExpression);
|
11031
|
-
return;
|
11103
|
+
try {
|
11104
|
+
writeTypeCache(node, { type: classType }, /* flags */ undefined);
|
11105
|
+
writeTypeCache(node.name, { type: classType }, /* flags */ undefined);
|
11106
|
+
// Keep a list of unique type parameters that are used in the
|
11107
|
+
// base class arguments.
|
11108
|
+
let typeParameters = [];
|
11109
|
+
if (node.typeParameters) {
|
11110
|
+
typeParameters = evaluateTypeParameterList(node.typeParameters).map((t) => types_1.TypeVarType.cloneAsInstance(t));
|
11111
|
+
}
|
11112
|
+
// If the class derives from "Generic" directly, it will provide
|
11113
|
+
// all of the type parameters in the specified order.
|
11114
|
+
let genericTypeParameters;
|
11115
|
+
let protocolTypeParameters;
|
11116
|
+
const initSubclassArgs = [];
|
11117
|
+
let metaclassNode;
|
11118
|
+
let exprFlags = 128 /* ExpectingInstantiableType */ |
|
11119
|
+
1024 /* AllowGenericClassType */ |
|
11120
|
+
262144 /* DisallowNakedGeneric */ |
|
11121
|
+
2048 /* DisallowTypeVarsWithScopeId */ |
|
11122
|
+
8192 /* AssociateTypeVarsWithCurrentScope */ |
|
11123
|
+
16384 /* EnforceTypeVarVarianceConsistency */ |
|
11124
|
+
16777216 /* DisallowPep695TypeAlias */;
|
11125
|
+
if (fileInfo.isStubFile) {
|
11126
|
+
exprFlags |= 4 /* AllowForwardReferences */;
|
11032
11127
|
}
|
11033
|
-
|
11034
|
-
|
11035
|
-
if (arg.argumentCategory ===
|
11128
|
+
node.arguments.forEach((arg) => {
|
11129
|
+
// Ignore unpacked arguments.
|
11130
|
+
if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
|
11131
|
+
// Evaluate the expression's type so symbols are marked accessed
|
11132
|
+
// and errors are reported.
|
11036
11133
|
getTypeOfExpression(arg.valueExpression);
|
11037
|
-
|
11134
|
+
return;
|
11038
11135
|
}
|
11039
|
-
|
11040
|
-
argType
|
11041
|
-
|
11042
|
-
|
11043
|
-
// on platform type). We'll assume that the conditional logic is correct
|
11044
|
-
// and strip off the "unbound" union.
|
11045
|
-
if ((0, types_1.isUnion)(argType)) {
|
11046
|
-
argType = (0, types_1.removeUnbound)(argType);
|
11047
|
-
}
|
11048
|
-
if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
|
11049
|
-
if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
|
11050
|
-
(0, debug_1.assert)((0, types_1.isClassInstance)(argType));
|
11051
|
-
argType =
|
11052
|
-
argType.typeArguments && argType.typeArguments.length > 0
|
11053
|
-
? argType.typeArguments[0]
|
11054
|
-
: types_1.UnknownType.create();
|
11055
|
-
}
|
11056
|
-
else if (!(0, types_1.isInstantiableClass)(argType)) {
|
11057
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
|
11136
|
+
if (!arg.name) {
|
11137
|
+
let argType;
|
11138
|
+
if (arg.argumentCategory === 1 /* UnpackedList */) {
|
11139
|
+
getTypeOfExpression(arg.valueExpression);
|
11058
11140
|
argType = types_1.UnknownType.create();
|
11059
11141
|
}
|
11060
11142
|
else {
|
11061
|
-
|
11062
|
-
|
11063
|
-
|
11064
|
-
|
11065
|
-
|
11066
|
-
|
11143
|
+
argType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(arg.valueExpression, exprFlags).type);
|
11144
|
+
}
|
11145
|
+
// In some stub files, classes are conditionally defined (e.g. based
|
11146
|
+
// on platform type). We'll assume that the conditional logic is correct
|
11147
|
+
// and strip off the "unbound" union.
|
11148
|
+
if ((0, types_1.isUnion)(argType)) {
|
11149
|
+
argType = (0, types_1.removeUnbound)(argType);
|
11150
|
+
}
|
11151
|
+
if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
|
11152
|
+
if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
|
11153
|
+
(0, debug_1.assert)((0, types_1.isClassInstance)(argType));
|
11154
|
+
argType =
|
11155
|
+
argType.typeArguments && argType.typeArguments.length > 0
|
11156
|
+
? argType.typeArguments[0]
|
11157
|
+
: types_1.UnknownType.create();
|
11067
11158
|
}
|
11068
|
-
if (types_1.
|
11069
|
-
|
11070
|
-
|
11071
|
-
|
11072
|
-
|
11159
|
+
else if (!(0, types_1.isInstantiableClass)(argType)) {
|
11160
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.baseClassInvalid(), arg);
|
11161
|
+
argType = types_1.UnknownType.create();
|
11162
|
+
}
|
11163
|
+
else {
|
11164
|
+
if (types_1.ClassType.isPartiallyEvaluated(argType) ||
|
11165
|
+
argType.details.mro.some((t) => (0, types_1.isClass)(t) && types_1.ClassType.isPartiallyEvaluated(t))) {
|
11166
|
+
// If the base class is partially evaluated, install a callback
|
11167
|
+
// so we can fix up this class (e.g. compute the MRO) when the
|
11168
|
+
// dependent class is completed.
|
11169
|
+
registerDeferredClassCompletion(node, argType);
|
11170
|
+
}
|
11171
|
+
if (types_1.ClassType.isBuiltIn(argType, 'Protocol')) {
|
11172
|
+
if (!fileInfo.isStubFile &&
|
11173
|
+
!types_1.ClassType.isTypingExtensionClass(argType) &&
|
11174
|
+
fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_7) {
|
11175
|
+
addError(localize_1.Localizer.Diagnostic.protocolIllegal(), arg.valueExpression);
|
11176
|
+
}
|
11177
|
+
classType.details.flags |= 8192 /* ProtocolClass */;
|
11178
|
+
}
|
11179
|
+
if (types_1.ClassType.isBuiltIn(argType, 'property')) {
|
11180
|
+
classType.details.flags |= 2048 /* PropertyClass */;
|
11181
|
+
}
|
11182
|
+
// If the class directly derives from NamedTuple (in Python 3.6 or
|
11183
|
+
// newer), it's considered a (read-only) dataclass.
|
11184
|
+
if (fileInfo.executionEnvironment.pythonVersion >= pythonVersion_1.PythonVersion.V3_6) {
|
11185
|
+
if (types_1.ClassType.isBuiltIn(argType, 'NamedTuple')) {
|
11186
|
+
classType.details.flags |=
|
11187
|
+
4 /* DataClass */ |
|
11188
|
+
32 /* SkipSynthesizedDataClassEq */ |
|
11189
|
+
16777216 /* ReadOnlyInstanceVariables */;
|
11190
|
+
}
|
11191
|
+
}
|
11192
|
+
// If the class directly derives from TypedDict or from a class that is
|
11193
|
+
// a TypedDict, it is considered a TypedDict.
|
11194
|
+
if (types_1.ClassType.isBuiltIn(argType, 'TypedDict') || types_1.ClassType.isTypedDictClass(argType)) {
|
11195
|
+
classType.details.flags |= 128 /* TypedDictClass */;
|
11196
|
+
}
|
11197
|
+
else if (types_1.ClassType.isTypedDictClass(classType) && !types_1.ClassType.isTypedDictClass(argType)) {
|
11198
|
+
// Exempt Generic from this test. As of Python 3.11, generic TypedDict
|
11199
|
+
// classes are supported.
|
11200
|
+
if (!(0, types_1.isInstantiableClass)(argType) || !types_1.ClassType.isBuiltIn(argType, 'Generic')) {
|
11201
|
+
// TypedDict classes must derive only from other TypedDict classes.
|
11202
|
+
addError(localize_1.Localizer.Diagnostic.typedDictBaseClass(), arg);
|
11203
|
+
}
|
11204
|
+
}
|
11205
|
+
// Validate that the class isn't deriving from itself, creating a
|
11206
|
+
// circular dependency.
|
11207
|
+
if ((0, typeUtils_1.derivesFromClassRecursive)(argType, classType, /* ignoreUnknown */ true)) {
|
11208
|
+
addError(localize_1.Localizer.Diagnostic.baseClassCircular(), arg);
|
11209
|
+
argType = types_1.UnknownType.create();
|
11073
11210
|
}
|
11074
|
-
classType.details.flags |= 8192 /* ProtocolClass */;
|
11075
11211
|
}
|
11076
|
-
|
11077
|
-
|
11212
|
+
}
|
11213
|
+
if ((0, types_1.isUnknown)(argType)) {
|
11214
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedBaseClass, diagnosticRules_1.DiagnosticRule.reportUntypedBaseClass, localize_1.Localizer.Diagnostic.baseClassUnknown(), arg);
|
11215
|
+
}
|
11216
|
+
// Check for a duplicate class.
|
11217
|
+
if (classType.details.baseClasses.some((prevBaseClass) => {
|
11218
|
+
return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
|
11219
|
+
(0, types_1.isInstantiableClass)(argType) &&
|
11220
|
+
types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
|
11221
|
+
})) {
|
11222
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
|
11223
|
+
}
|
11224
|
+
classType.details.baseClasses.push(argType);
|
11225
|
+
if ((0, types_1.isInstantiableClass)(argType)) {
|
11226
|
+
if (types_1.ClassType.isEnumClass(argType)) {
|
11227
|
+
classType.details.flags |= 1048576 /* EnumClass */;
|
11078
11228
|
}
|
11079
|
-
//
|
11080
|
-
//
|
11081
|
-
|
11082
|
-
|
11083
|
-
|
11084
|
-
|
11085
|
-
|
11086
|
-
|
11087
|
-
|
11229
|
+
// Determine if the class is abstract. Protocol classes support abstract methods
|
11230
|
+
// even though they don't derive from the ABCMeta class. We'll exclude built-in
|
11231
|
+
// protocol classes because these are known not to contain any abstract methods
|
11232
|
+
// and getAbstractMethods causes problems because of dependencies on some of these
|
11233
|
+
// built-in protocol classes.
|
11234
|
+
if (types_1.ClassType.supportsAbstractMethods(argType) ||
|
11235
|
+
(types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
|
11236
|
+
classType.details.flags |= 1024 /* SupportsAbstractMethods */;
|
11237
|
+
}
|
11238
|
+
if (types_1.ClassType.isPropertyClass(argType)) {
|
11239
|
+
classType.details.flags |= 2048 /* PropertyClass */;
|
11088
11240
|
}
|
11089
|
-
|
11090
|
-
|
11091
|
-
|
11092
|
-
classType.details.flags |= 128 /* TypedDictClass */;
|
11241
|
+
if (types_1.ClassType.isFinal(argType)) {
|
11242
|
+
const className = printObjectTypeForClass(argType);
|
11243
|
+
addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
|
11093
11244
|
}
|
11094
|
-
|
11095
|
-
|
11096
|
-
|
11097
|
-
|
11098
|
-
|
11099
|
-
|
11245
|
+
}
|
11246
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
11247
|
+
if ((0, types_1.isInstantiableClass)(argType)) {
|
11248
|
+
if (types_1.ClassType.isBuiltIn(argType, 'Generic')) {
|
11249
|
+
// 'Generic' is implicitly added if type parameter syntax is used.
|
11250
|
+
if (node.typeParameters) {
|
11251
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.genericBaseClassNotAllowed(), arg.valueExpression);
|
11252
|
+
}
|
11253
|
+
else {
|
11254
|
+
if (!genericTypeParameters) {
|
11255
|
+
if (protocolTypeParameters) {
|
11256
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
|
11257
|
+
}
|
11258
|
+
genericTypeParameters = [];
|
11259
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
11260
|
+
}
|
11100
11261
|
}
|
11101
11262
|
}
|
11102
|
-
|
11103
|
-
|
11104
|
-
|
11105
|
-
|
11106
|
-
|
11263
|
+
else if (types_1.ClassType.isBuiltIn(argType, 'Protocol') &&
|
11264
|
+
argType.typeArguments &&
|
11265
|
+
argType.typeArguments.length > 0) {
|
11266
|
+
if (!protocolTypeParameters) {
|
11267
|
+
if (genericTypeParameters) {
|
11268
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
|
11269
|
+
}
|
11270
|
+
protocolTypeParameters = [];
|
11271
|
+
(0, typeUtils_1.addTypeVarsToListIfUnique)(protocolTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
11272
|
+
if (node.typeParameters && protocolTypeParameters.length > 0) {
|
11273
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.protocolBaseClassWithTypeArgs(), arg.valueExpression);
|
11274
|
+
protocolTypeParameters = [];
|
11275
|
+
}
|
11276
|
+
}
|
11107
11277
|
}
|
11108
11278
|
}
|
11109
11279
|
}
|
11110
|
-
if (
|
11111
|
-
|
11112
|
-
|
11113
|
-
|
11114
|
-
|
11115
|
-
|
11116
|
-
(0, types_1.isInstantiableClass)(argType) &&
|
11117
|
-
types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
|
11118
|
-
})) {
|
11119
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
|
11120
|
-
}
|
11121
|
-
classType.details.baseClasses.push(argType);
|
11122
|
-
if ((0, types_1.isInstantiableClass)(argType)) {
|
11123
|
-
if (types_1.ClassType.isEnumClass(argType)) {
|
11124
|
-
classType.details.flags |= 1048576 /* EnumClass */;
|
11280
|
+
else if (arg.name.value === 'metaclass') {
|
11281
|
+
if (metaclassNode) {
|
11282
|
+
addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
|
11283
|
+
}
|
11284
|
+
else {
|
11285
|
+
metaclassNode = arg.valueExpression;
|
11125
11286
|
}
|
11126
|
-
|
11127
|
-
|
11128
|
-
|
11129
|
-
//
|
11130
|
-
//
|
11131
|
-
|
11132
|
-
|
11133
|
-
|
11287
|
+
}
|
11288
|
+
else if (types_1.ClassType.isTypedDictClass(classType) &&
|
11289
|
+
(arg.name.value === 'total' || arg.name.value === 'readonly')) {
|
11290
|
+
// The "total" and "readonly" parameters apply only for TypedDict classes.
|
11291
|
+
// PEP 589 specifies that the parameter must be either True or False.
|
11292
|
+
const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
|
11293
|
+
if (constArgValue === undefined) {
|
11294
|
+
addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
|
11134
11295
|
}
|
11135
|
-
if (
|
11136
|
-
classType.details.flags |=
|
11296
|
+
else if (arg.name.value === 'total' && !constArgValue) {
|
11297
|
+
classType.details.flags |= 256 /* CanOmitDictValues */;
|
11137
11298
|
}
|
11138
|
-
if (
|
11139
|
-
|
11140
|
-
addError(localize_1.Localizer.Diagnostic.baseClassFinal().format({ type: className }), arg.valueExpression);
|
11299
|
+
else if (arg.name.value === 'readonly' && constArgValue) {
|
11300
|
+
classType.details.flags |= 512 /* DictValuesReadOnly */;
|
11141
11301
|
}
|
11142
11302
|
}
|
11143
|
-
|
11144
|
-
|
11145
|
-
|
11146
|
-
|
11147
|
-
|
11148
|
-
|
11303
|
+
else {
|
11304
|
+
// Collect arguments that will be passed to the `__init_subclass__`
|
11305
|
+
// method described in PEP 487.
|
11306
|
+
initSubclassArgs.push({
|
11307
|
+
argumentCategory: 0 /* Simple */,
|
11308
|
+
node: arg,
|
11309
|
+
name: arg.name,
|
11310
|
+
valueExpression: arg.valueExpression,
|
11311
|
+
});
|
11312
|
+
}
|
11313
|
+
});
|
11314
|
+
// Check for NamedTuple multiple inheritance.
|
11315
|
+
if (classType.details.baseClasses.length > 1) {
|
11316
|
+
let derivesFromNamedTuple = false;
|
11317
|
+
let foundIllegalBaseClass = false;
|
11318
|
+
classType.details.baseClasses.forEach((baseClass) => {
|
11319
|
+
if ((0, types_1.isInstantiableClass)(baseClass)) {
|
11320
|
+
if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
|
11321
|
+
derivesFromNamedTuple = true;
|
11149
11322
|
}
|
11150
|
-
else {
|
11151
|
-
|
11152
|
-
if (protocolTypeParameters) {
|
11153
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
|
11154
|
-
}
|
11155
|
-
genericTypeParameters = [];
|
11156
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
11157
|
-
}
|
11323
|
+
else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
|
11324
|
+
foundIllegalBaseClass = true;
|
11158
11325
|
}
|
11159
11326
|
}
|
11160
|
-
|
11161
|
-
|
11162
|
-
|
11163
|
-
|
11164
|
-
|
11165
|
-
|
11166
|
-
|
11167
|
-
|
11168
|
-
|
11169
|
-
|
11170
|
-
|
11171
|
-
|
11327
|
+
});
|
11328
|
+
if (derivesFromNamedTuple && foundIllegalBaseClass) {
|
11329
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.namedTupleMultipleInheritance(), node.name);
|
11330
|
+
}
|
11331
|
+
}
|
11332
|
+
// Make sure we don't have 'object' derive from itself. Infinite
|
11333
|
+
// recursion will result.
|
11334
|
+
if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
|
11335
|
+
classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
|
11336
|
+
// If there are no other (known) base classes, the class implicitly derives from object.
|
11337
|
+
classType.details.baseClasses.push(getBuiltInType(node, 'object'));
|
11338
|
+
}
|
11339
|
+
// If genericTypeParameters or protocolTypeParameters are provided,
|
11340
|
+
// make sure that typeParameters is a proper subset.
|
11341
|
+
genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
|
11342
|
+
if (genericTypeParameters && !node.typeParameters) {
|
11343
|
+
verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
|
11344
|
+
}
|
11345
|
+
classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
|
11346
|
+
// Determine if one or more type parameters is autovariance.
|
11347
|
+
if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
|
11348
|
+
classType.details.requiresVarianceInference = true;
|
11349
|
+
}
|
11350
|
+
// Make sure there's at most one variadic type parameter.
|
11351
|
+
const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
11352
|
+
if (variadics.length > 1) {
|
11353
|
+
addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
|
11354
|
+
names: variadics.map((v) => `"${v.details.name}"`).join(', '),
|
11355
|
+
}), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
|
11356
|
+
}
|
11357
|
+
// Validate the default types for all type parameters.
|
11358
|
+
classType.details.typeParameters.forEach((typeParam, index) => {
|
11359
|
+
var _a;
|
11360
|
+
let bestErrorNode = node.name;
|
11361
|
+
if (node.typeParameters && index < node.typeParameters.parameters.length) {
|
11362
|
+
const typeParamNode = node.typeParameters.parameters[index];
|
11363
|
+
bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
|
11364
|
+
}
|
11365
|
+
validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
|
11366
|
+
});
|
11367
|
+
if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
|
11368
|
+
addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
|
11369
|
+
}
|
11370
|
+
// The scope for this class becomes the "fields" for the corresponding type.
|
11371
|
+
const innerScope = ScopeUtils.getScopeForNode(node.suite);
|
11372
|
+
classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
|
11373
|
+
? new Map(innerScope.symbolTable)
|
11374
|
+
: new Map();
|
11375
|
+
// Determine whether the class should inherit __hash__. If a class defines
|
11376
|
+
// __eq__ but doesn't define __hash__ then __hash__ is set to None.
|
11377
|
+
if (classType.details.fields.has('__eq__') && !classType.details.fields.has('__hash__')) {
|
11378
|
+
classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ |
|
11379
|
+
128 /* ClassVar */ |
|
11380
|
+
64 /* IgnoredForProtocolMatch */ |
|
11381
|
+
4096 /* IgnoredForOverrideChecks */, types_1.NoneType.createInstance()));
|
11382
|
+
}
|
11383
|
+
// Determine whether the class's instance variables are constrained
|
11384
|
+
// to those defined by __slots__. We need to do this prior to dataclass
|
11385
|
+
// processing because dataclasses can implicitly add to the slots
|
11386
|
+
// list.
|
11387
|
+
const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
|
11388
|
+
if (slotsNames) {
|
11389
|
+
classType.details.localSlotsNames = slotsNames;
|
11390
|
+
}
|
11391
|
+
// Determine if the class should be a "pseudo-generic" class, characterized
|
11392
|
+
// by having an __init__ method with parameters that lack type annotations.
|
11393
|
+
// For such classes, we'll treat them as generic, with the type arguments provided
|
11394
|
+
// by the callers of the constructor.
|
11395
|
+
if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
|
11396
|
+
const initMethod = classType.details.fields.get('__init__');
|
11397
|
+
if (initMethod) {
|
11398
|
+
const initDecls = initMethod.getTypedDeclarations();
|
11399
|
+
if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
|
11400
|
+
const initDeclNode = initDecls[0].node;
|
11401
|
+
const initParams = initDeclNode.parameters;
|
11402
|
+
if (initParams.length > 1 &&
|
11403
|
+
!initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
|
11404
|
+
const genericParams = initParams.filter((param, index) => index > 0 &&
|
11405
|
+
param.name &&
|
11406
|
+
param.category === 0 /* Simple */ &&
|
11407
|
+
!param.defaultValue);
|
11408
|
+
if (genericParams.length > 0) {
|
11409
|
+
classType.details.flags |= 16384 /* PseudoGenericClass */;
|
11410
|
+
// Create a type parameter for each simple, named parameter
|
11411
|
+
// in the __init__ method.
|
11412
|
+
classType.details.typeParameters = genericParams.map((param) => {
|
11413
|
+
const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
|
11414
|
+
typeVar.details.isSynthesized = true;
|
11415
|
+
typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
|
11416
|
+
typeVar.details.boundType = types_1.UnknownType.create();
|
11417
|
+
return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
11418
|
+
});
|
11172
11419
|
}
|
11173
11420
|
}
|
11174
11421
|
}
|
11175
11422
|
}
|
11176
11423
|
}
|
11177
|
-
|
11178
|
-
|
11179
|
-
|
11180
|
-
|
11181
|
-
|
11182
|
-
|
11183
|
-
|
11184
|
-
}
|
11185
|
-
else if (types_1.ClassType.isTypedDictClass(classType) &&
|
11186
|
-
(arg.name.value === 'total' || arg.name.value === 'readonly')) {
|
11187
|
-
// The "total" and "readonly" parameters apply only for TypedDict classes.
|
11188
|
-
// PEP 589 specifies that the parameter must be either True or False.
|
11189
|
-
const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
|
11190
|
-
if (constArgValue === undefined) {
|
11191
|
-
addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
|
11424
|
+
// Determine if the class has a custom __class_getitem__ method. This applies
|
11425
|
+
// only to classes that have no type parameters, since those with type parameters
|
11426
|
+
// are assumed to follow normal subscripting semantics for generic classes.
|
11427
|
+
if (classType.details.typeParameters.length === 0 && !types_1.ClassType.isBuiltIn(classType, 'type')) {
|
11428
|
+
if (classType.details.baseClasses.some((baseClass) => (0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.hasCustomClassGetItem(baseClass)) ||
|
11429
|
+
classType.details.fields.has('__class_getitem__')) {
|
11430
|
+
classType.details.flags |= 262144 /* HasCustomClassGetItem */;
|
11192
11431
|
}
|
11193
|
-
else if (arg.name.value === 'total' && !constArgValue) {
|
11194
|
-
classType.details.flags |= 256 /* CanOmitDictValues */;
|
11195
|
-
}
|
11196
|
-
else if (arg.name.value === 'readonly' && constArgValue) {
|
11197
|
-
classType.details.flags |= 512 /* DictValuesReadOnly */;
|
11198
|
-
}
|
11199
|
-
}
|
11200
|
-
else {
|
11201
|
-
// Collect arguments that will be passed to the `__init_subclass__`
|
11202
|
-
// method described in PEP 487.
|
11203
|
-
initSubclassArgs.push({
|
11204
|
-
argumentCategory: 0 /* Simple */,
|
11205
|
-
node: arg,
|
11206
|
-
name: arg.name,
|
11207
|
-
valueExpression: arg.valueExpression,
|
11208
|
-
});
|
11209
11432
|
}
|
11210
|
-
|
11211
|
-
|
11212
|
-
|
11213
|
-
|
11214
|
-
|
11215
|
-
|
11216
|
-
if ((0, types_1.isInstantiableClass)(baseClass)) {
|
11217
|
-
if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
|
11218
|
-
derivesFromNamedTuple = true;
|
11433
|
+
// Determine the effective metaclass.
|
11434
|
+
if (metaclassNode) {
|
11435
|
+
const metaclassType = getTypeOfExpression(metaclassNode, exprFlags).type;
|
11436
|
+
if ((0, types_1.isInstantiableClass)(metaclassType) || (0, types_1.isUnknown)(metaclassType)) {
|
11437
|
+
if ((0, typeUtils_1.requiresSpecialization)(metaclassType, /* ignorePseudoGeneric */ true)) {
|
11438
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
|
11219
11439
|
}
|
11220
|
-
|
11221
|
-
|
11222
|
-
|
11223
|
-
|
11224
|
-
|
11225
|
-
|
11226
|
-
|
11227
|
-
}
|
11228
|
-
}
|
11229
|
-
// Make sure we don't have 'object' derive from itself. Infinite
|
11230
|
-
// recursion will result.
|
11231
|
-
if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
|
11232
|
-
classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
|
11233
|
-
// If there are no other (known) base classes, the class implicitly derives from object.
|
11234
|
-
classType.details.baseClasses.push(getBuiltInType(node, 'object'));
|
11235
|
-
}
|
11236
|
-
// If genericTypeParameters or protocolTypeParameters are provided,
|
11237
|
-
// make sure that typeParameters is a proper subset.
|
11238
|
-
genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
|
11239
|
-
if (genericTypeParameters && !node.typeParameters) {
|
11240
|
-
verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
|
11241
|
-
}
|
11242
|
-
classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
|
11243
|
-
// Determine if one or more type parameters is autovariance.
|
11244
|
-
if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
|
11245
|
-
classType.details.requiresVarianceInference = true;
|
11246
|
-
}
|
11247
|
-
// Make sure there's at most one variadic type parameter.
|
11248
|
-
const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
11249
|
-
if (variadics.length > 1) {
|
11250
|
-
addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
|
11251
|
-
names: variadics.map((v) => `"${v.details.name}"`).join(', '),
|
11252
|
-
}), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
|
11253
|
-
}
|
11254
|
-
// Validate the default types for all type parameters.
|
11255
|
-
classType.details.typeParameters.forEach((typeParam, index) => {
|
11256
|
-
var _a;
|
11257
|
-
let bestErrorNode = node.name;
|
11258
|
-
if (node.typeParameters && index < node.typeParameters.parameters.length) {
|
11259
|
-
const typeParamNode = node.typeParameters.parameters[index];
|
11260
|
-
bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
|
11261
|
-
}
|
11262
|
-
validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
|
11263
|
-
});
|
11264
|
-
if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
|
11265
|
-
addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
|
11266
|
-
}
|
11267
|
-
// The scope for this class becomes the "fields" for the corresponding type.
|
11268
|
-
const innerScope = ScopeUtils.getScopeForNode(node.suite);
|
11269
|
-
classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
|
11270
|
-
? new Map(innerScope.symbolTable)
|
11271
|
-
: new Map();
|
11272
|
-
// Determine whether the class's instance variables are constrained
|
11273
|
-
// to those defined by __slots__. We need to do this prior to dataclass
|
11274
|
-
// processing because dataclasses can implicitly add to the slots
|
11275
|
-
// list.
|
11276
|
-
const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
|
11277
|
-
if (slotsNames) {
|
11278
|
-
classType.details.localSlotsNames = slotsNames;
|
11279
|
-
}
|
11280
|
-
// Determine if the class should be a "pseudo-generic" class, characterized
|
11281
|
-
// by having an __init__ method with parameters that lack type annotations.
|
11282
|
-
// For such classes, we'll treat them as generic, with the type arguments provided
|
11283
|
-
// by the callers of the constructor.
|
11284
|
-
if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
|
11285
|
-
const initMethod = classType.details.fields.get('__init__');
|
11286
|
-
if (initMethod) {
|
11287
|
-
const initDecls = initMethod.getTypedDeclarations();
|
11288
|
-
if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
|
11289
|
-
const initDeclNode = initDecls[0].node;
|
11290
|
-
const initParams = initDeclNode.parameters;
|
11291
|
-
if (initParams.length > 1 &&
|
11292
|
-
!initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
|
11293
|
-
const genericParams = initParams.filter((param, index) => index > 0 &&
|
11294
|
-
param.name &&
|
11295
|
-
param.category === 0 /* Simple */ &&
|
11296
|
-
!param.defaultValue);
|
11297
|
-
if (genericParams.length > 0) {
|
11298
|
-
classType.details.flags |= 16384 /* PseudoGenericClass */;
|
11299
|
-
// Create a type parameter for each simple, named parameter
|
11300
|
-
// in the __init__ method.
|
11301
|
-
classType.details.typeParameters = genericParams.map((param) => {
|
11302
|
-
const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
|
11303
|
-
typeVar.details.isSynthesized = true;
|
11304
|
-
typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
|
11305
|
-
typeVar.details.boundType = types_1.UnknownType.create();
|
11306
|
-
return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
11307
|
-
});
|
11440
|
+
classType.details.declaredMetaclass = metaclassType;
|
11441
|
+
if ((0, types_1.isInstantiableClass)(metaclassType)) {
|
11442
|
+
if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
|
11443
|
+
classType.details.flags |= 1048576 /* EnumClass */;
|
11444
|
+
}
|
11445
|
+
else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
|
11446
|
+
classType.details.flags |= 1024 /* SupportsAbstractMethods */;
|
11308
11447
|
}
|
11309
11448
|
}
|
11310
11449
|
}
|
11311
11450
|
}
|
11312
|
-
|
11313
|
-
|
11314
|
-
|
11315
|
-
|
11316
|
-
|
11317
|
-
|
11318
|
-
|
11319
|
-
|
11320
|
-
|
11321
|
-
|
11322
|
-
|
11323
|
-
|
11324
|
-
|
11325
|
-
|
11326
|
-
|
11327
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
|
11328
|
-
}
|
11329
|
-
classType.details.declaredMetaclass = metaclassType;
|
11330
|
-
if ((0, types_1.isInstantiableClass)(metaclassType)) {
|
11331
|
-
if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
|
11332
|
-
classType.details.flags |= 1048576 /* EnumClass */;
|
11333
|
-
}
|
11334
|
-
else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
|
11335
|
-
classType.details.flags |= 1024 /* SupportsAbstractMethods */;
|
11451
|
+
const effectiveMetaclass = computeEffectiveMetaclass(classType, node.name);
|
11452
|
+
// Clear the "partially constructed" flag.
|
11453
|
+
classType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
11454
|
+
// Now determine the decorated type of the class.
|
11455
|
+
let decoratedType = classType;
|
11456
|
+
let foundUnknown = false;
|
11457
|
+
for (let i = node.decorators.length - 1; i >= 0; i--) {
|
11458
|
+
const decorator = node.decorators[i];
|
11459
|
+
const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
|
11460
|
+
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
11461
|
+
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
11462
|
+
// Report this error only on the first unknown type.
|
11463
|
+
if (!foundUnknown) {
|
11464
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
|
11465
|
+
foundUnknown = true;
|
11336
11466
|
}
|
11337
11467
|
}
|
11338
|
-
|
11339
|
-
|
11340
|
-
|
11341
|
-
// Clear the "partially constructed" flag.
|
11342
|
-
classType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
11343
|
-
// Now determine the decorated type of the class.
|
11344
|
-
let decoratedType = classType;
|
11345
|
-
let foundUnknown = false;
|
11346
|
-
for (let i = node.decorators.length - 1; i >= 0; i--) {
|
11347
|
-
const decorator = node.decorators[i];
|
11348
|
-
const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
|
11349
|
-
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
11350
|
-
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
11351
|
-
// Report this error only on the first unknown type.
|
11352
|
-
if (!foundUnknown) {
|
11353
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
|
11354
|
-
foundUnknown = true;
|
11468
|
+
else {
|
11469
|
+
// Apply the decorator only if the type is known.
|
11470
|
+
decoratedType = newDecoratedType;
|
11355
11471
|
}
|
11356
11472
|
}
|
11357
|
-
|
11358
|
-
|
11359
|
-
|
11473
|
+
// Determine whether this class derives from (or has a metaclass) that imbues
|
11474
|
+
// it with dataclass-like behaviors. If so, we'll apply those here.
|
11475
|
+
let dataClassBehaviors;
|
11476
|
+
if ((0, types_1.isInstantiableClass)(effectiveMetaclass) && effectiveMetaclass.details.classDataClassTransform) {
|
11477
|
+
dataClassBehaviors = effectiveMetaclass.details.classDataClassTransform;
|
11360
11478
|
}
|
11361
|
-
|
11362
|
-
|
11363
|
-
|
11364
|
-
|
11365
|
-
|
11366
|
-
|
11367
|
-
|
11368
|
-
|
11369
|
-
|
11370
|
-
|
11371
|
-
|
11372
|
-
|
11373
|
-
|
11374
|
-
|
11375
|
-
|
11376
|
-
|
11377
|
-
|
11378
|
-
|
11379
|
-
|
11380
|
-
(
|
11381
|
-
|
11382
|
-
|
11383
|
-
|
11384
|
-
|
11385
|
-
|
11386
|
-
|
11387
|
-
|
11388
|
-
|
11389
|
-
|
11390
|
-
|
11391
|
-
|
11392
|
-
|
11393
|
-
|
11394
|
-
|
11395
|
-
|
11396
|
-
|
11397
|
-
|
11398
|
-
|
11399
|
-
|
11400
|
-
|
11401
|
-
|
11402
|
-
|
11403
|
-
}
|
11404
|
-
|
11405
|
-
|
11406
|
-
if (
|
11407
|
-
|
11408
|
-
|
11409
|
-
|
11410
|
-
|
11411
|
-
|
11412
|
-
|
11413
|
-
|
11414
|
-
|
11415
|
-
|
11416
|
-
|
11417
|
-
|
11418
|
-
|
11419
|
-
|
11420
|
-
!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
|
11421
|
-
if (baseClass.details.inheritedSlotsNames === undefined) {
|
11422
|
-
isLimitedToSlots = false;
|
11423
|
-
}
|
11424
|
-
else {
|
11425
|
-
(0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
|
11479
|
+
else {
|
11480
|
+
const baseClassDataTransform = classType.details.mro.find((mroClass) => {
|
11481
|
+
return ((0, types_1.isClass)(mroClass) &&
|
11482
|
+
mroClass.details.classDataClassTransform !== undefined &&
|
11483
|
+
!types_1.ClassType.isSameGenericClass(mroClass, classType));
|
11484
|
+
});
|
11485
|
+
if (baseClassDataTransform) {
|
11486
|
+
dataClassBehaviors = baseClassDataTransform.details.classDataClassTransform;
|
11487
|
+
}
|
11488
|
+
}
|
11489
|
+
if (dataClassBehaviors) {
|
11490
|
+
(0, dataClasses_1.applyDataClassDefaultBehaviors)(classType, dataClassBehaviors);
|
11491
|
+
(0, dataClasses_1.applyDataClassClassBehaviorOverrides)(evaluatorInterface, node.name, classType, initSubclassArgs, dataClassBehaviors);
|
11492
|
+
}
|
11493
|
+
// Run any deferred class completions that depend on this class.
|
11494
|
+
runDeferredClassCompletions(classType);
|
11495
|
+
// If there are any outstanding deferred class completions registered that
|
11496
|
+
// were not removed by the call to runDeferredClassCompletions, assume that
|
11497
|
+
// the current class may depend on them and register for deferred completion.
|
11498
|
+
registerDeferredClassCompletion(node, /* dependsUpon */ undefined);
|
11499
|
+
// Synthesize TypedDict methods.
|
11500
|
+
if (types_1.ClassType.isTypedDictClass(classType)) {
|
11501
|
+
(0, typedDicts_1.synthesizeTypedDictClassMethods)(evaluatorInterface, node, classType, (0, types_1.isClass)(decoratedType) && types_1.ClassType.isFinal(decoratedType));
|
11502
|
+
}
|
11503
|
+
// Synthesize dataclass methods.
|
11504
|
+
if (types_1.ClassType.isDataClass(classType)) {
|
11505
|
+
const skipSynthesizedInit = types_1.ClassType.isSkipSynthesizedDataClassInit(classType);
|
11506
|
+
let hasExistingInitMethod = skipSynthesizedInit;
|
11507
|
+
// See if there's already a non-synthesized __init__ method.
|
11508
|
+
// We shouldn't override it.
|
11509
|
+
if (!skipSynthesizedInit) {
|
11510
|
+
const initSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__init__', 2 /* SkipBaseClasses */);
|
11511
|
+
if (initSymbol) {
|
11512
|
+
hasExistingInitMethod = true;
|
11513
|
+
}
|
11514
|
+
}
|
11515
|
+
let skipSynthesizeHash = false;
|
11516
|
+
const hashSymbol = (0, typeUtils_1.lookUpClassMember)(classType, '__hash__', 2 /* SkipBaseClasses */);
|
11517
|
+
if (hashSymbol) {
|
11518
|
+
skipSynthesizeHash = true;
|
11519
|
+
}
|
11520
|
+
(0, dataClasses_1.synthesizeDataClassMethods)(evaluatorInterface, node, classType, skipSynthesizedInit, hasExistingInitMethod, skipSynthesizeHash);
|
11521
|
+
}
|
11522
|
+
// Build a complete list of all slots names defined by the class hierarchy.
|
11523
|
+
// This needs to be done after dataclass processing.
|
11524
|
+
if (classType.details.localSlotsNames) {
|
11525
|
+
let isLimitedToSlots = true;
|
11526
|
+
const extendedSlotsNames = Array.from(classType.details.localSlotsNames);
|
11527
|
+
classType.details.baseClasses.forEach((baseClass) => {
|
11528
|
+
if ((0, types_1.isInstantiableClass)(baseClass)) {
|
11529
|
+
if (!types_1.ClassType.isBuiltIn(baseClass, 'object') &&
|
11530
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'type') &&
|
11531
|
+
!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
|
11532
|
+
if (baseClass.details.inheritedSlotsNames === undefined) {
|
11533
|
+
isLimitedToSlots = false;
|
11534
|
+
}
|
11535
|
+
else {
|
11536
|
+
(0, collectionUtils_1.appendArray)(extendedSlotsNames, baseClass.details.inheritedSlotsNames);
|
11537
|
+
}
|
11426
11538
|
}
|
11427
11539
|
}
|
11540
|
+
else {
|
11541
|
+
isLimitedToSlots = false;
|
11542
|
+
}
|
11543
|
+
});
|
11544
|
+
if (isLimitedToSlots) {
|
11545
|
+
classType.details.inheritedSlotsNames = extendedSlotsNames;
|
11428
11546
|
}
|
11429
|
-
else {
|
11430
|
-
isLimitedToSlots = false;
|
11431
|
-
}
|
11432
|
-
});
|
11433
|
-
if (isLimitedToSlots) {
|
11434
|
-
classType.details.inheritedSlotsNames = extendedSlotsNames;
|
11435
11547
|
}
|
11548
|
+
// Update the undecorated class type.
|
11549
|
+
writeTypeCache(node.name, { type: classType }, 0 /* None */);
|
11550
|
+
// Update the decorated class type.
|
11551
|
+
writeTypeCache(node, { type: decoratedType }, 0 /* None */);
|
11552
|
+
return { classType, decoratedType };
|
11553
|
+
}
|
11554
|
+
catch (e) {
|
11555
|
+
if (cancellationUtils_1.OperationCanceledException.is(e)) {
|
11556
|
+
// If the work was canceled before the class types were updated, the
|
11557
|
+
// class type in the type cache is in an invalid, partially-constructed state.
|
11558
|
+
e.isTypeCacheInvalid = true;
|
11559
|
+
}
|
11560
|
+
throw e;
|
11436
11561
|
}
|
11437
|
-
// Update the undecorated class type.
|
11438
|
-
writeTypeCache(node.name, { type: classType }, 0 /* None */);
|
11439
|
-
// Update the decorated class type.
|
11440
|
-
writeTypeCache(node, { type: decoratedType }, 0 /* None */);
|
11441
|
-
return { classType, decoratedType };
|
11442
11562
|
}
|
11443
11563
|
// Determines whether the type parameters has a default that refers to another
|
11444
11564
|
// type parameter. If so, validates that it is in the list of "live" type
|
@@ -12105,11 +12225,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12105
12225
|
}
|
12106
12226
|
validateTypeParameterDefault(bestErrorNode, typeParam, functionType.details.typeParameters.slice(0, index));
|
12107
12227
|
});
|
12228
|
+
// If it's an async function, wrap the return type in an Awaitable or Generator.
|
12229
|
+
const preDecoratedType = node.isAsync ? createAsyncFunction(node, functionType) : functionType;
|
12108
12230
|
// Clear the "partially evaluated" flag to indicate that the functionType
|
12109
12231
|
// is fully evaluated.
|
12110
12232
|
functionType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
12111
|
-
// If it's an async function, wrap the return type in an Awaitable or Generator.
|
12112
|
-
const preDecoratedType = node.isAsync ? createAsyncFunction(node, functionType) : functionType;
|
12113
12233
|
// Apply all of the decorators in reverse order.
|
12114
12234
|
let decoratedType = preDecoratedType;
|
12115
12235
|
let foundUnknown = false;
|
@@ -12322,7 +12442,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12322
12442
|
(0, debug_1.assert)(types_1.FunctionType.isAsync(functionType));
|
12323
12443
|
// Clone the original function and replace its return type with an
|
12324
12444
|
// Awaitable[<returnType>]. Mark the new function as no longer async.
|
12325
|
-
const awaitableFunctionType = types_1.FunctionType.cloneWithNewFlags(functionType, functionType.details.flags & ~512 /* Async */);
|
12445
|
+
const awaitableFunctionType = types_1.FunctionType.cloneWithNewFlags(functionType, functionType.details.flags & ~(512 /* Async */ | 131072 /* PartiallyEvaluated */));
|
12326
12446
|
if (functionType.details.declaredReturnType) {
|
12327
12447
|
awaitableFunctionType.details.declaredReturnType = createAwaitableReturnType(node, functionType.details.declaredReturnType, types_1.FunctionType.isGenerator(functionType));
|
12328
12448
|
}
|
@@ -12805,7 +12925,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12805
12925
|
for (const caseStatement of node.parent.cases) {
|
12806
12926
|
if (caseStatement === node) {
|
12807
12927
|
if (fileInfo.diagnosticRuleSet.reportUnnecessaryComparison !== 'none') {
|
12808
|
-
(
|
12928
|
+
if (!subjectTypeResult.isIncomplete) {
|
12929
|
+
(0, patternMatching_1.checkForUnusedPattern)(evaluatorInterface, node.pattern, subjectType);
|
12930
|
+
}
|
12809
12931
|
}
|
12810
12932
|
break;
|
12811
12933
|
}
|
@@ -12821,23 +12943,57 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12821
12943
|
if (isTypeCached(node)) {
|
12822
12944
|
return;
|
12823
12945
|
}
|
12824
|
-
|
12825
|
-
|
12826
|
-
|
12827
|
-
|
12828
|
-
|
12829
|
-
|
12946
|
+
if (node.isWildcardImport) {
|
12947
|
+
// Write back a dummy type so we don't evaluate this node again.
|
12948
|
+
writeTypeCache(node, { type: types_1.AnyType.create() }, 0 /* None */);
|
12949
|
+
const flowNode = AnalyzerNodeInfo.getFlowNode(node);
|
12950
|
+
if (flowNode && (flowNode.flags & codeFlowTypes_1.FlowFlags.WildcardImport) !== 0) {
|
12951
|
+
const wildcardFlowNode = flowNode;
|
12952
|
+
wildcardFlowNode.names.forEach((name) => {
|
12953
|
+
var _a, _b;
|
12954
|
+
const importedSymbolType = getAliasedSymbolTypeForName(node, name);
|
12955
|
+
if (!importedSymbolType) {
|
12956
|
+
return;
|
12957
|
+
}
|
12958
|
+
const symbolWithScope = lookUpSymbolRecursive(node, name, /* honorCodeFlow */ false);
|
12959
|
+
if (!symbolWithScope) {
|
12960
|
+
return;
|
12961
|
+
}
|
12962
|
+
const declaredType = (_a = getDeclaredTypeOfSymbol(symbolWithScope.symbol)) === null || _a === void 0 ? void 0 : _a.type;
|
12963
|
+
if (!declaredType) {
|
12964
|
+
return;
|
12965
|
+
}
|
12966
|
+
const diagAddendum = new diagnostic_1.DiagnosticAddendum();
|
12967
|
+
if (!assignType(declaredType, importedSymbolType, diagAddendum)) {
|
12968
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAssignmentMismatchWildcard().format({
|
12969
|
+
...printSrcDestTypes(importedSymbolType, declaredType),
|
12970
|
+
name,
|
12971
|
+
}) + diagAddendum.getString(), node, (_b = node.wildcardToken) !== null && _b !== void 0 ? _b : node);
|
12972
|
+
}
|
12973
|
+
});
|
12974
|
+
}
|
12830
12975
|
}
|
12831
|
-
|
12832
|
-
|
12833
|
-
|
12834
|
-
|
12835
|
-
|
12836
|
-
|
12976
|
+
else {
|
12977
|
+
// Use the first element of the name parts as the symbol.
|
12978
|
+
const symbolNameNode = node.module.nameParts[0];
|
12979
|
+
// Look up the symbol to find the alias declaration.
|
12980
|
+
let symbolType = getAliasedSymbolTypeForName(node, symbolNameNode.value);
|
12981
|
+
if (!symbolType) {
|
12982
|
+
return;
|
12837
12983
|
}
|
12984
|
+
// Is there a cached module type associated with this node? If so, use
|
12985
|
+
// it instead of the type we just created.
|
12986
|
+
const cachedModuleType = readTypeCache(node, 0 /* None */);
|
12987
|
+
if (cachedModuleType && (0, types_1.isModule)(cachedModuleType) && symbolType) {
|
12988
|
+
if ((0, types_1.isTypeSame)(symbolType, cachedModuleType)) {
|
12989
|
+
symbolType = cachedModuleType;
|
12990
|
+
}
|
12991
|
+
}
|
12992
|
+
assignTypeToNameNode(symbolNameNode, symbolType,
|
12993
|
+
/* isIncomplete */ false,
|
12994
|
+
/* ignoreEmptyContainers */ false);
|
12995
|
+
writeTypeCache(node, { type: symbolType }, 0 /* None */);
|
12838
12996
|
}
|
12839
|
-
assignTypeToNameNode(symbolNameNode, symbolType, /* isIncomplete */ false, /* ignoreEmptyContainers */ false);
|
12840
|
-
writeTypeCache(node, { type: symbolType }, 0 /* None */);
|
12841
12997
|
}
|
12842
12998
|
function evaluateTypesForTypeAnnotationNode(node) {
|
12843
12999
|
var _a;
|
@@ -13663,6 +13819,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13663
13819
|
if ((0, types_1.isParamSpec)(typeArg)) {
|
13664
13820
|
functionType.details.paramSpec = typeArg;
|
13665
13821
|
}
|
13822
|
+
else if ((0, typeUtils_1.isEllipsisType)(typeArg)) {
|
13823
|
+
types_1.FunctionType.addDefaultParameters(functionType);
|
13824
|
+
functionType.details.flags |=
|
13825
|
+
32768 /* SkipArgsKwargsCompatibilityCheck */;
|
13826
|
+
}
|
13666
13827
|
}
|
13667
13828
|
else {
|
13668
13829
|
types_1.FunctionType.addParameter(functionType, {
|
@@ -13762,8 +13923,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13762
13923
|
let flags = 128 /* ExpectingInstantiableType */ |
|
13763
13924
|
8 /* EvaluateStringLiteralAsType */ |
|
13764
13925
|
131072 /* DisallowClassVar */;
|
13765
|
-
if (
|
13766
|
-
flags |= 4096 /*
|
13926
|
+
if (options === null || options === void 0 ? void 0 : options.allowTypeVarsWithoutScopeId) {
|
13927
|
+
flags |= 4096 /* AllowTypeVarsWithoutScopeId */;
|
13767
13928
|
}
|
13768
13929
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
13769
13930
|
if (fileInfo.isStubFile || (options === null || options === void 0 ? void 0 : options.allowForwardReference)) {
|
@@ -15650,6 +15811,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15650
15811
|
const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
|
15651
15812
|
let effectiveFlags;
|
15652
15813
|
let errorSource;
|
15814
|
+
let includeDiagAddendum = true;
|
15653
15815
|
if (variance === 3 /* Covariant */) {
|
15654
15816
|
effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
|
15655
15817
|
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
|
@@ -15662,6 +15824,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15662
15824
|
else {
|
15663
15825
|
effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
|
15664
15826
|
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsInvariant;
|
15827
|
+
// Omit the diagnostic addendum for the invariant case because it's obvious
|
15828
|
+
// why two types are not the same.
|
15829
|
+
includeDiagAddendum = false;
|
15665
15830
|
}
|
15666
15831
|
if (!assignType(variance === 4 /* Contravariant */ ? srcTypeArg : destTypeArg, variance === 4 /* Contravariant */ ? destTypeArg : srcTypeArg, assignmentDiag, variance === 4 /* Contravariant */ ? srcTypeVarContext : destTypeVarContext, variance === 4 /* Contravariant */ ? destTypeVarContext : srcTypeVarContext, effectiveFlags, recursionCount)) {
|
15667
15832
|
// Don't report errors with type variables in "pseudo-random"
|
@@ -15674,6 +15839,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15674
15839
|
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15675
15840
|
...printSrcDestTypes(srcTypeArg, destTypeArg),
|
15676
15841
|
}));
|
15842
|
+
if (includeDiagAddendum) {
|
15843
|
+
childDiag.addAddendum(assignmentDiag);
|
15844
|
+
}
|
15677
15845
|
}
|
15678
15846
|
else {
|
15679
15847
|
diag.addAddendum(assignmentDiag);
|
@@ -16895,7 +17063,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16895
17063
|
}
|
16896
17064
|
}
|
16897
17065
|
}
|
16898
|
-
else {
|
17066
|
+
else if (!srcParamDetails.paramSpec) {
|
16899
17067
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.functionTooManyParams().format({
|
16900
17068
|
expected: srcPositionalCount,
|
16901
17069
|
received: destPositionalCount,
|
@@ -17044,16 +17212,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17044
17212
|
// concatenated parameters must match.
|
17045
17213
|
if (targetIncludesParamSpec &&
|
17046
17214
|
((_j = srcType.details.paramSpec) === null || _j === void 0 ? void 0 : _j.nameWithScope) === ((_k = destType.details.paramSpec) === null || _k === void 0 ? void 0 : _k.nameWithScope)) {
|
17047
|
-
|
17048
|
-
|
17049
|
-
if (srcParamCount !== destParamCount) {
|
17050
|
-
// If the dest has an extra position-only parameter separator appended
|
17051
|
-
// to the end of the signature, it's OK.
|
17052
|
-
if (srcParamCount !== destParamCount - 1 ||
|
17053
|
-
destType.details.parameters[destParamCount - 1].category !== 0 /* Simple */ ||
|
17054
|
-
!!destType.details.parameters[destParamCount - 1].name) {
|
17055
|
-
canAssign = false;
|
17056
|
-
}
|
17215
|
+
if (srcParamDetails.params.length !== destParamDetails.params.length) {
|
17216
|
+
canAssign = false;
|
17057
17217
|
}
|
17058
17218
|
}
|
17059
17219
|
const effectiveSrcTypeVarContext = (flags & 2 /* ReverseTypeVarMatching */) === 0 ? srcTypeVarContext : destTypeVarContext;
|
@@ -17245,6 +17405,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17245
17405
|
return types_1.ClassType.cloneForSpecialization(assignedType, newTypeArgs, /* isTypeArgumentExplicit */ true);
|
17246
17406
|
}
|
17247
17407
|
}
|
17408
|
+
// If the declared and assigned types are the same generic type but the assigned type
|
17409
|
+
// contains one or more unknowns, use the declared type instead.
|
17410
|
+
if (types_1.ClassType.isSameGenericClass(declaredType, assignedType)) {
|
17411
|
+
if ((0, typeUtils_1.containsAnyRecursive)(assignedType) && !(0, typeUtils_1.containsAnyRecursive)(declaredType)) {
|
17412
|
+
return declaredType;
|
17413
|
+
}
|
17414
|
+
}
|
17248
17415
|
return undefined;
|
17249
17416
|
}
|
17250
17417
|
// When a value is assigned to a variable with a declared type,
|
@@ -17257,29 +17424,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17257
17424
|
return declaredSubtype;
|
17258
17425
|
}
|
17259
17426
|
if (assignType(declaredSubtype, assignedSubtype)) {
|
17260
|
-
// If the
|
17261
|
-
|
17262
|
-
|
17427
|
+
// If the assigned subtype is Any, stick with the declared type.
|
17428
|
+
if ((0, types_1.isAny)(assignedSubtype)) {
|
17429
|
+
return declaredSubtype;
|
17430
|
+
}
|
17431
|
+
if ((0, types_1.isClass)(declaredSubtype) &&
|
17432
|
+
(0, types_1.isClass)(assignedSubtype) &&
|
17433
|
+
types_1.TypeBase.isInstance(declaredSubtype) === types_1.TypeBase.isInstance(assignedSubtype)) {
|
17263
17434
|
const result = replaceTypeArgsWithAny(node, declaredSubtype, assignedSubtype);
|
17264
17435
|
if (result) {
|
17265
17436
|
assignedSubtype = result;
|
17266
17437
|
}
|
17438
|
+
return assignedSubtype;
|
17267
17439
|
}
|
17268
|
-
|
17269
|
-
const result = replaceTypeArgsWithAny(node, types_1.ClassType.cloneAsInstantiable(declaredSubtype), types_1.ClassType.cloneAsInstantiable(assignedSubtype));
|
17270
|
-
if (result) {
|
17271
|
-
assignedSubtype = types_1.ClassType.cloneAsInstance(result);
|
17272
|
-
}
|
17273
|
-
}
|
17274
|
-
else if (!(0, types_1.isTypeVar)(declaredSubtype) && (0, types_1.isTypeVar)(assignedSubtype)) {
|
17440
|
+
if (!(0, types_1.isTypeVar)(declaredSubtype) && (0, types_1.isTypeVar)(assignedSubtype)) {
|
17275
17441
|
// If the source is an unsolved TypeVar but the declared type is concrete,
|
17276
17442
|
// use the concrete type.
|
17277
17443
|
return declaredSubtype;
|
17278
17444
|
}
|
17279
|
-
// If the assigned subtype is Any, stick with the declared type.
|
17280
|
-
if ((0, types_1.isAny)(assignedSubtype)) {
|
17281
|
-
return declaredSubtype;
|
17282
|
-
}
|
17283
17445
|
// If the declared type doesn't contain any `Any` but the assigned
|
17284
17446
|
// type does, stick with the declared type.
|
17285
17447
|
if ((0, typeUtils_1.containsAnyRecursive)(assignedSubtype) && !(0, typeUtils_1.containsAnyRecursive)(declaredSubtype)) {
|
@@ -17347,28 +17509,42 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17347
17509
|
// must all match and be in the correct order. It is OK if the base method
|
17348
17510
|
// has additional overloads that are not present in the override.
|
17349
17511
|
let previousMatchIndex = -1;
|
17350
|
-
let overrideOverloadIndex = 0;
|
17351
17512
|
const baseOverloads = types_1.OverloadedFunctionType.getOverloads(baseMethod);
|
17352
17513
|
for (const overrideOverload of types_1.OverloadedFunctionType.getOverloads(overrideMethod)) {
|
17353
|
-
|
17514
|
+
let possibleMatchIndex;
|
17515
|
+
let matchIndex = baseOverloads.findIndex((baseOverload, index) => {
|
17354
17516
|
// If the override isn't applicable for this base class, skip the check.
|
17355
17517
|
if (baseClass && !isOverrideMethodApplicable(baseOverload, baseClass)) {
|
17356
17518
|
return false;
|
17357
17519
|
}
|
17358
|
-
|
17520
|
+
const isCompatible = validateOverrideMethodInternal(baseOverload, overrideOverload,
|
17359
17521
|
/* diag */ undefined, enforceParamNames,
|
17360
17522
|
/* exemptSelfClsParam */ false);
|
17523
|
+
// If the override is compatible but the match is one that is below the previous
|
17524
|
+
// matched index, keep looking for additional matches. Record the fact that
|
17525
|
+
// we found at least one match.
|
17526
|
+
if (isCompatible && index <= previousMatchIndex && possibleMatchIndex === undefined) {
|
17527
|
+
possibleMatchIndex = index;
|
17528
|
+
return false;
|
17529
|
+
}
|
17530
|
+
return isCompatible;
|
17361
17531
|
});
|
17532
|
+
if (matchIndex < 0 && possibleMatchIndex !== undefined) {
|
17533
|
+
matchIndex = possibleMatchIndex;
|
17534
|
+
}
|
17362
17535
|
if (matchIndex < 0) {
|
17363
|
-
|
17364
|
-
return false;
|
17536
|
+
continue;
|
17365
17537
|
}
|
17366
17538
|
if (matchIndex < previousMatchIndex) {
|
17367
17539
|
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadOrder());
|
17368
17540
|
return false;
|
17369
17541
|
}
|
17370
17542
|
previousMatchIndex = matchIndex;
|
17371
|
-
|
17543
|
+
}
|
17544
|
+
if (previousMatchIndex < baseOverloads.length - 1) {
|
17545
|
+
// We didn't find matches for all of the base overloads.
|
17546
|
+
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadNoMatch());
|
17547
|
+
return false;
|
17372
17548
|
}
|
17373
17549
|
return true;
|
17374
17550
|
}
|
@@ -17638,9 +17814,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17638
17814
|
}
|
17639
17815
|
}
|
17640
17816
|
// Verify that one or the other method doesn't contain a ParamSpec.
|
17641
|
-
if (
|
17642
|
-
|
17643
|
-
|
17817
|
+
if (baseParamDetails.paramSpec && !overrideParamDetails.paramSpec) {
|
17818
|
+
// If the override uses an `*args: Any, **kwargs: Any` signature, we
|
17819
|
+
// will allow this as an acceptable overload for a `*args: P.args, **kwargs: P.kwargs`.
|
17820
|
+
const overrideHasArgsKwargs = overrideParamDetails.argsIndex !== undefined &&
|
17821
|
+
(0, types_1.isAnyOrUnknown)(overrideParamDetails.params[overrideParamDetails.argsIndex].type) &&
|
17822
|
+
overrideParamDetails.kwargsIndex !== undefined &&
|
17823
|
+
(0, types_1.isAnyOrUnknown)(overrideParamDetails.params[overrideParamDetails.kwargsIndex].type);
|
17824
|
+
if (!overrideHasArgsKwargs) {
|
17825
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.paramSpecMissingInOverride());
|
17826
|
+
canOverride = false;
|
17827
|
+
}
|
17644
17828
|
}
|
17645
17829
|
// Now check the return type.
|
17646
17830
|
const baseReturnType = getFunctionEffectiveReturnType(baseMethod);
|