@zzzen/pyright-internal 1.2.0-dev.20230820 → 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/checker.js +46 -64
- 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/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/importResolver.js +5 -0
- package/dist/analyzer/importResolver.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/sourceFile.js +1 -0
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +530 -432
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeGuards.js +15 -4
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +2 -2
- package/dist/analyzer/typeUtils.js +10 -5
- 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 +19 -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/languageService/completionProvider.js +9 -3
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +3 -0
- package/dist/localization/localize.js +1 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +12 -10
- package/dist/localization/package.nls.de.json +12 -10
- package/dist/localization/package.nls.en-us.json +2 -1
- package/dist/localization/package.nls.es.json +12 -10
- package/dist/localization/package.nls.fr.json +12 -10
- package/dist/localization/package.nls.it.json +12 -10
- package/dist/localization/package.nls.ja.json +12 -10
- package/dist/localization/package.nls.ko.json +12 -10
- package/dist/localization/package.nls.pl.json +12 -10
- package/dist/localization/package.nls.pt-br.json +12 -10
- package/dist/localization/package.nls.qps-ploc.json +12 -10
- package/dist/localization/package.nls.ru.json +12 -10
- package/dist/localization/package.nls.tr.json +12 -10
- package/dist/localization/package.nls.zh-cn.json +12 -10
- package/dist/localization/package.nls.zh-tw.json +12 -10
- package/dist/parser/parser.js +2 -0
- 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/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/typeEvaluator1.test.js +4 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +4 -0
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +14 -20
- package/dist/tests/typeEvaluator3.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +12 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/dist/tests/typeEvaluator5.test.js +24 -0
- 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,6 +683,26 @@ 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.
|
@@ -1234,11 +1254,30 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1234
1254
|
let memberInfo;
|
1235
1255
|
const classDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
1236
1256
|
const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
1257
|
+
let considerMetaclassOnly = (memberAccessFlags & 32 /* ConsiderMetaclassOnly */) !== 0;
|
1237
1258
|
if (types_1.ClassType.isPartiallyEvaluated(classType)) {
|
1238
1259
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: classType.details.name }), errorNode);
|
1239
1260
|
return { type: types_1.UnknownType.create() };
|
1240
1261
|
}
|
1241
|
-
|
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) {
|
1242
1281
|
memberInfo = getTypeOfClassMemberName(errorNode, classType,
|
1243
1282
|
/* isAccessedThroughObject */ false, memberName, usage, classDiag, memberAccessFlags | 1 /* AccessClassMembersOnly */, bindToType);
|
1244
1283
|
}
|
@@ -2920,6 +2959,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
2920
2959
|
}
|
2921
2960
|
}
|
2922
2961
|
}
|
2962
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
|
2963
|
+
reportUseOfTypeCheckOnly(type, node);
|
2964
|
+
}
|
2923
2965
|
if ((flags & 16777216 /* DisallowPep695TypeAlias */) !== 0) {
|
2924
2966
|
if (reportInvalidUseOfPep695TypeAlias(type, node)) {
|
2925
2967
|
type = types_1.UnknownType.create();
|
@@ -3389,7 +3431,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3389
3431
|
}
|
3390
3432
|
return { type: types_1.UnknownType.create(isIncomplete), isIncomplete };
|
3391
3433
|
}
|
3392
|
-
if (flags & 256 /* ExpectingTypeAnnotation */) {
|
3434
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
3393
3435
|
if (!isIncomplete) {
|
3394
3436
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarNoMember().format({
|
3395
3437
|
type: printType(baseType),
|
@@ -3613,6 +3655,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3613
3655
|
// additional reportUnknownMemberType diagnostics.
|
3614
3656
|
type = isFunctionRule ? types_1.AnyType.create() : types_1.UnknownType.create();
|
3615
3657
|
}
|
3658
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) === 0) {
|
3659
|
+
reportUseOfTypeCheckOnly(type, node.memberName);
|
3660
|
+
}
|
3616
3661
|
// Should we specialize the class?
|
3617
3662
|
if ((flags & 2 /* DoNotSpecialize */) === 0) {
|
3618
3663
|
if ((0, types_1.isInstantiableClass)(type) && !type.typeArguments) {
|
@@ -3705,13 +3750,24 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3705
3750
|
}
|
3706
3751
|
}
|
3707
3752
|
if (!type) {
|
3753
|
+
let selfClass = classType;
|
3708
3754
|
// Determine whether to replace Self variables with a specific
|
3709
3755
|
// class. Avoid doing this if there's a "bindToType" specified
|
3710
3756
|
// because that case is used for super() calls where we want
|
3711
3757
|
// to leave the Self type generic (not specialized). We'll also
|
3712
3758
|
// skip this for __new__ methods because they are not bound
|
3713
3759
|
// to the class but rather assume the type of the cls argument.
|
3714
|
-
|
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
|
+
}
|
3715
3771
|
const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
|
3716
3772
|
if (typeResult) {
|
3717
3773
|
type = typeResult.type;
|
@@ -3886,14 +3942,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3886
3942
|
];
|
3887
3943
|
if (usage.method === 'get') {
|
3888
3944
|
// Provide "owner" argument.
|
3889
|
-
// Use Any rather than None for the owner argument if accessing through an object.
|
3890
|
-
// None is more correct, but it doesn't really matter, and many descriptor classes
|
3891
|
-
// incorrectly annotate the owner parameter. Rather than create a bunch of noise,
|
3892
|
-
// we'll use Any here.
|
3893
3945
|
argList.push({
|
3894
3946
|
argumentCategory: 0 /* Simple */,
|
3895
3947
|
typeResult: {
|
3896
|
-
type:
|
3948
|
+
type: baseTypeClass,
|
3897
3949
|
},
|
3898
3950
|
});
|
3899
3951
|
}
|
@@ -4251,14 +4303,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4251
4303
|
function getTypeOfIndex(node, flags = 0 /* None */) {
|
4252
4304
|
const baseTypeResult = getTypeOfExpression(node.baseExpression, flags | 2 /* IndexBaseDefaults */);
|
4253
4305
|
// If this is meant to be a type and the base expression is a string expression,
|
4254
|
-
// emit an error because this
|
4255
|
-
//
|
4306
|
+
// emit an error because this is an illegal annotation form and will generate a
|
4307
|
+
// runtime exception.
|
4256
4308
|
if (flags & 128 /* ExpectingInstantiableType */) {
|
4257
4309
|
if (node.baseExpression.nodeType === 48 /* StringList */) {
|
4258
|
-
|
4259
|
-
if (!fileInfo.isStubFile && fileInfo.executionEnvironment.pythonVersion < pythonVersion_1.PythonVersion.V3_10) {
|
4260
|
-
addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
|
4261
|
-
}
|
4310
|
+
addError(localize_1.Localizer.Diagnostic.stringNotSubscriptable(), node.baseExpression);
|
4262
4311
|
}
|
4263
4312
|
}
|
4264
4313
|
// Check for builtin classes that will generate runtime exceptions if subscripted.
|
@@ -4608,7 +4657,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4608
4657
|
const itemMethodType = getTypeOfClassMember(node, concreteSubtype, getIndexAccessMagicMethodName(usage),
|
4609
4658
|
/* usage */ undefined,
|
4610
4659
|
/* diag */ undefined, 64 /* SkipAttributeAccessOverride */ | 32 /* ConsiderMetaclassOnly */);
|
4611
|
-
if (flags & 256 /* ExpectingTypeAnnotation */) {
|
4660
|
+
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
4612
4661
|
// If the class doesn't derive from Generic, a type argument should not be allowed.
|
4613
4662
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
|
4614
4663
|
name: printType(types_1.ClassType.cloneAsInstance(concreteSubtype)),
|
@@ -4660,9 +4709,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4660
4709
|
// Inlined TypedDicts are supported only for 'dict' (and not for 'Dict').
|
4661
4710
|
// This feature is currently experimental.
|
4662
4711
|
const supportsTypedDictTypeArg = AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.enableExperimentalFeatures &&
|
4663
|
-
|
4664
|
-
types_1.ClassType.isBuiltIn(concreteSubtype, '
|
4665
|
-
!concreteSubtype.aliasName;
|
4712
|
+
types_1.ClassType.isBuiltIn(concreteSubtype, ['dict', 'TypedDict']) &&
|
4713
|
+
!types_1.ClassType.isBuiltIn(concreteSubtype, 'Dict');
|
4666
4714
|
let typeArgs = getTypeArgs(node, flags, {
|
4667
4715
|
isAnnotatedClass,
|
4668
4716
|
hasCustomClassGetItem: hasCustomClassGetItem || !isGenericClass,
|
@@ -5633,7 +5681,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5633
5681
|
if (node.arguments.length > 2) {
|
5634
5682
|
addError(localize_1.Localizer.Diagnostic.superCallArgCount(), node.arguments[2]);
|
5635
5683
|
}
|
5636
|
-
const
|
5684
|
+
const enclosingFunction = ParseTreeUtils.getEnclosingFunction(node);
|
5685
|
+
const enclosingClass = enclosingFunction
|
5686
|
+
? ParseTreeUtils.getEnclosingClass(enclosingFunction, /* stopAtFunction */ true)
|
5687
|
+
: undefined;
|
5637
5688
|
const enclosingClassType = enclosingClass ? (_a = getTypeOfClass(enclosingClass)) === null || _a === void 0 ? void 0 : _a.classType : undefined;
|
5638
5689
|
// Determine which class the "super" call is applied to. If
|
5639
5690
|
// there is no first argument, then the class is implicit.
|
@@ -5804,13 +5855,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5804
5855
|
return argParamCopy;
|
5805
5856
|
});
|
5806
5857
|
}
|
5807
|
-
// Clone the typeVarContext so we don't modify the original.
|
5808
|
-
|
5809
|
-
// from the previous successful match.
|
5810
|
-
const typeVarContextToClone = matchedOverloads.length > 0
|
5811
|
-
? matchedOverloads[matchedOverloads.length - 1].typeVarContext.clone()
|
5812
|
-
: typeVarContext;
|
5813
|
-
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));
|
5814
5860
|
effectiveTypeVarContext.addSolveForScope((0, typeUtils_1.getTypeVarScopeIds)(overload));
|
5815
5861
|
effectiveTypeVarContext.unlock();
|
5816
5862
|
// Use speculative mode so we don't output any diagnostics or
|
@@ -6557,7 +6603,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6557
6603
|
var _a, _b;
|
6558
6604
|
const memberType = (_a = getTypeOfObjectMember(errorNode, expandedCallType, '__call__',
|
6559
6605
|
/* usage */ undefined,
|
6560
|
-
/* 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;
|
6561
6607
|
if (!memberType) {
|
6562
6608
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6563
6609
|
type: printType(expandedCallType),
|
@@ -7960,6 +8006,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7960
8006
|
const argsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 1 /* ArgsList */);
|
7961
8007
|
const kwargsParam = paramSpecParams.find((paramInfo) => paramInfo.category === 2 /* KwargsDict */);
|
7962
8008
|
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
8009
|
+
const nestedArgList = [];
|
7963
8010
|
argList.forEach((arg) => {
|
7964
8011
|
var _a;
|
7965
8012
|
if (arg.argumentCategory === 0 /* Simple */) {
|
@@ -7989,6 +8036,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
7989
8036
|
else if (argsParam) {
|
7990
8037
|
paramType = argsParam.type;
|
7991
8038
|
}
|
8039
|
+
else if (paramSpecType.details.paramSpec) {
|
8040
|
+
nestedArgList.push(arg);
|
8041
|
+
}
|
7992
8042
|
else {
|
7993
8043
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, paramSpecParams.length === 1
|
7994
8044
|
? localize_1.Localizer.Diagnostic.argPositionalExpectedOne()
|
@@ -8034,6 +8084,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8034
8084
|
}
|
8035
8085
|
}
|
8036
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
|
+
}
|
8037
8099
|
});
|
8038
8100
|
}
|
8039
8101
|
// Report any missing parameters.
|
@@ -8071,10 +8133,17 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8071
8133
|
let isCompatible = true;
|
8072
8134
|
const functionName = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type.details.name;
|
8073
8135
|
let skippedBareTypeVarExpectedType = false;
|
8136
|
+
let skipSolveTypeVars = false;
|
8074
8137
|
if (argParam.argument.valueExpression) {
|
8075
8138
|
let expectedType;
|
8076
|
-
|
8077
|
-
|
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) {
|
8078
8147
|
expectedType = argParam.paramType;
|
8079
8148
|
// If the parameter type is a function with a ParamSpec, don't apply
|
8080
8149
|
// the solved TypeVars if the typeVarContext has more than one signature.
|
@@ -8090,6 +8159,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8090
8159
|
}
|
8091
8160
|
else {
|
8092
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
|
+
}
|
8093
8169
|
}
|
8094
8170
|
// If the expected type is unknown, don't use an expected type. Instead,
|
8095
8171
|
// use default rules for evaluating the expression type.
|
@@ -8206,7 +8282,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8206
8282
|
}
|
8207
8283
|
}
|
8208
8284
|
if ((0, types_1.isClassInstance)(argType)) {
|
8209
|
-
const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__');
|
8285
|
+
const callMember = (0, typeUtils_1.lookUpObjectMember)(argType, '__call__', 8 /* SkipInstanceVariables */);
|
8210
8286
|
if (callMember) {
|
8211
8287
|
const memberType = getTypeOfMember(callMember);
|
8212
8288
|
if ((0, types_1.isOverloadedFunction)(memberType)) {
|
@@ -8223,7 +8299,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8223
8299
|
}
|
8224
8300
|
}
|
8225
8301
|
}
|
8226
|
-
if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext
|
8302
|
+
if (!assignType(argParam.paramType, argType, diag.createAddendum(), typeVarContext,
|
8303
|
+
/* srcTypeVarContext */ undefined, skipSolveTypeVars ? 8 /* SkipSolveTypeVars */ : undefined)) {
|
8227
8304
|
// Mismatching parameter types are common in untyped code; don't bother spending time
|
8228
8305
|
// printing types if the diagnostic is disabled.
|
8229
8306
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(argParam.errorNode);
|
@@ -10616,7 +10693,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10616
10693
|
// methods that are abstract are overridden and shouldn't
|
10617
10694
|
// cause the TypedDict to be marked as abstract.
|
10618
10695
|
if ((0, types_1.isInstantiableClass)(baseClass) && types_1.ClassType.isBuiltIn(baseClass, '_TypedDict')) {
|
10619
|
-
baseClass.details.flags
|
10696
|
+
baseClass = types_1.ClassType.cloneWithNewFlags(baseClass, baseClass.details.flags &
|
10697
|
+
~(1024 /* SupportsAbstractMethods */ | 134217728 /* TypeCheckOnly */));
|
10620
10698
|
}
|
10621
10699
|
}
|
10622
10700
|
}
|
@@ -11022,452 +11100,465 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11022
11100
|
setSymbolResolutionPartialType(classSymbol, classDecl, classType);
|
11023
11101
|
}
|
11024
11102
|
classType.details.flags |= 131072 /* PartiallyEvaluated */;
|
11025
|
-
|
11026
|
-
|
11027
|
-
|
11028
|
-
|
11029
|
-
|
11030
|
-
|
11031
|
-
|
11032
|
-
|
11033
|
-
|
11034
|
-
|
11035
|
-
|
11036
|
-
|
11037
|
-
|
11038
|
-
|
11039
|
-
|
11040
|
-
|
11041
|
-
|
11042
|
-
|
11043
|
-
|
11044
|
-
|
11045
|
-
|
11046
|
-
|
11047
|
-
|
11048
|
-
|
11049
|
-
node.arguments.forEach((arg) => {
|
11050
|
-
// Ignore unpacked arguments.
|
11051
|
-
if (arg.argumentCategory === 2 /* UnpackedDictionary */) {
|
11052
|
-
// Evaluate the expression's type so symbols are marked accessed
|
11053
|
-
// and errors are reported.
|
11054
|
-
getTypeOfExpression(arg.valueExpression);
|
11055
|
-
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 */;
|
11056
11127
|
}
|
11057
|
-
|
11058
|
-
|
11059
|
-
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.
|
11060
11133
|
getTypeOfExpression(arg.valueExpression);
|
11061
|
-
|
11134
|
+
return;
|
11062
11135
|
}
|
11063
|
-
|
11064
|
-
argType
|
11065
|
-
|
11066
|
-
|
11067
|
-
// on platform type). We'll assume that the conditional logic is correct
|
11068
|
-
// and strip off the "unbound" union.
|
11069
|
-
if ((0, types_1.isUnion)(argType)) {
|
11070
|
-
argType = (0, types_1.removeUnbound)(argType);
|
11071
|
-
}
|
11072
|
-
if (!(0, types_1.isAnyOrUnknown)(argType) && !(0, types_1.isUnbound)(argType)) {
|
11073
|
-
if ((0, typeUtils_1.isMetaclassInstance)(argType)) {
|
11074
|
-
(0, debug_1.assert)((0, types_1.isClassInstance)(argType));
|
11075
|
-
argType =
|
11076
|
-
argType.typeArguments && argType.typeArguments.length > 0
|
11077
|
-
? argType.typeArguments[0]
|
11078
|
-
: types_1.UnknownType.create();
|
11079
|
-
}
|
11080
|
-
else if (!(0, types_1.isInstantiableClass)(argType)) {
|
11081
|
-
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);
|
11082
11140
|
argType = types_1.UnknownType.create();
|
11083
11141
|
}
|
11084
11142
|
else {
|
11085
|
-
|
11086
|
-
|
11087
|
-
|
11088
|
-
|
11089
|
-
|
11090
|
-
|
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();
|
11091
11158
|
}
|
11092
|
-
if (types_1.
|
11093
|
-
|
11094
|
-
|
11095
|
-
|
11096
|
-
|
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();
|
11097
11210
|
}
|
11098
|
-
classType.details.flags |= 8192 /* ProtocolClass */;
|
11099
11211
|
}
|
11100
|
-
|
11101
|
-
|
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 */;
|
11102
11228
|
}
|
11103
|
-
//
|
11104
|
-
//
|
11105
|
-
|
11106
|
-
|
11107
|
-
|
11108
|
-
|
11109
|
-
|
11110
|
-
|
11111
|
-
|
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 */;
|
11112
11240
|
}
|
11113
|
-
|
11114
|
-
|
11115
|
-
|
11116
|
-
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);
|
11117
11244
|
}
|
11118
|
-
|
11119
|
-
|
11120
|
-
|
11121
|
-
|
11122
|
-
|
11123
|
-
|
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
|
+
}
|
11124
11261
|
}
|
11125
11262
|
}
|
11126
|
-
|
11127
|
-
|
11128
|
-
|
11129
|
-
|
11130
|
-
|
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
|
+
}
|
11131
11277
|
}
|
11132
11278
|
}
|
11133
11279
|
}
|
11134
|
-
if (
|
11135
|
-
|
11136
|
-
|
11137
|
-
// Check for a duplicate class.
|
11138
|
-
if (classType.details.baseClasses.some((prevBaseClass) => {
|
11139
|
-
return ((0, types_1.isInstantiableClass)(prevBaseClass) &&
|
11140
|
-
(0, types_1.isInstantiableClass)(argType) &&
|
11141
|
-
types_1.ClassType.isSameGenericClass(argType, prevBaseClass));
|
11142
|
-
})) {
|
11143
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateBaseClass(), arg.name || arg);
|
11144
|
-
}
|
11145
|
-
classType.details.baseClasses.push(argType);
|
11146
|
-
if ((0, types_1.isInstantiableClass)(argType)) {
|
11147
|
-
if (types_1.ClassType.isEnumClass(argType)) {
|
11148
|
-
classType.details.flags |= 1048576 /* EnumClass */;
|
11280
|
+
else if (arg.name.value === 'metaclass') {
|
11281
|
+
if (metaclassNode) {
|
11282
|
+
addError(localize_1.Localizer.Diagnostic.metaclassDuplicate(), arg);
|
11149
11283
|
}
|
11150
|
-
|
11151
|
-
|
11152
|
-
// protocol classes because these are known not to contain any abstract methods
|
11153
|
-
// and getAbstractMethods causes problems because of dependencies on some of these
|
11154
|
-
// built-in protocol classes.
|
11155
|
-
if (types_1.ClassType.supportsAbstractMethods(argType) ||
|
11156
|
-
(types_1.ClassType.isProtocolClass(argType) && !types_1.ClassType.isBuiltIn(argType))) {
|
11157
|
-
classType.details.flags |= 1024 /* SupportsAbstractMethods */;
|
11284
|
+
else {
|
11285
|
+
metaclassNode = arg.valueExpression;
|
11158
11286
|
}
|
11159
|
-
|
11160
|
-
|
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);
|
11161
11295
|
}
|
11162
|
-
if (
|
11163
|
-
|
11164
|
-
|
11296
|
+
else if (arg.name.value === 'total' && !constArgValue) {
|
11297
|
+
classType.details.flags |= 256 /* CanOmitDictValues */;
|
11298
|
+
}
|
11299
|
+
else if (arg.name.value === 'readonly' && constArgValue) {
|
11300
|
+
classType.details.flags |= 512 /* DictValuesReadOnly */;
|
11165
11301
|
}
|
11166
11302
|
}
|
11167
|
-
|
11168
|
-
|
11169
|
-
|
11170
|
-
|
11171
|
-
|
11172
|
-
|
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;
|
11173
11322
|
}
|
11174
|
-
else {
|
11175
|
-
|
11176
|
-
if (protocolTypeParameters) {
|
11177
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.duplicateGenericAndProtocolBase(), arg.valueExpression);
|
11178
|
-
}
|
11179
|
-
genericTypeParameters = [];
|
11180
|
-
(0, typeUtils_1.addTypeVarsToListIfUnique)(genericTypeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(argType));
|
11181
|
-
}
|
11323
|
+
else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
|
11324
|
+
foundIllegalBaseClass = true;
|
11182
11325
|
}
|
11183
11326
|
}
|
11184
|
-
|
11185
|
-
|
11186
|
-
|
11187
|
-
|
11188
|
-
|
11189
|
-
|
11190
|
-
|
11191
|
-
|
11192
|
-
|
11193
|
-
|
11194
|
-
|
11195
|
-
|
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
|
+
});
|
11196
11419
|
}
|
11197
11420
|
}
|
11198
11421
|
}
|
11199
11422
|
}
|
11200
11423
|
}
|
11201
|
-
|
11202
|
-
|
11203
|
-
|
11204
|
-
|
11205
|
-
|
11206
|
-
|
11207
|
-
|
11208
|
-
}
|
11209
|
-
else if (types_1.ClassType.isTypedDictClass(classType) &&
|
11210
|
-
(arg.name.value === 'total' || arg.name.value === 'readonly')) {
|
11211
|
-
// The "total" and "readonly" parameters apply only for TypedDict classes.
|
11212
|
-
// PEP 589 specifies that the parameter must be either True or False.
|
11213
|
-
const constArgValue = (0, staticExpressions_1.evaluateStaticBoolExpression)(arg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
|
11214
|
-
if (constArgValue === undefined) {
|
11215
|
-
addError(localize_1.Localizer.Diagnostic.typedDictBoolParam().format({ name: arg.name.value }), arg.valueExpression);
|
11216
|
-
}
|
11217
|
-
else if (arg.name.value === 'total' && !constArgValue) {
|
11218
|
-
classType.details.flags |= 256 /* CanOmitDictValues */;
|
11219
|
-
}
|
11220
|
-
else if (arg.name.value === 'readonly' && constArgValue) {
|
11221
|
-
classType.details.flags |= 512 /* DictValuesReadOnly */;
|
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 */;
|
11222
11431
|
}
|
11223
11432
|
}
|
11224
|
-
|
11225
|
-
|
11226
|
-
|
11227
|
-
|
11228
|
-
|
11229
|
-
|
11230
|
-
name: arg.name,
|
11231
|
-
valueExpression: arg.valueExpression,
|
11232
|
-
});
|
11233
|
-
}
|
11234
|
-
});
|
11235
|
-
// Check for NamedTuple multiple inheritance.
|
11236
|
-
if (classType.details.baseClasses.length > 1) {
|
11237
|
-
let derivesFromNamedTuple = false;
|
11238
|
-
let foundIllegalBaseClass = false;
|
11239
|
-
classType.details.baseClasses.forEach((baseClass) => {
|
11240
|
-
if ((0, types_1.isInstantiableClass)(baseClass)) {
|
11241
|
-
if (types_1.ClassType.isBuiltIn(baseClass, 'NamedTuple')) {
|
11242
|
-
derivesFromNamedTuple = true;
|
11243
|
-
}
|
11244
|
-
else if (!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
|
11245
|
-
foundIllegalBaseClass = 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);
|
11246
11439
|
}
|
11247
|
-
|
11248
|
-
|
11249
|
-
|
11250
|
-
|
11251
|
-
|
11252
|
-
|
11253
|
-
|
11254
|
-
// recursion will result.
|
11255
|
-
if (!types_1.ClassType.isBuiltIn(classType, 'object') &&
|
11256
|
-
classType.details.baseClasses.filter((baseClass) => (0, types_1.isClass)(baseClass)).length === 0) {
|
11257
|
-
// If there are no other (known) base classes, the class implicitly derives from object.
|
11258
|
-
classType.details.baseClasses.push(getBuiltInType(node, 'object'));
|
11259
|
-
}
|
11260
|
-
// If genericTypeParameters or protocolTypeParameters are provided,
|
11261
|
-
// make sure that typeParameters is a proper subset.
|
11262
|
-
genericTypeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : protocolTypeParameters;
|
11263
|
-
if (genericTypeParameters && !node.typeParameters) {
|
11264
|
-
verifyGenericTypeParameters(node.name, typeParameters, genericTypeParameters);
|
11265
|
-
}
|
11266
|
-
classType.details.typeParameters = genericTypeParameters !== null && genericTypeParameters !== void 0 ? genericTypeParameters : typeParameters;
|
11267
|
-
// Determine if one or more type parameters is autovariance.
|
11268
|
-
if (classType.details.typeParameters.some((param) => param.details.declaredVariance === 0 /* Auto */ && param.computedVariance === undefined)) {
|
11269
|
-
classType.details.requiresVarianceInference = true;
|
11270
|
-
}
|
11271
|
-
// Make sure there's at most one variadic type parameter.
|
11272
|
-
const variadics = classType.details.typeParameters.filter((param) => (0, types_1.isVariadicTypeVar)(param));
|
11273
|
-
if (variadics.length > 1) {
|
11274
|
-
addError(localize_1.Localizer.Diagnostic.variadicTypeParamTooManyClass().format({
|
11275
|
-
names: variadics.map((v) => `"${v.details.name}"`).join(', '),
|
11276
|
-
}), node.name, textRange_1.TextRange.combine(node.arguments) || node.name);
|
11277
|
-
}
|
11278
|
-
// Validate the default types for all type parameters.
|
11279
|
-
classType.details.typeParameters.forEach((typeParam, index) => {
|
11280
|
-
var _a;
|
11281
|
-
let bestErrorNode = node.name;
|
11282
|
-
if (node.typeParameters && index < node.typeParameters.parameters.length) {
|
11283
|
-
const typeParamNode = node.typeParameters.parameters[index];
|
11284
|
-
bestErrorNode = (_a = typeParamNode.defaultExpression) !== null && _a !== void 0 ? _a : typeParamNode.name;
|
11285
|
-
}
|
11286
|
-
validateTypeParameterDefault(bestErrorNode, typeParam, classType.details.typeParameters.slice(0, index));
|
11287
|
-
});
|
11288
|
-
if (!(0, typeUtils_1.computeMroLinearization)(classType)) {
|
11289
|
-
addError(localize_1.Localizer.Diagnostic.methodOrdering(), node.name);
|
11290
|
-
}
|
11291
|
-
// The scope for this class becomes the "fields" for the corresponding type.
|
11292
|
-
const innerScope = ScopeUtils.getScopeForNode(node.suite);
|
11293
|
-
classType.details.fields = (innerScope === null || innerScope === void 0 ? void 0 : innerScope.symbolTable)
|
11294
|
-
? new Map(innerScope.symbolTable)
|
11295
|
-
: new Map();
|
11296
|
-
// Determine whether the class should inherit __hash__. If a class defines
|
11297
|
-
// __eq__ but doesn't define __hash__ then __hash__ is set to None.
|
11298
|
-
if (classType.details.fields.has('__eq__') && !classType.details.fields.has('__hash__')) {
|
11299
|
-
classType.details.fields.set('__hash__', symbol_1.Symbol.createWithType(4 /* ClassMember */ | 128 /* ClassVar */ | 64 /* IgnoredForProtocolMatch */, types_1.NoneType.createInstance()));
|
11300
|
-
}
|
11301
|
-
// Determine whether the class's instance variables are constrained
|
11302
|
-
// to those defined by __slots__. We need to do this prior to dataclass
|
11303
|
-
// processing because dataclasses can implicitly add to the slots
|
11304
|
-
// list.
|
11305
|
-
const slotsNames = innerScope === null || innerScope === void 0 ? void 0 : innerScope.getSlotsNames();
|
11306
|
-
if (slotsNames) {
|
11307
|
-
classType.details.localSlotsNames = slotsNames;
|
11308
|
-
}
|
11309
|
-
// Determine if the class should be a "pseudo-generic" class, characterized
|
11310
|
-
// by having an __init__ method with parameters that lack type annotations.
|
11311
|
-
// For such classes, we'll treat them as generic, with the type arguments provided
|
11312
|
-
// by the callers of the constructor.
|
11313
|
-
if (!fileInfo.isStubFile && classType.details.typeParameters.length === 0) {
|
11314
|
-
const initMethod = classType.details.fields.get('__init__');
|
11315
|
-
if (initMethod) {
|
11316
|
-
const initDecls = initMethod.getTypedDeclarations();
|
11317
|
-
if (initDecls.length === 1 && initDecls[0].type === 5 /* Function */) {
|
11318
|
-
const initDeclNode = initDecls[0].node;
|
11319
|
-
const initParams = initDeclNode.parameters;
|
11320
|
-
if (initParams.length > 1 &&
|
11321
|
-
!initParams.some((param, index) => !!ParseTreeUtils.getTypeAnnotationForParameter(initDeclNode, index))) {
|
11322
|
-
const genericParams = initParams.filter((param, index) => index > 0 &&
|
11323
|
-
param.name &&
|
11324
|
-
param.category === 0 /* Simple */ &&
|
11325
|
-
!param.defaultValue);
|
11326
|
-
if (genericParams.length > 0) {
|
11327
|
-
classType.details.flags |= 16384 /* PseudoGenericClass */;
|
11328
|
-
// Create a type parameter for each simple, named parameter
|
11329
|
-
// in the __init__ method.
|
11330
|
-
classType.details.typeParameters = genericParams.map((param) => {
|
11331
|
-
const typeVar = types_1.TypeVarType.createInstance(getPseudoGenericTypeVarName(param.name.value));
|
11332
|
-
typeVar.details.isSynthesized = true;
|
11333
|
-
typeVar.scopeId = ParseTreeUtils.getScopeIdForNode(initDeclNode);
|
11334
|
-
typeVar.details.boundType = types_1.UnknownType.create();
|
11335
|
-
return types_1.TypeVarType.cloneForScopeId(typeVar, ParseTreeUtils.getScopeIdForNode(node), node.name.value, 0 /* Class */);
|
11336
|
-
});
|
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 */;
|
11337
11447
|
}
|
11338
11448
|
}
|
11339
11449
|
}
|
11340
11450
|
}
|
11341
|
-
|
11342
|
-
|
11343
|
-
|
11344
|
-
|
11345
|
-
|
11346
|
-
|
11347
|
-
|
11348
|
-
|
11349
|
-
|
11350
|
-
|
11351
|
-
|
11352
|
-
|
11353
|
-
|
11354
|
-
|
11355
|
-
|
11356
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.metaclassIsGeneric(), metaclassNode);
|
11357
|
-
}
|
11358
|
-
classType.details.declaredMetaclass = metaclassType;
|
11359
|
-
if ((0, types_1.isInstantiableClass)(metaclassType)) {
|
11360
|
-
if (types_1.ClassType.isBuiltIn(metaclassType, 'EnumMeta')) {
|
11361
|
-
classType.details.flags |= 1048576 /* EnumClass */;
|
11362
|
-
}
|
11363
|
-
else if (types_1.ClassType.isBuiltIn(metaclassType, 'ABCMeta')) {
|
11364
|
-
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;
|
11365
11466
|
}
|
11366
11467
|
}
|
11367
|
-
|
11368
|
-
|
11369
|
-
|
11370
|
-
// Clear the "partially constructed" flag.
|
11371
|
-
classType.details.flags &= ~131072 /* PartiallyEvaluated */;
|
11372
|
-
// Now determine the decorated type of the class.
|
11373
|
-
let decoratedType = classType;
|
11374
|
-
let foundUnknown = false;
|
11375
|
-
for (let i = node.decorators.length - 1; i >= 0; i--) {
|
11376
|
-
const decorator = node.decorators[i];
|
11377
|
-
const newDecoratedType = (0, decorators_1.applyClassDecorator)(evaluatorInterface, decoratedType, classType, decorator);
|
11378
|
-
const unknownOrAny = (0, typeUtils_1.containsAnyOrUnknown)(newDecoratedType, /* recurse */ false);
|
11379
|
-
if (unknownOrAny && (0, types_1.isUnknown)(unknownOrAny)) {
|
11380
|
-
// Report this error only on the first unknown type.
|
11381
|
-
if (!foundUnknown) {
|
11382
|
-
addDiagnostic(fileInfo.diagnosticRuleSet.reportUntypedClassDecorator, diagnosticRules_1.DiagnosticRule.reportUntypedClassDecorator, localize_1.Localizer.Diagnostic.classDecoratorTypeUnknown(), node.decorators[i].expression);
|
11383
|
-
foundUnknown = true;
|
11468
|
+
else {
|
11469
|
+
// Apply the decorator only if the type is known.
|
11470
|
+
decoratedType = newDecoratedType;
|
11384
11471
|
}
|
11385
11472
|
}
|
11386
|
-
|
11387
|
-
|
11388
|
-
|
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;
|
11389
11478
|
}
|
11390
|
-
|
11391
|
-
|
11392
|
-
|
11393
|
-
|
11394
|
-
|
11395
|
-
|
11396
|
-
|
11397
|
-
|
11398
|
-
|
11399
|
-
|
11400
|
-
|
11401
|
-
|
11402
|
-
|
11403
|
-
|
11404
|
-
|
11405
|
-
|
11406
|
-
|
11407
|
-
|
11408
|
-
|
11409
|
-
(
|
11410
|
-
|
11411
|
-
|
11412
|
-
|
11413
|
-
|
11414
|
-
|
11415
|
-
|
11416
|
-
|
11417
|
-
|
11418
|
-
|
11419
|
-
|
11420
|
-
|
11421
|
-
|
11422
|
-
|
11423
|
-
|
11424
|
-
|
11425
|
-
|
11426
|
-
|
11427
|
-
|
11428
|
-
|
11429
|
-
|
11430
|
-
|
11431
|
-
|
11432
|
-
}
|
11433
|
-
|
11434
|
-
|
11435
|
-
if (
|
11436
|
-
|
11437
|
-
|
11438
|
-
|
11439
|
-
|
11440
|
-
|
11441
|
-
|
11442
|
-
|
11443
|
-
|
11444
|
-
|
11445
|
-
|
11446
|
-
|
11447
|
-
|
11448
|
-
|
11449
|
-
!types_1.ClassType.isBuiltIn(baseClass, 'Generic')) {
|
11450
|
-
if (baseClass.details.inheritedSlotsNames === undefined) {
|
11451
|
-
isLimitedToSlots = false;
|
11452
|
-
}
|
11453
|
-
else {
|
11454
|
-
(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
|
+
}
|
11455
11538
|
}
|
11456
11539
|
}
|
11540
|
+
else {
|
11541
|
+
isLimitedToSlots = false;
|
11542
|
+
}
|
11543
|
+
});
|
11544
|
+
if (isLimitedToSlots) {
|
11545
|
+
classType.details.inheritedSlotsNames = extendedSlotsNames;
|
11457
11546
|
}
|
11458
|
-
else {
|
11459
|
-
isLimitedToSlots = false;
|
11460
|
-
}
|
11461
|
-
});
|
11462
|
-
if (isLimitedToSlots) {
|
11463
|
-
classType.details.inheritedSlotsNames = extendedSlotsNames;
|
11464
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;
|
11465
11561
|
}
|
11466
|
-
// Update the undecorated class type.
|
11467
|
-
writeTypeCache(node.name, { type: classType }, 0 /* None */);
|
11468
|
-
// Update the decorated class type.
|
11469
|
-
writeTypeCache(node, { type: decoratedType }, 0 /* None */);
|
11470
|
-
return { classType, decoratedType };
|
11471
11562
|
}
|
11472
11563
|
// Determines whether the type parameters has a default that refers to another
|
11473
11564
|
// type parameter. If so, validates that it is in the list of "live" type
|
@@ -15720,6 +15811,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15720
15811
|
const variance = destTypeParam ? types_1.TypeVarType.getVariance(destTypeParam) : 3 /* Covariant */;
|
15721
15812
|
let effectiveFlags;
|
15722
15813
|
let errorSource;
|
15814
|
+
let includeDiagAddendum = true;
|
15723
15815
|
if (variance === 3 /* Covariant */) {
|
15724
15816
|
effectiveFlags = flags | 128 /* RetainLiteralsForTypeVar */;
|
15725
15817
|
errorSource = localize_1.Localizer.DiagnosticAddendum.typeVarIsCovariant;
|
@@ -15732,6 +15824,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15732
15824
|
else {
|
15733
15825
|
effectiveFlags = flags | 1 /* EnforceInvariance */ | 128 /* RetainLiteralsForTypeVar */;
|
15734
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;
|
15735
15830
|
}
|
15736
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)) {
|
15737
15832
|
// Don't report errors with type variables in "pseudo-random"
|
@@ -15744,6 +15839,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15744
15839
|
name: types_1.TypeVarType.getReadableName(destTypeParam),
|
15745
15840
|
...printSrcDestTypes(srcTypeArg, destTypeArg),
|
15746
15841
|
}));
|
15842
|
+
if (includeDiagAddendum) {
|
15843
|
+
childDiag.addAddendum(assignmentDiag);
|
15844
|
+
}
|
15747
15845
|
}
|
15748
15846
|
else {
|
15749
15847
|
diag.addAddendum(assignmentDiag);
|
@@ -16965,7 +17063,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16965
17063
|
}
|
16966
17064
|
}
|
16967
17065
|
}
|
16968
|
-
else {
|
17066
|
+
else if (!srcParamDetails.paramSpec) {
|
16969
17067
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.functionTooManyParams().format({
|
16970
17068
|
expected: srcPositionalCount,
|
16971
17069
|
received: destPositionalCount,
|