@zzzen/pyright-internal 1.2.0-dev.20231105 → 1.2.0-dev.20231119
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.d.ts +1 -0
- package/dist/analyzer/checker.js +76 -77
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/codeFlowEngine.js +12 -33
- package/dist/analyzer/codeFlowEngine.js.map +1 -1
- package/dist/analyzer/constraintSolver.js +30 -21
- package/dist/analyzer/constraintSolver.js.map +1 -1
- package/dist/analyzer/constructorTransform.js +3 -5
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/constructors.d.ts +6 -3
- package/dist/analyzer/constructors.js +53 -29
- package/dist/analyzer/constructors.js.map +1 -1
- package/dist/analyzer/dataClasses.js +10 -15
- package/dist/analyzer/dataClasses.js.map +1 -1
- package/dist/analyzer/declarationUtils.js +6 -3
- package/dist/analyzer/declarationUtils.js.map +1 -1
- package/dist/analyzer/decorators.js +1 -1
- package/dist/analyzer/decorators.js.map +1 -1
- package/dist/analyzer/docStringConversion.js +1 -1
- package/dist/analyzer/docStringConversion.js.map +1 -1
- package/dist/analyzer/docStringUtils.js +1 -1
- package/dist/analyzer/enums.js +1 -1
- package/dist/analyzer/enums.js.map +1 -1
- package/dist/analyzer/importResolver.d.ts +2 -1
- package/dist/analyzer/importResolver.js +23 -6
- package/dist/analyzer/importResolver.js.map +1 -1
- package/dist/analyzer/importStatementUtils.d.ts +1 -1
- package/dist/analyzer/importStatementUtils.js +33 -5
- package/dist/analyzer/importStatementUtils.js.map +1 -1
- package/dist/analyzer/operations.js +12 -6
- package/dist/analyzer/operations.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +9 -5
- package/dist/analyzer/packageTypeVerifier.js.map +1 -1
- package/dist/analyzer/parseTreeUtils.d.ts +1 -0
- package/dist/analyzer/parseTreeUtils.js +17 -2
- package/dist/analyzer/parseTreeUtils.js.map +1 -1
- package/dist/analyzer/patternMatching.js +20 -15
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.js +19 -12
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/properties.js +20 -23
- package/dist/analyzer/properties.js.map +1 -1
- package/dist/analyzer/protocols.d.ts +1 -1
- package/dist/analyzer/protocols.js +14 -18
- package/dist/analyzer/protocols.js.map +1 -1
- package/dist/analyzer/service.js +1 -2
- package/dist/analyzer/service.js.map +1 -1
- package/dist/analyzer/sourceFile.js +33 -2
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/sourceFileInfoUtils.d.ts +1 -1
- package/dist/analyzer/sourceFileInfoUtils.js +9 -3
- package/dist/analyzer/sourceFileInfoUtils.js.map +1 -1
- package/dist/analyzer/sourceMapper.js +3 -0
- package/dist/analyzer/sourceMapper.js.map +1 -1
- package/dist/analyzer/typeEvaluator.d.ts +3 -1
- package/dist/analyzer/typeEvaluator.js +561 -574
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +2 -2
- package/dist/analyzer/typeGuards.js +26 -11
- package/dist/analyzer/typeGuards.js.map +1 -1
- package/dist/analyzer/typeUtils.js +43 -1
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typeVarContext.d.ts +1 -0
- package/dist/analyzer/typeVarContext.js +3 -0
- package/dist/analyzer/typeVarContext.js.map +1 -1
- package/dist/analyzer/types.d.ts +4 -2
- package/dist/analyzer/types.js +13 -5
- package/dist/analyzer/types.js.map +1 -1
- package/dist/common/configOptions.d.ts +2 -1
- package/dist/common/configOptions.js +18 -1
- package/dist/common/configOptions.js.map +1 -1
- package/dist/common/extensibility.d.ts +3 -0
- package/dist/common/serviceProviderExtensions.d.ts +2 -1
- package/dist/common/serviceProviderExtensions.js +1 -0
- package/dist/common/serviceProviderExtensions.js.map +1 -1
- package/dist/common/textEditTracker.js +2 -2
- package/dist/common/textEditTracker.js.map +1 -1
- package/dist/languageServerBase.d.ts +4 -4
- package/dist/languageServerBase.js +10 -7
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +2 -1
- package/dist/languageService/completionProvider.js +9 -13
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/localization/localize.d.ts +7 -3
- package/dist/localization/localize.js +5 -1
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.cs.json +5 -2
- package/dist/localization/package.nls.de.json +5 -2
- package/dist/localization/package.nls.en-us.json +11 -7
- package/dist/localization/package.nls.es.json +5 -2
- package/dist/localization/package.nls.fr.json +5 -2
- package/dist/localization/package.nls.it.json +5 -2
- package/dist/localization/package.nls.ja.json +5 -2
- package/dist/localization/package.nls.ko.json +5 -2
- package/dist/localization/package.nls.pl.json +5 -2
- package/dist/localization/package.nls.pt-br.json +5 -2
- package/dist/localization/package.nls.qps-ploc.json +5 -2
- package/dist/localization/package.nls.ru.json +5 -2
- package/dist/localization/package.nls.tr.json +5 -2
- package/dist/localization/package.nls.zh-cn.json +5 -2
- package/dist/localization/package.nls.zh-tw.json +5 -2
- package/dist/pyright.js +17 -1
- package/dist/pyright.js.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tests/config.test.js +7 -5
- package/dist/tests/config.test.js.map +1 -1
- package/dist/tests/diagnosticOverrides.test.js +4 -2
- package/dist/tests/diagnosticOverrides.test.js.map +1 -1
- package/dist/tests/docStringConversion.test.js +0 -22
- package/dist/tests/docStringConversion.test.js.map +1 -1
- package/dist/tests/fourslash/completions.params.fourslash.js +11 -0
- package/dist/tests/fourslash/completions.params.fourslash.js.map +1 -1
- package/dist/tests/fourslash/hover.docstring.split.fourslash.js +10 -0
- package/dist/tests/fourslash/hover.docstring.split.fourslash.js.map +1 -1
- package/dist/tests/fourslash/signature.dunderNew.fourslash.js +1 -1
- package/dist/tests/fourslash/signature.dunderNew.fourslash.js.map +1 -1
- package/dist/tests/harness/fourslash/testState.js +3 -3
- package/dist/tests/harness/fourslash/testState.js.map +1 -1
- package/dist/tests/parseTreeUtils.test.js +15 -0
- package/dist/tests/parseTreeUtils.test.js.map +1 -1
- package/dist/tests/textEditUtil.test.js +25 -0
- package/dist/tests/textEditUtil.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +8 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +12 -0
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator3.test.js +3 -3
- package/dist/tests/typeEvaluator4.test.js +6 -6
- package/package.json +1 -1
@@ -617,7 +617,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
617
617
|
break;
|
618
618
|
}
|
619
619
|
case 4 /* AssignmentExpression */: {
|
620
|
-
typeResult = getTypeOfExpression(node.rightExpression);
|
620
|
+
typeResult = getTypeOfExpression(node.rightExpression, flags, inferenceContext);
|
621
621
|
assignTypeToExpression(node.name, typeResult.type, !!typeResult.isIncomplete, node.rightExpression,
|
622
622
|
/* ignoreEmptyContainers */ true);
|
623
623
|
break;
|
@@ -1297,9 +1297,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1297
1297
|
// using the objectType parameter. Callers can specify these separately
|
1298
1298
|
// to handle the case where we're fetching the object member from a
|
1299
1299
|
// metaclass but binding to the class.
|
1300
|
-
function
|
1300
|
+
function getTypeOfBoundMember(errorNode, objectType, memberName, usage = { method: 'get' }, diag = undefined, flags = 0 /* Default */, selfType, recursionCount = 0) {
|
1301
1301
|
if (types_1.ClassType.isPartiallyEvaluated(objectType)) {
|
1302
|
-
|
1302
|
+
if (errorNode) {
|
1303
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.classDefinitionCycle().format({ name: objectType.details.name }), errorNode);
|
1304
|
+
}
|
1303
1305
|
return { type: types_1.UnknownType.create() };
|
1304
1306
|
}
|
1305
1307
|
// Determine the class that was used to instantiate the objectType.
|
@@ -1357,7 +1359,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1357
1359
|
effectiveFlags &= ~16 /* SkipInstanceMembers */;
|
1358
1360
|
}
|
1359
1361
|
const metaclassDiag = diag ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
1360
|
-
memberInfo = getTypeOfClassMemberName(errorNode, types_1.ClassType.cloneAsInstance(metaclass), memberName, usage, metaclassDiag, effectiveFlags, objectTypeIsInstantiable ? objectType : types_1.ClassType.cloneAsInstantiable(objectType));
|
1362
|
+
memberInfo = getTypeOfClassMemberName(errorNode, types_1.ClassType.cloneAsInstance(metaclass), memberName, usage, metaclassDiag, effectiveFlags, objectTypeIsInstantiable ? objectType : types_1.ClassType.cloneAsInstantiable(objectType), recursionCount);
|
1361
1363
|
// If there was a descriptor error (as opposed to an error where the members
|
1362
1364
|
// was simply not found), use this diagnostic message.
|
1363
1365
|
if (memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isDescriptorError) {
|
@@ -1378,20 +1380,25 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1378
1380
|
}
|
1379
1381
|
return undefined;
|
1380
1382
|
}
|
1381
|
-
function
|
1382
|
-
|
1383
|
-
|
1383
|
+
function getBoundMagicMethod(classType, memberName, selfType, recursionCount = 0) {
|
1384
|
+
if (recursionCount > types_1.maxTypeRecursionCount) {
|
1385
|
+
return undefined;
|
1386
|
+
}
|
1387
|
+
recursionCount++;
|
1388
|
+
const boundMethodResult = getTypeOfBoundMember(
|
1389
|
+
/* errorNode */ undefined, classType, memberName,
|
1390
|
+
/* usage */ undefined,
|
1391
|
+
/* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */, selfType, recursionCount);
|
1392
|
+
if (!boundMethodResult || boundMethodResult.typeErrors) {
|
1384
1393
|
return undefined;
|
1385
1394
|
}
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
/* selfType */ undefined,
|
1392
|
-
/* diag */ undefined, recursionCount);
|
1395
|
+
if ((0, types_1.isFunction)(boundMethodResult.type) || (0, types_1.isOverloadedFunction)(boundMethodResult.type)) {
|
1396
|
+
return boundMethodResult.type;
|
1397
|
+
}
|
1398
|
+
if ((0, types_1.isClassInstance)(boundMethodResult.type)) {
|
1399
|
+
return getBoundMagicMethod(boundMethodResult.type, '__call__', selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType), recursionCount);
|
1393
1400
|
}
|
1394
|
-
if ((0, types_1.isAnyOrUnknown)(
|
1401
|
+
if ((0, types_1.isAnyOrUnknown)(boundMethodResult.type)) {
|
1395
1402
|
const unknownFunction = types_1.FunctionType.createSynthesizedInstance('', 32768 /* SkipArgsKwargsCompatibilityCheck */);
|
1396
1403
|
types_1.FunctionType.addDefaultParameters(unknownFunction);
|
1397
1404
|
return unknownFunction;
|
@@ -1472,35 +1479,39 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1472
1479
|
}
|
1473
1480
|
case 6 /* Class */: {
|
1474
1481
|
if (types_1.TypeBase.isInstantiable(subtype)) {
|
1475
|
-
let
|
1482
|
+
let constructorType;
|
1476
1483
|
// Try to get the `__init__` method first because it typically has more
|
1477
1484
|
// type information than `__new__`.
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
const
|
1485
|
+
const initMethodResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, callNode, types_1.ClassType.cloneAsInstance(subtype),
|
1486
|
+
/* skipObjectBase */ false);
|
1487
|
+
if (initMethodResult && !initMethodResult.typeErrors && (0, types_1.isFunction)(initMethodResult.type)) {
|
1488
|
+
constructorType = initMethodResult.type;
|
1489
|
+
}
|
1490
|
+
const isObjectInit = constructorType &&
|
1491
|
+
(0, types_1.isFunction)(constructorType) &&
|
1492
|
+
constructorType.details.fullName === 'builtins.object.__init__';
|
1493
|
+
const isDefaultParams = constructorType &&
|
1494
|
+
(0, types_1.isFunction)(constructorType) &&
|
1495
|
+
types_1.FunctionType.hasDefaultParameters(constructorType);
|
1484
1496
|
// If there was no `__init__` or the only `__init__` that was found was from
|
1485
1497
|
// the `object` class or accepts only default parameters(* args, ** kwargs),
|
1486
1498
|
// see if we can find a better signature from the `__new__` method.
|
1487
|
-
if (!
|
1488
|
-
const
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
}
|
1499
|
+
if (!constructorType || isObjectInit || isDefaultParams) {
|
1500
|
+
const newMethodResult = (0, constructors_1.getBoundNewMethod)(evaluatorInterface, callNode, subtype,
|
1501
|
+
/* skipObjectBase */ false);
|
1502
|
+
if (newMethodResult &&
|
1503
|
+
!newMethodResult.typeErrors &&
|
1504
|
+
(0, types_1.isFunction)(newMethodResult.type) &&
|
1505
|
+
newMethodResult.type.details.fullName !== 'builtins.object.__new__') {
|
1506
|
+
constructorType = newMethodResult.type;
|
1496
1507
|
}
|
1497
1508
|
}
|
1498
|
-
if (
|
1499
|
-
addFunctionToSignature(
|
1509
|
+
if (constructorType) {
|
1510
|
+
addFunctionToSignature(constructorType);
|
1500
1511
|
}
|
1501
1512
|
}
|
1502
1513
|
else {
|
1503
|
-
const methodType =
|
1514
|
+
const methodType = getBoundMagicMethod(subtype, '__call__');
|
1504
1515
|
if (methodType) {
|
1505
1516
|
addFunctionToSignature(methodType);
|
1506
1517
|
}
|
@@ -1635,20 +1646,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1635
1646
|
case 24 /* Index */: {
|
1636
1647
|
const baseType = makeTopLevelTypeVarsConcrete(getTypeOfExpression(expression.baseExpression, 2 /* IndexBaseDefaults */).type);
|
1637
1648
|
if (baseType && (0, types_1.isClassInstance)(baseType)) {
|
1638
|
-
const
|
1639
|
-
if (
|
1640
|
-
const
|
1641
|
-
if ((0, types_1.
|
1642
|
-
|
1643
|
-
/* treatConstructorAsClassMember */ false);
|
1644
|
-
if (boundFunction && (0, types_1.isFunction)(boundFunction)) {
|
1645
|
-
if (boundFunction.details.parameters.length >= 2) {
|
1646
|
-
const paramType = types_1.FunctionType.getEffectiveParameterType(boundFunction, 1);
|
1647
|
-
if (!(0, types_1.isAnyOrUnknown)(paramType)) {
|
1648
|
-
return paramType;
|
1649
|
-
}
|
1650
|
-
}
|
1651
|
-
}
|
1649
|
+
const setItemType = getBoundMagicMethod(baseType, '__setitem__');
|
1650
|
+
if (setItemType && (0, types_1.isFunction)(setItemType) && setItemType.details.parameters.length >= 2) {
|
1651
|
+
const paramType = types_1.FunctionType.getEffectiveParameterType(setItemType, 1);
|
1652
|
+
if (!(0, types_1.isAnyOrUnknown)(paramType)) {
|
1653
|
+
return paramType;
|
1652
1654
|
}
|
1653
1655
|
}
|
1654
1656
|
else if (types_1.ClassType.isTypedDictClass(baseType)) {
|
@@ -1666,14 +1668,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1666
1668
|
if (declaredType) {
|
1667
1669
|
// If it's a descriptor, we need to get the setter type.
|
1668
1670
|
if (useDescriptorSetterType && (0, types_1.isClassInstance)(declaredType)) {
|
1669
|
-
const
|
1670
|
-
|
1671
|
-
|
1672
|
-
declaredType = setter.details.parameters[2].type;
|
1673
|
-
if ((0, types_1.isClass)(setterInfo.classType)) {
|
1674
|
-
const typeVarMap = (0, typeUtils_1.buildTypeVarContextFromSpecializedClass)(setterInfo.classType);
|
1675
|
-
declaredType = (0, typeUtils_1.applySolvedTypeVars)(declaredType, typeVarMap);
|
1676
|
-
}
|
1671
|
+
const setter = getBoundMagicMethod(declaredType, '__set__');
|
1672
|
+
if (setter && (0, types_1.isFunction)(setter) && setter.details.parameters.length >= 2) {
|
1673
|
+
declaredType = setter.details.parameters[1].type;
|
1677
1674
|
if ((0, types_1.isAnyOrUnknown)(declaredType)) {
|
1678
1675
|
return undefined;
|
1679
1676
|
}
|
@@ -1685,8 +1682,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
1685
1682
|
}
|
1686
1683
|
if ((0, types_1.isFunction)(declaredType) || (0, types_1.isOverloadedFunction)(declaredType)) {
|
1687
1684
|
if (bindFunction) {
|
1688
|
-
declaredType =
|
1689
|
-
/* memberAccessClass */ undefined, expression);
|
1685
|
+
declaredType = bindFunctionToClassOrObject(classOrObjectBase, declaredType);
|
1690
1686
|
}
|
1691
1687
|
}
|
1692
1688
|
}
|
@@ -3323,7 +3319,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3323
3319
|
}
|
3324
3320
|
if (typeParametersForScope) {
|
3325
3321
|
const match = typeParametersForScope.find((typeVar) => typeVar.details.name === type.details.name);
|
3326
|
-
if (match === null || match === void 0 ? void 0 : match.scopeId) {
|
3322
|
+
if ((match === null || match === void 0 ? void 0 : match.scopeId) !== undefined && match.scopeName !== undefined && match.scopeType !== undefined) {
|
3327
3323
|
// Use the scoped version of the TypeVar rather than the (unscoped) original type.
|
3328
3324
|
type = types_1.TypeVarType.cloneForScopeId(type, match.scopeId, match.scopeName, match.scopeType);
|
3329
3325
|
return {
|
@@ -3559,7 +3555,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3559
3555
|
}, usage, 0 /* None */);
|
3560
3556
|
}
|
3561
3557
|
case 6 /* Class */: {
|
3562
|
-
const typeResult = (_a = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete)) !== null && _a !== void 0 ? _a :
|
3558
|
+
const typeResult = (_a = (0, enums_1.getTypeOfEnumMember)(evaluatorInterface, node, baseType, memberName, isIncomplete)) !== null && _a !== void 0 ? _a : getTypeOfBoundMember(node.memberName, baseType, memberName, usage, diag,
|
3563
3559
|
/* memberAccessFlags */ undefined, baseTypeResult.bindToSelfType);
|
3564
3560
|
if (typeResult) {
|
3565
3561
|
type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
|
@@ -3651,7 +3647,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3651
3647
|
return undefined;
|
3652
3648
|
}
|
3653
3649
|
if ((0, typeUtils_1.isNoneInstance)(subtype) && noneType && (0, types_1.isClassInstance)(noneType)) {
|
3654
|
-
const typeResult =
|
3650
|
+
const typeResult = getTypeOfBoundMember(node.memberName, noneType, memberName, usage, diag);
|
3655
3651
|
if (typeResult) {
|
3656
3652
|
type = (0, typeUtils_1.addConditionToType)(typeResult.type, (0, typeUtils_1.getTypeCondition)(baseType));
|
3657
3653
|
if (typeResult.isIncomplete) {
|
@@ -3732,8 +3728,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3732
3728
|
}
|
3733
3729
|
return { type, isIncomplete, isAsymmetricAccessor, isRequired, isNotRequired, memberAccessDeprecationInfo };
|
3734
3730
|
}
|
3735
|
-
function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType) {
|
3736
|
-
var _a, _b, _c
|
3731
|
+
function getTypeOfClassMemberName(errorNode, classType, memberName, usage, diag, flags, selfType, recursionCount = 0) {
|
3732
|
+
var _a, _b, _c;
|
3737
3733
|
const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
|
3738
3734
|
// Always look for a member with a declared type first.
|
3739
3735
|
let memberInfo = (0, typeUtils_1.lookUpClassMember)(classType, memberName, flags | 64 /* DeclaredTypesOnly */);
|
@@ -3746,8 +3742,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3746
3742
|
// No attribute of that name was found. If this is a member access
|
3747
3743
|
// through an object, see if there's an attribute access override
|
3748
3744
|
// method ("__getattr__", etc.).
|
3749
|
-
if ((flags & 512 /* SkipAttributeAccessOverride */) === 0) {
|
3750
|
-
const generalAttrType = applyAttributeAccessOverride(
|
3745
|
+
if ((flags & 512 /* SkipAttributeAccessOverride */) === 0 && errorNode) {
|
3746
|
+
const generalAttrType = applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType);
|
3751
3747
|
if (generalAttrType) {
|
3752
3748
|
return {
|
3753
3749
|
symbol: undefined,
|
@@ -3756,7 +3752,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3756
3752
|
isDescriptorError: false,
|
3757
3753
|
isClassMember: false,
|
3758
3754
|
isClassVar: false,
|
3759
|
-
isAsymmetricAccessor: generalAttrType.isAsymmetricAccessor,
|
3755
|
+
isAsymmetricAccessor: !!generalAttrType.isAsymmetricAccessor,
|
3760
3756
|
};
|
3761
3757
|
}
|
3762
3758
|
}
|
@@ -3770,7 +3766,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3770
3766
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberIsInitVar().format({ name: memberName }));
|
3771
3767
|
return undefined;
|
3772
3768
|
}
|
3773
|
-
if (usage.method !== 'get') {
|
3769
|
+
if (usage.method !== 'get' && errorNode) {
|
3774
3770
|
// If the usage indicates a 'set' or 'delete' and the access is within the
|
3775
3771
|
// class definition itself, use only the declared type to avoid circular
|
3776
3772
|
// type evaluation.
|
@@ -3805,23 +3801,16 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3805
3801
|
}
|
3806
3802
|
}
|
3807
3803
|
if (!type) {
|
3808
|
-
let selfClass
|
3809
|
-
// Determine whether to replace Self variables with a specific
|
3810
|
-
// class. Avoid doing this if there's a "selfType" specified
|
3811
|
-
// because that case is used for super() calls where we want
|
3812
|
-
// to leave the Self type generic (not specialized). We'll also
|
3813
|
-
// skip this for __new__ methods because they are not bound
|
3814
|
-
// to the class but rather assume the type of the cls argument.
|
3804
|
+
let selfClass;
|
3815
3805
|
if (selfType) {
|
3816
|
-
|
3817
|
-
selfClass = selfType;
|
3818
|
-
}
|
3819
|
-
else {
|
3820
|
-
selfClass = undefined;
|
3821
|
-
}
|
3806
|
+
selfClass = (0, typeUtils_1.convertToInstantiable)(selfType);
|
3822
3807
|
}
|
3823
|
-
else
|
3824
|
-
|
3808
|
+
else {
|
3809
|
+
// Skip this for __new__ methods because they are not bound
|
3810
|
+
// to the class but rather assume the type of the cls argument.
|
3811
|
+
if (memberName !== '__new__') {
|
3812
|
+
selfClass = classType;
|
3813
|
+
}
|
3825
3814
|
}
|
3826
3815
|
const typeResult = getTypeOfMemberInternal(memberInfo, selfClass);
|
3827
3816
|
type = (_c = typeResult === null || typeResult === void 0 ? void 0 : typeResult.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create();
|
@@ -3839,7 +3828,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3839
3828
|
}
|
3840
3829
|
if (usage.method === 'get') {
|
3841
3830
|
// Mark the member accessed if it's not coming from a parent class.
|
3842
|
-
if (
|
3831
|
+
if (errorNode &&
|
3832
|
+
(0, types_1.isInstantiableClass)(memberInfo.classType) &&
|
3843
3833
|
types_1.ClassType.isSameGenericClass(memberInfo.classType, classType)) {
|
3844
3834
|
setSymbolAccessed(AnalyzerNodeInfo.getFileInfo(errorNode), memberInfo.symbol, errorNode);
|
3845
3835
|
}
|
@@ -3852,32 +3842,96 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3852
3842
|
}
|
3853
3843
|
}
|
3854
3844
|
}
|
3855
|
-
|
3856
|
-
|
3857
|
-
|
3858
|
-
|
3859
|
-
|
3860
|
-
|
3861
|
-
|
3862
|
-
|
3863
|
-
|
3864
|
-
|
3865
|
-
|
3866
|
-
|
3867
|
-
|
3868
|
-
|
3869
|
-
|
3845
|
+
// If the member is a descriptor object, apply the descriptor protocol
|
3846
|
+
// now. If the member is an instance or class method, bind the method.
|
3847
|
+
let isDescriptorError = false;
|
3848
|
+
let isAsymmetricAccessor = false;
|
3849
|
+
let isDescriptorApplied = false;
|
3850
|
+
let memberAccessDeprecationInfo;
|
3851
|
+
type = (0, typeUtils_1.mapSubtypes)(type, (subtype) => {
|
3852
|
+
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
3853
|
+
const isClassMember = !memberInfo || memberInfo.isClassMember;
|
3854
|
+
let resultType;
|
3855
|
+
if ((0, types_1.isClass)(concreteSubtype) && isClassMember && errorNode) {
|
3856
|
+
const descResult = applyDescriptorAccessMethod(subtype, concreteSubtype, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag);
|
3857
|
+
if (descResult.isAsymmetricAccessor) {
|
3858
|
+
isAsymmetricAccessor = true;
|
3859
|
+
}
|
3860
|
+
if (descResult.memberAccessDeprecationInfo) {
|
3861
|
+
memberAccessDeprecationInfo = descResult.memberAccessDeprecationInfo;
|
3862
|
+
}
|
3863
|
+
if (descResult.typeErrors) {
|
3870
3864
|
isDescriptorError = true;
|
3871
3865
|
}
|
3872
|
-
if (
|
3873
|
-
|
3874
|
-
|
3875
|
-
|
3876
|
-
|
3877
|
-
|
3866
|
+
if (descResult.isDescriptorApplied) {
|
3867
|
+
isDescriptorApplied = true;
|
3868
|
+
}
|
3869
|
+
resultType = descResult.type;
|
3870
|
+
}
|
3871
|
+
else if ((0, types_1.isFunction)(concreteSubtype) || (0, types_1.isOverloadedFunction)(concreteSubtype)) {
|
3872
|
+
const typeResult = bindMethodForMemberAccess(subtype, concreteSubtype, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount);
|
3873
|
+
resultType = typeResult.type;
|
3874
|
+
if (typeResult.typeErrors) {
|
3875
|
+
isDescriptorError = true;
|
3876
|
+
}
|
3877
|
+
}
|
3878
|
+
else {
|
3879
|
+
resultType = subtype;
|
3880
|
+
}
|
3881
|
+
// If this is a "set" operation, we have a bit more work to do.
|
3882
|
+
if (usage.method !== 'set') {
|
3883
|
+
return resultType;
|
3884
|
+
}
|
3885
|
+
// Check for an attempt to overwrite a ClassVar member from an instance.
|
3886
|
+
if (!isDescriptorApplied &&
|
3887
|
+
(memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.isClassVar()) &&
|
3888
|
+
(flags & 128 /* DisallowClassVarWrites */) !== 0) {
|
3889
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
|
3890
|
+
isDescriptorError = true;
|
3891
|
+
}
|
3892
|
+
// Check for an attempt to overwrite a final member variable.
|
3893
|
+
const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
|
3894
|
+
if (finalVarTypeDecl &&
|
3895
|
+
errorNode &&
|
3896
|
+
!ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
|
3897
|
+
// If a Final instance variable is declared in the class body but is
|
3898
|
+
// being assigned within an __init__ method, it's allowed.
|
3899
|
+
const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
|
3900
|
+
if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
|
3901
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
|
3878
3902
|
isDescriptorError = true;
|
3879
3903
|
}
|
3880
3904
|
}
|
3905
|
+
// Check for an attempt to overwrite an instance variable that is
|
3906
|
+
// read-only (e.g. in a named tuple).
|
3907
|
+
if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
|
3908
|
+
(0, types_1.isClass)(memberInfo.classType) &&
|
3909
|
+
types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
|
3910
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
|
3911
|
+
isDescriptorError = true;
|
3912
|
+
}
|
3913
|
+
return resultType;
|
3914
|
+
});
|
3915
|
+
if (!isDescriptorError && usage.method === 'set' && usage.setType) {
|
3916
|
+
// Verify that the assigned type is compatible.
|
3917
|
+
if (!assignType(type, usage.setType.type, diag === null || diag === void 0 ? void 0 : diag.createAddendum())) {
|
3918
|
+
if (!usage.setType.isIncomplete) {
|
3919
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberAssignment().format({
|
3920
|
+
type: printType(usage.setType.type),
|
3921
|
+
name: memberName,
|
3922
|
+
classType: printObjectTypeForClass(classType),
|
3923
|
+
}));
|
3924
|
+
}
|
3925
|
+
isDescriptorError = true;
|
3926
|
+
}
|
3927
|
+
if ((0, types_1.isInstantiableClass)(memberInfo.classType) &&
|
3928
|
+
types_1.ClassType.isFrozenDataClass(memberInfo.classType) &&
|
3929
|
+
isAccessedThroughObject) {
|
3930
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.dataClassFrozen().format({
|
3931
|
+
name: printType(types_1.ClassType.cloneAsInstance(memberInfo.classType)),
|
3932
|
+
}));
|
3933
|
+
isDescriptorError = true;
|
3934
|
+
}
|
3881
3935
|
}
|
3882
3936
|
return {
|
3883
3937
|
symbol: memberInfo.symbol,
|
@@ -3887,329 +3941,219 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
3887
3941
|
isClassMember: !memberInfo.isInstanceMember,
|
3888
3942
|
isClassVar: memberInfo.isClassVar,
|
3889
3943
|
classType: memberInfo.classType,
|
3890
|
-
isAsymmetricAccessor
|
3891
|
-
memberAccessDeprecationInfo
|
3944
|
+
isAsymmetricAccessor,
|
3945
|
+
memberAccessDeprecationInfo,
|
3892
3946
|
};
|
3893
3947
|
}
|
3894
3948
|
// Applies descriptor access methods "__get__", "__set__", or "__delete__"
|
3895
|
-
// if they apply.
|
3896
|
-
|
3897
|
-
|
3898
|
-
const treatConstructorAsClassMember = (flags & 256 /* TreatConstructorAsClassMethod */) !== 0;
|
3949
|
+
// if they apply.
|
3950
|
+
function applyDescriptorAccessMethod(memberType, concreteMemberType, memberInfo, classType, selfType, flags, errorNode, memberName, usage, diag) {
|
3951
|
+
var _a, _b, _c, _d;
|
3899
3952
|
const isAccessedThroughObject = types_1.TypeBase.isInstance(classType);
|
3900
|
-
let
|
3953
|
+
let accessMethodName;
|
3954
|
+
if (usage.method === 'get') {
|
3955
|
+
accessMethodName = '__get__';
|
3956
|
+
}
|
3957
|
+
else if (usage.method === 'set') {
|
3958
|
+
accessMethodName = '__set__';
|
3959
|
+
}
|
3960
|
+
else {
|
3961
|
+
accessMethodName = '__delete__';
|
3962
|
+
}
|
3963
|
+
const methodTypeResult = getTypeOfBoundMember(errorNode, concreteMemberType, accessMethodName,
|
3964
|
+
/* usage */ undefined, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */);
|
3965
|
+
if (!methodTypeResult) {
|
3966
|
+
// Provide special error messages for properties.
|
3967
|
+
if (types_1.ClassType.isPropertyClass(concreteMemberType)) {
|
3968
|
+
if (usage.method !== 'get') {
|
3969
|
+
const message = usage.method === 'set'
|
3970
|
+
? localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter()
|
3971
|
+
: localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter();
|
3972
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(message.format({ name: memberName }));
|
3973
|
+
return { type: types_1.AnyType.create(), typeErrors: true };
|
3974
|
+
}
|
3975
|
+
}
|
3976
|
+
return { type: memberType };
|
3977
|
+
}
|
3978
|
+
const methodClassType = methodTypeResult.classType;
|
3979
|
+
let methodType = methodTypeResult.type;
|
3980
|
+
if (methodTypeResult.typeErrors || !methodClassType) {
|
3981
|
+
return { type: types_1.UnknownType.create(), typeErrors: true };
|
3982
|
+
}
|
3983
|
+
if (!(0, types_1.isFunction)(methodType) && !(0, types_1.isOverloadedFunction)(methodType)) {
|
3984
|
+
if ((0, types_1.isAnyOrUnknown)(methodType)) {
|
3985
|
+
return { type: methodType };
|
3986
|
+
}
|
3987
|
+
// TODO - emit an error for this condition.
|
3988
|
+
return { type: memberType, typeErrors: true };
|
3989
|
+
}
|
3990
|
+
// Special-case logic for properties.
|
3991
|
+
if (types_1.ClassType.isPropertyClass(concreteMemberType) &&
|
3992
|
+
memberInfo &&
|
3993
|
+
(0, types_1.isInstantiableClass)(memberInfo.classType) &&
|
3994
|
+
methodType) {
|
3995
|
+
// If the property is being accessed from a protocol class (not an instance),
|
3996
|
+
// flag this as an error because a property within a protocol is meant to be
|
3997
|
+
// interpreted as a read-only attribute rather than a protocol, so accessing
|
3998
|
+
// it directly from the class has an ambiguous meaning.
|
3999
|
+
if ((flags & 16 /* SkipInstanceMembers */) !== 0 && types_1.ClassType.isProtocolClass(classType)) {
|
4000
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
|
4001
|
+
return { type: memberType, typeErrors: true };
|
4002
|
+
}
|
4003
|
+
// Infer return types before specializing. Otherwise a generic inferred
|
4004
|
+
// return type won't be properly specialized.
|
4005
|
+
inferReturnTypeIfNecessary(methodType);
|
4006
|
+
// This specialization is required specifically for properties, which should be
|
4007
|
+
// generic but are not defined that way. Because of this, we use type variables
|
4008
|
+
// in the synthesized methods (e.g. __get__) for the property class that are
|
4009
|
+
// defined in the class that declares the fget method.
|
4010
|
+
const specializedType = (0, typeUtils_1.partiallySpecializeType)(methodType, memberInfo.classType, selfType ? (0, typeUtils_1.convertToInstantiable)(selfType) : classType);
|
4011
|
+
if ((0, types_1.isFunction)(specializedType) || (0, types_1.isOverloadedFunction)(specializedType)) {
|
4012
|
+
methodType = specializedType;
|
4013
|
+
}
|
4014
|
+
}
|
4015
|
+
// Determine if we're calling __set__ on an asymmetric descriptor or property.
|
3901
4016
|
let isAsymmetricAccessor = false;
|
3902
|
-
|
3903
|
-
|
3904
|
-
|
3905
|
-
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
3906
|
-
const isClassMember = !memberInfo || memberInfo.isClassMember;
|
3907
|
-
if ((0, types_1.isClass)(concreteSubtype) && isClassMember) {
|
3908
|
-
// If it's an object, use its class to lookup the descriptor. If it's a class,
|
3909
|
-
// use its metaclass instead.
|
3910
|
-
let lookupClass = concreteSubtype;
|
3911
|
-
let isAccessedThroughMetaclass = false;
|
3912
|
-
if (types_1.TypeBase.isInstantiable(concreteSubtype)) {
|
3913
|
-
if (concreteSubtype.details.effectiveMetaclass &&
|
3914
|
-
(0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass)) {
|
3915
|
-
// When accessing a class member that is a class whose metaclass implements
|
3916
|
-
// a descriptor protocol, only 'get' operations are allowed. If it's accessed
|
3917
|
-
// through the object, all access methods are supported.
|
3918
|
-
if (isAccessedThroughObject || usage.method === 'get') {
|
3919
|
-
lookupClass = types_1.ClassType.cloneAsInstance(concreteSubtype.details.effectiveMetaclass);
|
3920
|
-
isAccessedThroughMetaclass = true;
|
3921
|
-
}
|
3922
|
-
else {
|
3923
|
-
lookupClass = undefined;
|
3924
|
-
}
|
3925
|
-
}
|
3926
|
-
else {
|
3927
|
-
lookupClass = undefined;
|
3928
|
-
}
|
3929
|
-
}
|
3930
|
-
if (lookupClass) {
|
3931
|
-
let accessMethodName;
|
3932
|
-
if (usage.method === 'get') {
|
3933
|
-
accessMethodName = '__get__';
|
3934
|
-
}
|
3935
|
-
else if (usage.method === 'set') {
|
3936
|
-
accessMethodName = '__set__';
|
3937
|
-
}
|
3938
|
-
else {
|
3939
|
-
accessMethodName = '__delete__';
|
3940
|
-
}
|
3941
|
-
const accessMethod = (0, typeUtils_1.lookUpClassMember)(lookupClass, accessMethodName, 16 /* SkipInstanceMembers */);
|
3942
|
-
// Handle properties specially.
|
3943
|
-
if (types_1.ClassType.isPropertyClass(lookupClass)) {
|
3944
|
-
if (usage.method === 'set') {
|
3945
|
-
if (!accessMethod) {
|
3946
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMissingSetter().format({
|
3947
|
-
name: memberName,
|
3948
|
-
}));
|
3949
|
-
isTypeValid = false;
|
3950
|
-
return undefined;
|
3951
|
-
}
|
3952
|
-
}
|
3953
|
-
else if (usage.method === 'del') {
|
3954
|
-
if (!accessMethod) {
|
3955
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyMissingDeleter().format({
|
3956
|
-
name: memberName,
|
3957
|
-
}));
|
3958
|
-
isTypeValid = false;
|
3959
|
-
return undefined;
|
3960
|
-
}
|
3961
|
-
}
|
3962
|
-
}
|
3963
|
-
if (accessMethod) {
|
3964
|
-
let accessMethodType = getTypeOfMember(accessMethod);
|
3965
|
-
const argList = [
|
3966
|
-
{
|
3967
|
-
// Provide "obj" argument.
|
3968
|
-
argumentCategory: 0 /* Simple */,
|
3969
|
-
typeResult: {
|
3970
|
-
type: types_1.ClassType.isClassProperty(lookupClass)
|
3971
|
-
? classType
|
3972
|
-
: isAccessedThroughObject
|
3973
|
-
? selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType)
|
3974
|
-
: getNoneType(),
|
3975
|
-
},
|
3976
|
-
},
|
3977
|
-
];
|
3978
|
-
if (usage.method === 'get') {
|
3979
|
-
// Provide "owner" argument.
|
3980
|
-
argList.push({
|
3981
|
-
argumentCategory: 0 /* Simple */,
|
3982
|
-
typeResult: {
|
3983
|
-
type: isAccessedThroughObject
|
3984
|
-
? types_1.ClassType.cloneAsInstantiable(classType)
|
3985
|
-
: classType,
|
3986
|
-
},
|
3987
|
-
});
|
3988
|
-
}
|
3989
|
-
else if (usage.method === 'set') {
|
3990
|
-
// Provide "value" argument.
|
3991
|
-
argList.push({
|
3992
|
-
argumentCategory: 0 /* Simple */,
|
3993
|
-
typeResult: {
|
3994
|
-
type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
|
3995
|
-
isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
|
3996
|
-
},
|
3997
|
-
});
|
3998
|
-
}
|
3999
|
-
if (types_1.ClassType.isPropertyClass(lookupClass) &&
|
4000
|
-
memberInfo &&
|
4001
|
-
(0, types_1.isInstantiableClass)(memberInfo.classType)) {
|
4002
|
-
// This specialization is required specifically for properties, which should be
|
4003
|
-
// generic but are not defined that way. Because of this, we use type variables
|
4004
|
-
// in the synthesized methods (e.g. __get__) for the property class that are
|
4005
|
-
// defined in the class that declares the fget method.
|
4006
|
-
// Infer return types before specializing. Otherwise a generic inferred
|
4007
|
-
// return type won't be properly specialized.
|
4008
|
-
inferReturnTypeIfNecessary(accessMethodType);
|
4009
|
-
accessMethodType = (0, typeUtils_1.partiallySpecializeType)(accessMethodType, memberInfo.classType);
|
4010
|
-
// If the property is being accessed from a protocol class (not an instance),
|
4011
|
-
// flag this as an error because a property within a protocol is meant to be
|
4012
|
-
// interpreted as a read-only attribute rather than a protocol, so accessing
|
4013
|
-
// it directly from the class has an ambiguous meaning.
|
4014
|
-
if ((flags & 16 /* SkipInstanceMembers */) !== 0 &&
|
4015
|
-
types_1.ClassType.isProtocolClass(classType)) {
|
4016
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.propertyAccessFromProtocolClass());
|
4017
|
-
isTypeValid = false;
|
4018
|
-
}
|
4019
|
-
}
|
4020
|
-
if (accessMethodType &&
|
4021
|
-
((0, types_1.isFunction)(accessMethodType) || (0, types_1.isOverloadedFunction)(accessMethodType))) {
|
4022
|
-
const methodType = accessMethodType;
|
4023
|
-
// Don't emit separate diagnostics for these method calls because
|
4024
|
-
// they will be redundant.
|
4025
|
-
const returnType = suppressDiagnostics(errorNode, () => {
|
4026
|
-
var _a;
|
4027
|
-
// Bind the accessor to the base object type.
|
4028
|
-
let bindToClass;
|
4029
|
-
// The "bind-to" class depends on whether the descriptor is defined
|
4030
|
-
// on the metaclass or the class. We handle properties specially here
|
4031
|
-
// because of the way we model the __get__ logic in the property class.
|
4032
|
-
if (types_1.ClassType.isPropertyClass(concreteSubtype) && !isAccessedThroughMetaclass) {
|
4033
|
-
if (memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType)) {
|
4034
|
-
bindToClass = types_1.ClassType.cloneAsInstance(memberInfo.classType);
|
4035
|
-
}
|
4036
|
-
}
|
4037
|
-
let boundMethodType = bindFunctionToClassOrObjectWithErrors(lookupClass, methodType, bindToClass, errorNode,
|
4038
|
-
/* treatConstructorAsClassMember */ undefined, isAccessedThroughMetaclass ? concreteSubtype : undefined);
|
4039
|
-
// The synthesized access method for the property may contain
|
4040
|
-
// type variables associated with the "bindToClass", so we need
|
4041
|
-
// to specialize those here.
|
4042
|
-
if (boundMethodType &&
|
4043
|
-
((0, types_1.isFunction)(boundMethodType) || (0, types_1.isOverloadedFunction)(boundMethodType))) {
|
4044
|
-
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(boundMethodType));
|
4045
|
-
if (bindToClass) {
|
4046
|
-
const specializedBoundType = (0, typeUtils_1.partiallySpecializeType)(boundMethodType, bindToClass, classType);
|
4047
|
-
if (specializedBoundType) {
|
4048
|
-
if ((0, types_1.isFunction)(specializedBoundType) ||
|
4049
|
-
(0, types_1.isOverloadedFunction)(specializedBoundType)) {
|
4050
|
-
boundMethodType = specializedBoundType;
|
4051
|
-
}
|
4052
|
-
}
|
4053
|
-
}
|
4054
|
-
const callResult = validateCallArguments(errorNode, argList, { type: boundMethodType }, typeVarContext,
|
4055
|
-
/* skipUnknownArgCheck */ true);
|
4056
|
-
if (callResult.overloadsUsedForCall &&
|
4057
|
-
callResult.overloadsUsedForCall.length >= 1) {
|
4058
|
-
const overloadUsed = callResult.overloadsUsedForCall[0];
|
4059
|
-
if (overloadUsed.details.deprecatedMessage) {
|
4060
|
-
memberAccessDeprecationInfo = {
|
4061
|
-
deprecationMessage: overloadUsed.details.deprecatedMessage,
|
4062
|
-
accessType: lookupClass && types_1.ClassType.isPropertyClass(lookupClass)
|
4063
|
-
? 'property'
|
4064
|
-
: 'descriptor',
|
4065
|
-
accessMethod: usage.method,
|
4066
|
-
};
|
4067
|
-
}
|
4068
|
-
}
|
4069
|
-
if (callResult.argumentErrors) {
|
4070
|
-
if (usage.method === 'set') {
|
4071
|
-
if (usage.setType &&
|
4072
|
-
(0, types_1.isFunction)(boundMethodType) &&
|
4073
|
-
boundMethodType.details.parameters.length >= 2 &&
|
4074
|
-
!usage.setType.isIncomplete) {
|
4075
|
-
const setterType = types_1.FunctionType.getEffectiveParameterType(boundMethodType, 1);
|
4076
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
|
4077
|
-
destType: printType(setterType),
|
4078
|
-
sourceType: printType(usage.setType.type),
|
4079
|
-
}));
|
4080
|
-
}
|
4081
|
-
else if ((0, types_1.isOverloadedFunction)(boundMethodType)) {
|
4082
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
|
4083
|
-
}
|
4084
|
-
}
|
4085
|
-
else {
|
4086
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessCallFailed().format({
|
4087
|
-
name: accessMethodName,
|
4088
|
-
className: printType((0, typeUtils_1.convertToInstance)(accessMethod.classType)),
|
4089
|
-
}));
|
4090
|
-
}
|
4091
|
-
isTypeValid = false;
|
4092
|
-
return types_1.AnyType.create();
|
4093
|
-
}
|
4094
|
-
// For set or delete, always return Any.
|
4095
|
-
return usage.method === 'get'
|
4096
|
-
? (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create()
|
4097
|
-
: types_1.AnyType.create();
|
4098
|
-
}
|
4099
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessBindingFailed().format({
|
4100
|
-
name: accessMethodName,
|
4101
|
-
className: printType((0, typeUtils_1.convertToInstance)(accessMethod.classType)),
|
4102
|
-
}));
|
4103
|
-
isTypeValid = false;
|
4104
|
-
return undefined;
|
4105
|
-
});
|
4106
|
-
// Determine if we're calling __set__ on an asymmetric descriptor or property.
|
4107
|
-
if (usage.method === 'set' && (0, types_1.isClass)(accessMethod.classType)) {
|
4108
|
-
if (isAsymmetricDescriptorClass(accessMethod.classType)) {
|
4109
|
-
isAsymmetricAccessor = true;
|
4110
|
-
}
|
4111
|
-
}
|
4112
|
-
if (returnType) {
|
4113
|
-
return returnType;
|
4114
|
-
}
|
4115
|
-
}
|
4116
|
-
}
|
4117
|
-
}
|
4017
|
+
if (usage.method === 'set' && (0, types_1.isClass)(methodClassType)) {
|
4018
|
+
if (isAsymmetricDescriptorClass(methodClassType)) {
|
4019
|
+
isAsymmetricAccessor = true;
|
4118
4020
|
}
|
4119
|
-
|
4120
|
-
|
4121
|
-
|
4122
|
-
|
4123
|
-
|
4124
|
-
|
4125
|
-
|
4126
|
-
|
4127
|
-
|
4128
|
-
|
4129
|
-
|
4130
|
-
|
4131
|
-
|
4132
|
-
|
4133
|
-
|
4134
|
-
|
4135
|
-
|
4136
|
-
|
4137
|
-
|
4138
|
-
|
4139
|
-
|
4140
|
-
|
4141
|
-
|
4142
|
-
|
4143
|
-
|
4144
|
-
|
4145
|
-
|
4021
|
+
}
|
4022
|
+
if (!methodType) {
|
4023
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessBindingFailed().format({
|
4024
|
+
name: accessMethodName,
|
4025
|
+
className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
|
4026
|
+
}));
|
4027
|
+
return {
|
4028
|
+
type: types_1.UnknownType.create(),
|
4029
|
+
typeErrors: true,
|
4030
|
+
isDescriptorApplied: true,
|
4031
|
+
isAsymmetricAccessor,
|
4032
|
+
};
|
4033
|
+
}
|
4034
|
+
// Simulate a call to the access method.
|
4035
|
+
const argList = [];
|
4036
|
+
// Provide "obj" argument.
|
4037
|
+
let objArgType;
|
4038
|
+
if (types_1.ClassType.isClassProperty(concreteMemberType)) {
|
4039
|
+
// Handle "class properties" as a special case. We need to pass
|
4040
|
+
// the class rather than the object instance in this case.
|
4041
|
+
objArgType = classType;
|
4042
|
+
}
|
4043
|
+
else if (isAccessedThroughObject) {
|
4044
|
+
objArgType = selfType !== null && selfType !== void 0 ? selfType : types_1.ClassType.cloneAsInstance(classType);
|
4045
|
+
}
|
4046
|
+
else {
|
4047
|
+
objArgType = getNoneType();
|
4048
|
+
}
|
4049
|
+
argList.push({
|
4050
|
+
argumentCategory: 0 /* Simple */,
|
4051
|
+
typeResult: { type: objArgType },
|
4052
|
+
});
|
4053
|
+
if (usage.method === 'get') {
|
4054
|
+
let classArgType;
|
4055
|
+
if (selfType) {
|
4056
|
+
classArgType = (0, typeUtils_1.convertToInstantiable)(selfType);
|
4146
4057
|
}
|
4147
|
-
|
4148
|
-
|
4149
|
-
if (flags & 128 /* DisallowClassVarWrites */) {
|
4150
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.memberSetClassVar().format({ name: memberName }));
|
4151
|
-
isTypeValid = false;
|
4152
|
-
return undefined;
|
4153
|
-
}
|
4154
|
-
}
|
4155
|
-
// Check for an attempt to overwrite a final member variable.
|
4156
|
-
const finalVarTypeDecl = memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.symbol.getDeclarations().find((decl) => isFinalVariableDeclaration(decl));
|
4157
|
-
if (finalVarTypeDecl && !ParseTreeUtils.isNodeContainedWithin(errorNode, finalVarTypeDecl.node)) {
|
4158
|
-
// If a Final instance variable is declared in the class body but is
|
4159
|
-
// being assigned within an __init__ method, it's allowed.
|
4160
|
-
const enclosingFunctionNode = ParseTreeUtils.getEnclosingFunction(errorNode);
|
4161
|
-
if (!enclosingFunctionNode || enclosingFunctionNode.name.value !== '__init__') {
|
4162
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalReassigned().format({ name: memberName }));
|
4163
|
-
isTypeValid = false;
|
4164
|
-
return undefined;
|
4165
|
-
}
|
4166
|
-
}
|
4167
|
-
// Check for an attempt to overwrite an instance variable that is
|
4168
|
-
// read-only (e.g. in a named tuple).
|
4169
|
-
if ((memberInfo === null || memberInfo === void 0 ? void 0 : memberInfo.isInstanceMember) &&
|
4170
|
-
(0, types_1.isClass)(memberInfo.classType) &&
|
4171
|
-
types_1.ClassType.isReadOnlyInstanceVariables(memberInfo.classType)) {
|
4172
|
-
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.readOnlyAttribute().format({ name: memberName }));
|
4173
|
-
isTypeValid = false;
|
4174
|
-
return undefined;
|
4175
|
-
}
|
4176
|
-
let enforceTargetType = false;
|
4177
|
-
if (memberInfo && memberInfo.symbol.hasTypedDeclarations()) {
|
4178
|
-
// If the member has a declared type, we will enforce it.
|
4179
|
-
enforceTargetType = true;
|
4180
|
-
}
|
4181
|
-
else {
|
4182
|
-
// If the member has no declared type, we will enforce it
|
4183
|
-
// if this assignment isn't within the enclosing class. If
|
4184
|
-
// it is within the enclosing class, the assignment is used
|
4185
|
-
// to infer the type of the member.
|
4186
|
-
if (memberInfo && !memberInfo.symbol.getDeclarations().some((decl) => decl.node === errorNode)) {
|
4187
|
-
enforceTargetType = true;
|
4188
|
-
}
|
4189
|
-
}
|
4190
|
-
if (enforceTargetType) {
|
4191
|
-
let effectiveType = subtype;
|
4192
|
-
// If the code is patching a method (defined on the class)
|
4193
|
-
// with an object-level function, strip the "self" parameter
|
4194
|
-
// off the original type. This is sometimes done for test
|
4195
|
-
// purposes to override standard behaviors of specific methods.
|
4196
|
-
if (isAccessedThroughObject) {
|
4197
|
-
if (!memberInfo.isInstanceMember && (0, types_1.isFunction)(concreteSubtype)) {
|
4198
|
-
if (types_1.FunctionType.isClassMethod(concreteSubtype) ||
|
4199
|
-
types_1.FunctionType.isInstanceMethod(concreteSubtype)) {
|
4200
|
-
effectiveType = types_1.FunctionType.clone(concreteSubtype, /* stripFirstParam */ true);
|
4201
|
-
}
|
4202
|
-
}
|
4203
|
-
}
|
4204
|
-
return effectiveType;
|
4205
|
-
}
|
4058
|
+
else {
|
4059
|
+
classArgType = isAccessedThroughObject ? types_1.ClassType.cloneAsInstantiable(classType) : classType;
|
4206
4060
|
}
|
4207
|
-
|
4061
|
+
// Provide "owner" argument.
|
4062
|
+
argList.push({
|
4063
|
+
argumentCategory: 0 /* Simple */,
|
4064
|
+
typeResult: { type: classArgType },
|
4065
|
+
});
|
4066
|
+
}
|
4067
|
+
else if (usage.method === 'set') {
|
4068
|
+
// Provide "value" argument.
|
4069
|
+
argList.push({
|
4070
|
+
argumentCategory: 0 /* Simple */,
|
4071
|
+
typeResult: {
|
4072
|
+
type: (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create(),
|
4073
|
+
isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
|
4074
|
+
},
|
4075
|
+
});
|
4076
|
+
}
|
4077
|
+
// Suppress diagnostics for these method calls because they would be redundant.
|
4078
|
+
const callResult = suppressDiagnostics(errorNode, () => {
|
4079
|
+
return validateCallArguments(errorNode, argList, { type: methodType },
|
4080
|
+
/* typeVarContext */ undefined,
|
4081
|
+
/* skipUnknownArgCheck */ true);
|
4208
4082
|
});
|
4209
|
-
|
4210
|
-
|
4083
|
+
// Collect deprecation information associated with the member access method.
|
4084
|
+
let deprecationInfo;
|
4085
|
+
if (callResult.overloadsUsedForCall && callResult.overloadsUsedForCall.length >= 1) {
|
4086
|
+
const overloadUsed = callResult.overloadsUsedForCall[0];
|
4087
|
+
if (overloadUsed.details.deprecatedMessage) {
|
4088
|
+
deprecationInfo = {
|
4089
|
+
deprecationMessage: overloadUsed.details.deprecatedMessage,
|
4090
|
+
accessType: types_1.ClassType.isPropertyClass(concreteMemberType) ? 'property' : 'descriptor',
|
4091
|
+
accessMethod: usage.method,
|
4092
|
+
};
|
4093
|
+
}
|
4094
|
+
}
|
4095
|
+
if (!callResult.argumentErrors) {
|
4096
|
+
return {
|
4097
|
+
// For set or delete, always return Any.
|
4098
|
+
type: usage.method === 'get' ? (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create() : types_1.AnyType.create(),
|
4099
|
+
isDescriptorApplied: true,
|
4100
|
+
isAsymmetricAccessor,
|
4101
|
+
memberAccessDeprecationInfo: deprecationInfo,
|
4102
|
+
};
|
4211
4103
|
}
|
4212
|
-
|
4104
|
+
// Errors were detected when evaluating the access method call.
|
4105
|
+
if (usage.method === 'set') {
|
4106
|
+
if (usage.setType &&
|
4107
|
+
(0, types_1.isFunction)(methodType) &&
|
4108
|
+
methodType.details.parameters.length >= 2 &&
|
4109
|
+
!usage.setType.isIncomplete) {
|
4110
|
+
const setterType = types_1.FunctionType.getEffectiveParameterType(methodType, 1);
|
4111
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.typeIncompatible().format({
|
4112
|
+
destType: printType(setterType),
|
4113
|
+
sourceType: printType(usage.setType.type),
|
4114
|
+
}));
|
4115
|
+
}
|
4116
|
+
else if ((0, types_1.isOverloadedFunction)(methodType)) {
|
4117
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.noOverload().format({ name: accessMethodName }));
|
4118
|
+
}
|
4119
|
+
}
|
4120
|
+
else {
|
4121
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.descriptorAccessCallFailed().format({
|
4122
|
+
name: accessMethodName,
|
4123
|
+
className: printType((0, typeUtils_1.convertToInstance)(methodClassType)),
|
4124
|
+
}));
|
4125
|
+
}
|
4126
|
+
return {
|
4127
|
+
type: types_1.UnknownType.create(),
|
4128
|
+
typeErrors: true,
|
4129
|
+
isDescriptorApplied: true,
|
4130
|
+
isAsymmetricAccessor,
|
4131
|
+
memberAccessDeprecationInfo: deprecationInfo,
|
4132
|
+
};
|
4133
|
+
}
|
4134
|
+
function bindMethodForMemberAccess(type, concreteType, memberInfo, classType, selfType, flags, memberName, usage, diag, recursionCount = 0) {
|
4135
|
+
// Check for an attempt to overwrite a final method.
|
4136
|
+
if (usage.method === 'set') {
|
4137
|
+
const impl = (0, types_1.isFunction)(concreteType)
|
4138
|
+
? concreteType
|
4139
|
+
: types_1.OverloadedFunctionType.getImplementation(concreteType);
|
4140
|
+
if (impl && types_1.FunctionType.isFinal(impl) && memberInfo && (0, types_1.isClass)(memberInfo.classType)) {
|
4141
|
+
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.Diagnostic.finalMethodOverride().format({
|
4142
|
+
name: memberName,
|
4143
|
+
className: memberInfo.classType.details.name,
|
4144
|
+
}));
|
4145
|
+
return { type: types_1.UnknownType.create(), typeErrors: true };
|
4146
|
+
}
|
4147
|
+
}
|
4148
|
+
// If this function is an instance member (e.g. a lambda that was
|
4149
|
+
// assigned to an instance variable), don't perform any binding.
|
4150
|
+
if (types_1.TypeBase.isInstance(classType)) {
|
4151
|
+
if (!memberInfo || memberInfo.isInstanceMember) {
|
4152
|
+
return { type: type };
|
4153
|
+
}
|
4154
|
+
}
|
4155
|
+
const boundType = bindFunctionToClassOrObject(classType, concreteType, memberInfo && (0, types_1.isInstantiableClass)(memberInfo.classType) ? memberInfo.classType : undefined, (flags & 256 /* TreatConstructorAsClassMethod */) !== 0, selfType && (0, types_1.isClass)(selfType) ? types_1.ClassType.cloneIncludeSubclasses(selfType) : selfType, diag, recursionCount);
|
4156
|
+
return { type: boundType !== null && boundType !== void 0 ? boundType : types_1.UnknownType.create(), typeErrors: !boundType };
|
4213
4157
|
}
|
4214
4158
|
function isAsymmetricDescriptorClass(classType) {
|
4215
4159
|
var _a;
|
@@ -4276,11 +4220,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4276
4220
|
return isAsymmetric;
|
4277
4221
|
}
|
4278
4222
|
// Applies the __getattr__, __setattr__ or __delattr__ method if present.
|
4279
|
-
|
4223
|
+
// If it's not applicable, returns undefined.
|
4224
|
+
function applyAttributeAccessOverride(errorNode, classType, usage, memberName, selfType) {
|
4280
4225
|
var _a, _b, _c, _d, _e;
|
4281
4226
|
const getAttributeAccessMember = (name) => {
|
4282
4227
|
var _a;
|
4283
|
-
return (_a =
|
4228
|
+
return (_a = getTypeOfBoundMember(errorNode, classType, name,
|
4229
|
+
/* usage */ undefined,
|
4284
4230
|
/* diag */ undefined, 16 /* SkipInstanceMembers */ |
|
4285
4231
|
4 /* SkipObjectBaseClass */ |
|
4286
4232
|
512 /* SkipAttributeAccessOverride */, selfType)) === null || _a === void 0 ? void 0 : _a.type;
|
@@ -4299,20 +4245,19 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4299
4245
|
if (!accessMemberType) {
|
4300
4246
|
return undefined;
|
4301
4247
|
}
|
4302
|
-
|
4303
|
-
|
4304
|
-
|
4305
|
-
|
4306
|
-
|
4307
|
-
|
4308
|
-
|
4309
|
-
|
4310
|
-
typeResult: { type: nameLiteralType },
|
4248
|
+
const argList = [];
|
4249
|
+
// Provide "name" argument.
|
4250
|
+
argList.push({
|
4251
|
+
argumentCategory: 0 /* Simple */,
|
4252
|
+
typeResult: {
|
4253
|
+
type: strClassType && (0, types_1.isInstantiableClass)(strClassType)
|
4254
|
+
? types_1.ClassType.cloneWithLiteral(types_1.ClassType.cloneAsInstance(strClassType), memberName)
|
4255
|
+
: types_1.AnyType.create(),
|
4311
4256
|
},
|
4312
|
-
|
4257
|
+
});
|
4313
4258
|
if (usage.method === 'set') {
|
4259
|
+
// Provide "value" argument.
|
4314
4260
|
argList.push({
|
4315
|
-
// Provide "value" argument.
|
4316
4261
|
argumentCategory: 0 /* Simple */,
|
4317
4262
|
typeResult: {
|
4318
4263
|
type: (_c = (_b = usage.setType) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : types_1.UnknownType.create(),
|
@@ -4321,20 +4266,22 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4321
4266
|
});
|
4322
4267
|
}
|
4323
4268
|
if (!(0, types_1.isFunction)(accessMemberType) && !(0, types_1.isOverloadedFunction)(accessMemberType)) {
|
4324
|
-
|
4269
|
+
if ((0, types_1.isAnyOrUnknown)(accessMemberType)) {
|
4270
|
+
return { type: accessMemberType };
|
4271
|
+
}
|
4272
|
+
// TODO - emit an error for this condition.
|
4325
4273
|
return undefined;
|
4326
4274
|
}
|
4327
4275
|
const typeVarContext = new typeVarContext_1.TypeVarContext((0, typeUtils_1.getTypeVarScopeId)(accessMemberType));
|
4328
4276
|
const callResult = validateCallArguments(errorNode, argList, { type: accessMemberType }, typeVarContext,
|
4329
4277
|
/* skipUnknownArgCheck */ true);
|
4330
|
-
// TODO - need to handle and report errors when validating call to
|
4331
|
-
// attribute access method.
|
4332
4278
|
let isAsymmetricAccessor = false;
|
4333
4279
|
if (usage.method === 'set') {
|
4334
4280
|
isAsymmetricAccessor = isClassWithAsymmetricAttributeAccessor(classType);
|
4335
4281
|
}
|
4336
4282
|
return {
|
4337
4283
|
type: (_e = callResult.returnType) !== null && _e !== void 0 ? _e : types_1.UnknownType.create(),
|
4284
|
+
typeErrors: callResult.argumentErrors,
|
4338
4285
|
isAsymmetricAccessor,
|
4339
4286
|
};
|
4340
4287
|
}
|
@@ -4545,10 +4492,11 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4545
4492
|
typeParameters.forEach((param, index) => {
|
4546
4493
|
if (param.details.isParamSpec && index < typeArgs.length) {
|
4547
4494
|
const typeArgType = typeArgs[index].type;
|
4548
|
-
|
4495
|
+
const typeList = typeArgs[index].typeList;
|
4496
|
+
if (typeList) {
|
4549
4497
|
const functionType = types_1.FunctionType.createSynthesizedInstance('', 65536 /* ParamSpecValue */);
|
4550
4498
|
types_1.TypeBase.setSpecialForm(functionType);
|
4551
|
-
|
4499
|
+
typeList.forEach((paramType, paramIndex) => {
|
4552
4500
|
types_1.FunctionType.addParameter(functionType, {
|
4553
4501
|
category: 0 /* Simple */,
|
4554
4502
|
name: `__p${paramIndex}`,
|
@@ -4663,7 +4611,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4663
4611
|
}
|
4664
4612
|
if ((0, types_1.isTypeVar)(baseTypeResult.type) && (0, typeUtils_1.isTypeAliasPlaceholder)(baseTypeResult.type)) {
|
4665
4613
|
const typeArgTypes = getTypeArgs(node, flags).map((t) => (0, typeUtils_1.convertToInstance)(t.type));
|
4666
|
-
const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, baseTypeResult.type.details.recursiveTypeAliasIsPep695Syntax, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
|
4614
|
+
const type = types_1.TypeBase.cloneForTypeAlias(baseTypeResult.type, baseTypeResult.type.details.recursiveTypeAliasName, '', baseTypeResult.type.details.recursiveTypeAliasScopeId, !!baseTypeResult.type.details.recursiveTypeAliasIsPep695Syntax, baseTypeResult.type.details.recursiveTypeParameters, typeArgTypes);
|
4667
4615
|
return { type };
|
4668
4616
|
}
|
4669
4617
|
let isIncomplete = baseTypeResult.isIncomplete;
|
@@ -4692,9 +4640,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4692
4640
|
(0, types_1.isInstantiableClass)(concreteSubtype.details.effectiveMetaclass) &&
|
4693
4641
|
!types_1.ClassType.isBuiltIn(concreteSubtype.details.effectiveMetaclass, ['type', '_InitVarMeta']) &&
|
4694
4642
|
(flags & 128 /* ExpectingInstantiableType */) === 0) {
|
4695
|
-
const itemMethodType =
|
4696
|
-
/* usage */ undefined,
|
4697
|
-
/* diag */ undefined, 512 /* SkipAttributeAccessOverride */);
|
4643
|
+
const itemMethodType = getBoundMagicMethod(concreteSubtype, getIndexAccessMagicMethodName(usage));
|
4698
4644
|
if ((flags & 256 /* ExpectingTypeAnnotation */) !== 0) {
|
4699
4645
|
// If the class doesn't derive from Generic, a type argument should not be allowed.
|
4700
4646
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeArgsExpectingNone().format({
|
@@ -4920,7 +4866,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4920
4866
|
}
|
4921
4867
|
}
|
4922
4868
|
function getTypeOfIndexedObjectOrClass(node, baseType, usage) {
|
4923
|
-
var _a, _b, _c, _d
|
4869
|
+
var _a, _b, _c, _d;
|
4924
4870
|
// Handle index operations for TypedDict classes specially.
|
4925
4871
|
if ((0, types_1.isClassInstance)(baseType) && types_1.ClassType.isTypedDictClass(baseType)) {
|
4926
4872
|
const typeFromTypedDict = (0, typedDicts_1.getTypeOfIndexedTypedDict)(evaluatorInterface, node, baseType, usage);
|
@@ -4929,9 +4875,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
4929
4875
|
}
|
4930
4876
|
}
|
4931
4877
|
const magicMethodName = getIndexAccessMagicMethodName(usage);
|
4932
|
-
const itemMethodType = (
|
4933
|
-
/* usage */ undefined,
|
4934
|
-
/* diag */ undefined, 512 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
4878
|
+
const itemMethodType = getBoundMagicMethod(baseType, magicMethodName);
|
4935
4879
|
if (!itemMethodType) {
|
4936
4880
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
|
4937
4881
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.methodNotDefinedOnType().format({
|
@@ -5060,7 +5004,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5060
5004
|
},
|
5061
5005
|
];
|
5062
5006
|
if (usage.method === 'set') {
|
5063
|
-
let setType = (
|
5007
|
+
let setType = (_b = (_a = usage.setType) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.AnyType.create();
|
5064
5008
|
// Expand constrained type variables.
|
5065
5009
|
if ((0, types_1.isTypeVar)(setType) && setType.details.constraints.length > 0) {
|
5066
5010
|
const conditionFilter = (0, types_1.isClassInstance)(baseType) ? baseType.condition : undefined;
|
@@ -5071,7 +5015,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5071
5015
|
argumentCategory: 0 /* Simple */,
|
5072
5016
|
typeResult: {
|
5073
5017
|
type: setType,
|
5074
|
-
isIncomplete: !!((
|
5018
|
+
isIncomplete: !!((_c = usage.setType) === null || _c === void 0 ? void 0 : _c.isIncomplete),
|
5075
5019
|
},
|
5076
5020
|
});
|
5077
5021
|
}
|
@@ -5103,7 +5047,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5103
5047
|
if ((0, types_1.isClassInstance)(positionalIndexType)) {
|
5104
5048
|
const altArgList = [...argList];
|
5105
5049
|
altArgList[0] = { ...altArgList[0] };
|
5106
|
-
const indexMethod =
|
5050
|
+
const indexMethod = getBoundMagicMethod(positionalIndexType, '__index__');
|
5107
5051
|
if (indexMethod) {
|
5108
5052
|
const intType = getBuiltInObject(node, 'int');
|
5109
5053
|
if ((0, types_1.isClassInstance)(intType)) {
|
@@ -5121,7 +5065,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5121
5065
|
}
|
5122
5066
|
callResult = validateCallArguments(node, argList, { type: itemMethodType });
|
5123
5067
|
return {
|
5124
|
-
type: (
|
5068
|
+
type: (_d = callResult.returnType) !== null && _d !== void 0 ? _d : types_1.UnknownType.create(),
|
5125
5069
|
isIncomplete: !!callResult.isTypeIncomplete,
|
5126
5070
|
};
|
5127
5071
|
}
|
@@ -5807,7 +5751,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5807
5751
|
}
|
5808
5752
|
}
|
5809
5753
|
if (bindToType && implicitBindToType) {
|
5810
|
-
|
5754
|
+
const typeCondition = (0, typeUtils_1.getTypeCondition)(implicitBindToType);
|
5755
|
+
if (typeCondition) {
|
5756
|
+
bindToType = (0, typeUtils_1.addConditionToType)(bindToType, typeCondition);
|
5757
|
+
}
|
5758
|
+
else if ((0, types_1.isClass)(implicitBindToType)) {
|
5759
|
+
bindToType = implicitBindToType;
|
5760
|
+
}
|
5811
5761
|
}
|
5812
5762
|
}
|
5813
5763
|
// Determine whether super() should return an instance of the class or
|
@@ -5830,9 +5780,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
5830
5780
|
// Python docs indicate that super() isn't valid for
|
5831
5781
|
// operations other than member accesses or attribute lookups.
|
5832
5782
|
const parentNode = node.parent;
|
5833
|
-
if (parentNode.nodeType === 35 /* MemberAccess */) {
|
5783
|
+
if ((parentNode === null || parentNode === void 0 ? void 0 : parentNode.nodeType) === 35 /* MemberAccess */) {
|
5834
5784
|
const memberName = parentNode.memberName.value;
|
5835
|
-
|
5785
|
+
let effectiveTargetClass = (0, types_1.isClass)(targetClassType) ? targetClassType : undefined;
|
5786
|
+
// If the bind-to type is a protocol, don't use the effective target class.
|
5787
|
+
// This pattern is used for mixins, where the mixin type is a protocol class
|
5788
|
+
// that is used to decorate the "self" or "cls" parameter.
|
5789
|
+
if (bindToType &&
|
5790
|
+
types_1.ClassType.isProtocolClass(bindToType) &&
|
5791
|
+
effectiveTargetClass &&
|
5792
|
+
!types_1.ClassType.isSameGenericClass(bindToType, effectiveTargetClass)) {
|
5793
|
+
effectiveTargetClass = undefined;
|
5794
|
+
}
|
5836
5795
|
const lookupResults = bindToType
|
5837
5796
|
? (0, typeUtils_1.lookUpClassMember)(bindToType, memberName, 0 /* Default */, effectiveTargetClass)
|
5838
5797
|
: undefined;
|
@@ -6563,7 +6522,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6563
6522
|
const result = {
|
6564
6523
|
returnType: (0, namedTuples_1.createNamedTupleType)(evaluatorInterface, errorNode, argList, /* includesTypes */ true),
|
6565
6524
|
};
|
6566
|
-
const initTypeResult =
|
6525
|
+
const initTypeResult = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, errorNode, types_1.ClassType.cloneAsInstance(expandedCallType),
|
6526
|
+
/* skipObjectBase */ false);
|
6567
6527
|
if (initTypeResult && (0, types_1.isOverloadedFunction)(initTypeResult.type)) {
|
6568
6528
|
validateOverloadedFunctionArguments(errorNode, argList, { type: initTypeResult.type },
|
6569
6529
|
/* typeVarContext */ undefined, skipUnknownArgCheck,
|
@@ -6664,18 +6624,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6664
6624
|
return { returnType, overloadsUsedForCall, argumentErrors, isTypeIncomplete };
|
6665
6625
|
}
|
6666
6626
|
function validateCallForClassInstance(errorNode, argList, expandedCallType, unexpandedCallType, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount) {
|
6667
|
-
var _a
|
6668
|
-
const
|
6627
|
+
var _a;
|
6628
|
+
const callMethodResult = getTypeOfBoundMember(errorNode, expandedCallType, '__call__',
|
6669
6629
|
/* usage */ undefined,
|
6670
|
-
/* diag */ undefined,
|
6671
|
-
|
6630
|
+
/* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */,
|
6631
|
+
/* selfType */ undefined, recursionCount);
|
6632
|
+
const callMethodType = callMethodResult === null || callMethodResult === void 0 ? void 0 : callMethodResult.type;
|
6633
|
+
if (!callMethodType) {
|
6672
6634
|
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.objectNotCallable().format({
|
6673
6635
|
type: printType(expandedCallType),
|
6674
6636
|
}), errorNode);
|
6675
6637
|
return { returnType: types_1.UnknownType.create(), argumentErrors: true };
|
6676
6638
|
}
|
6677
|
-
const callResult = validateCallArguments(errorNode, argList, { type:
|
6678
|
-
let returnType = (
|
6639
|
+
const callResult = validateCallArguments(errorNode, argList, { type: callMethodType }, typeVarContext, skipUnknownArgCheck, inferenceContext, recursionCount);
|
6640
|
+
let returnType = (_a = callResult.returnType) !== null && _a !== void 0 ? _a : types_1.UnknownType.create();
|
6679
6641
|
if ((0, types_1.isTypeVar)(unexpandedCallType) &&
|
6680
6642
|
types_1.TypeBase.isInstantiable(unexpandedCallType) &&
|
6681
6643
|
(0, types_1.isClass)(expandedCallType) &&
|
@@ -6867,9 +6829,12 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6867
6829
|
let paramIndex = 0;
|
6868
6830
|
while (argIndex < positionalArgCount) {
|
6869
6831
|
if (argIndex < positionalOnlyLimitIndex && argList[argIndex].name) {
|
6870
|
-
const
|
6871
|
-
|
6872
|
-
|
6832
|
+
const nameNode = argList[argIndex].name;
|
6833
|
+
if (nameNode) {
|
6834
|
+
const fileInfo = AnalyzerNodeInfo.getFileInfo(nameNode);
|
6835
|
+
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.argPositional(), nameNode);
|
6836
|
+
reportedArgError = true;
|
6837
|
+
}
|
6873
6838
|
}
|
6874
6839
|
const remainingArgCount = positionalArgCount - argIndex;
|
6875
6840
|
const remainingParamCount = positionParamLimitIndex - paramIndex - 1;
|
@@ -6982,7 +6947,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
6982
6947
|
else {
|
6983
6948
|
listElementType =
|
6984
6949
|
(_e = (_d = getTypeOfIterator({ type: argType, isIncomplete: argTypeResult.isIncomplete },
|
6985
|
-
/* isAsync */ false,
|
6950
|
+
/* isAsync */ false, errorNode,
|
6951
|
+
/* emitNotIterableError */ false)) === null || _d === void 0 ? void 0 : _d.type) !== null && _e !== void 0 ? _e : types_1.UnknownType.create();
|
6986
6952
|
if (paramDetails.params[paramIndex].param.category !== 1 /* ArgsList */) {
|
6987
6953
|
matchedUnpackedListOfUnknownLength = true;
|
6988
6954
|
}
|
@@ -8901,13 +8867,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8901
8867
|
let magicMethodSupported = true;
|
8902
8868
|
// Create a helper lambda for object subtypes.
|
8903
8869
|
const handleSubtype = (subtype) => {
|
8904
|
-
var _a;
|
8905
8870
|
let magicMethodType;
|
8906
8871
|
const concreteSubtype = makeTopLevelTypeVarsConcrete(subtype);
|
8907
8872
|
if ((0, types_1.isClass)(concreteSubtype)) {
|
8908
|
-
magicMethodType = (
|
8909
|
-
/* usage */ undefined,
|
8910
|
-
/* diag */ undefined, 16 /* SkipInstanceMembers */ | 512 /* SkipAttributeAccessOverride */)) === null || _a === void 0 ? void 0 : _a.type;
|
8873
|
+
magicMethodType = getBoundMagicMethod(concreteSubtype, methodName, subtype);
|
8911
8874
|
}
|
8912
8875
|
if (magicMethodType) {
|
8913
8876
|
const functionArgs = argList.map((arg) => {
|
@@ -8917,16 +8880,18 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
8917
8880
|
};
|
8918
8881
|
});
|
8919
8882
|
let callResult;
|
8920
|
-
useSpeculativeMode(errorNode, () => {
|
8921
|
-
|
8883
|
+
callResult = useSpeculativeMode(errorNode, () => {
|
8884
|
+
(0, debug_1.assert)(magicMethodType !== undefined);
|
8885
|
+
return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
|
8922
8886
|
/* typeVarContext */ undefined,
|
8923
8887
|
/* skipUnknownArgCheck */ true, inferenceContext);
|
8924
8888
|
});
|
8925
8889
|
// If there were errors with the expected type, try
|
8926
8890
|
// to evaluate without the expected type.
|
8927
8891
|
if (callResult.argumentErrors && inferenceContext) {
|
8928
|
-
useSpeculativeMode(errorNode, () => {
|
8929
|
-
|
8892
|
+
callResult = useSpeculativeMode(errorNode, () => {
|
8893
|
+
(0, debug_1.assert)(magicMethodType !== undefined);
|
8894
|
+
return validateCallArguments(errorNode, functionArgs, { type: magicMethodType },
|
8930
8895
|
/* typeVarContext */ undefined,
|
8931
8896
|
/* skipUnknownArgCheck */ true);
|
8932
8897
|
});
|
@@ -9569,7 +9534,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
9569
9534
|
expectedFunctionTypes.push(subtype);
|
9570
9535
|
}
|
9571
9536
|
if ((0, types_1.isClassInstance)(subtype)) {
|
9572
|
-
const boundMethod =
|
9537
|
+
const boundMethod = getBoundMagicMethod(subtype, '__call__');
|
9573
9538
|
if (boundMethod && (0, types_1.isFunction)(boundMethod)) {
|
9574
9539
|
expectedFunctionTypes.push(boundMethod);
|
9575
9540
|
}
|
@@ -10452,6 +10417,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10452
10417
|
let reportedUnpackedError = false;
|
10453
10418
|
// Verify that we didn't receive any inappropriate types.
|
10454
10419
|
typeArgs.forEach((typeArg, index) => {
|
10420
|
+
(0, debug_1.assert)(typeArgs !== undefined);
|
10455
10421
|
if ((0, typeUtils_1.isEllipsisType)(typeArg.type)) {
|
10456
10422
|
if (!isTupleTypeParam) {
|
10457
10423
|
if (!allowParamSpec) {
|
@@ -10638,6 +10604,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10638
10604
|
// with this type alias.
|
10639
10605
|
typeParameters = [];
|
10640
10606
|
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
10607
|
+
(0, debug_1.assert)(typeParameters !== undefined);
|
10641
10608
|
(0, typeUtils_1.addTypeVarsToListIfUnique)(typeParameters, (0, typeUtils_1.getTypeVarArgumentsRecursive)(subtype));
|
10642
10609
|
});
|
10643
10610
|
// Don't include any synthesized type variables.
|
@@ -10654,6 +10621,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10654
10621
|
// Validate the default types for all type parameters.
|
10655
10622
|
typeParameters.forEach((typeParam, index) => {
|
10656
10623
|
var _a;
|
10624
|
+
(0, debug_1.assert)(typeParameters !== undefined);
|
10657
10625
|
let bestErrorNode = errorNode;
|
10658
10626
|
if (typeParamNodes && index < typeParamNodes.length) {
|
10659
10627
|
bestErrorNode = (_a = typeParamNodes[index].defaultExpression) !== null && _a !== void 0 ? _a : typeParamNodes[index].name;
|
@@ -10934,6 +10902,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
10934
10902
|
// If this is a type alias, record its name based on the assignment target.
|
10935
10903
|
rightHandType = transformTypeForTypeAlias(rightHandType, typeAliasNameNode, node.rightExpression,
|
10936
10904
|
/* isPep695Syntax */ false);
|
10905
|
+
(0, debug_1.assert)(typeAliasTypeVar !== undefined);
|
10937
10906
|
if ((0, typeUtils_1.isTypeAliasRecursive)(typeAliasTypeVar, rightHandType)) {
|
10938
10907
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeAliasIsRecursiveDirect().format({
|
10939
10908
|
name: typeAliasNameNode.value,
|
@@ -11650,6 +11619,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11650
11619
|
if (p.details.isVariadic) {
|
11651
11620
|
return p;
|
11652
11621
|
}
|
11622
|
+
(0, debug_1.assert)(objectType !== undefined);
|
11653
11623
|
return i === paramIndex ? objectType : dummyTypeObject;
|
11654
11624
|
});
|
11655
11625
|
// Replace all type arguments with a dummy type except for the
|
@@ -11818,6 +11788,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11818
11788
|
computeEffectiveMetaclass(type, errorNode);
|
11819
11789
|
}
|
11820
11790
|
function validateInitSubclassArgs(node, classType) {
|
11791
|
+
var _a, _b;
|
11821
11792
|
// Collect arguments that will be passed to the `__init_subclass__`
|
11822
11793
|
// method described in PEP 487 and validate it.
|
11823
11794
|
const argList = [];
|
@@ -11831,72 +11802,91 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
11831
11802
|
});
|
11832
11803
|
}
|
11833
11804
|
});
|
11834
|
-
const errorNode = argList.length > 0 ? argList[0].node.name : node.name;
|
11835
|
-
|
11836
|
-
|
11837
|
-
4 /* SkipObjectBaseClass */ |
|
11838
|
-
1 /* SkipOriginalClass */ |
|
11839
|
-
512 /* SkipAttributeAccessOverride */);
|
11840
|
-
if (initSubclassMethodInfo) {
|
11841
|
-
const initSubclassMethodType = initSubclassMethodInfo.type;
|
11842
|
-
if (initSubclassMethodType) {
|
11843
|
-
validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
|
11844
|
-
/* typeVarContext */ undefined,
|
11845
|
-
/* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(getNoneType()));
|
11846
|
-
}
|
11847
|
-
}
|
11848
|
-
else if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
|
11805
|
+
const errorNode = argList.length > 0 ? (_b = (_a = argList[0].node) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : node.name : node.name;
|
11806
|
+
let newMethodMember;
|
11807
|
+
if (classType.details.effectiveMetaclass && (0, types_1.isClass)(classType.details.effectiveMetaclass)) {
|
11849
11808
|
// See if the metaclass has a `__new__` method that accepts keyword parameters.
|
11850
|
-
|
11851
|
-
|
11852
|
-
|
11853
|
-
|
11854
|
-
|
11855
|
-
|
11856
|
-
|
11857
|
-
|
11858
|
-
|
11859
|
-
|
11860
|
-
|
11861
|
-
|
11862
|
-
|
11809
|
+
newMethodMember = (0, typeUtils_1.lookUpClassMember)(classType.details.effectiveMetaclass, '__new__', 8 /* SkipTypeBaseClass */);
|
11810
|
+
}
|
11811
|
+
if (newMethodMember) {
|
11812
|
+
const newMethodType = getTypeOfMember(newMethodMember);
|
11813
|
+
if ((0, types_1.isFunction)(newMethodType)) {
|
11814
|
+
const paramListDetails = (0, parameterUtils_1.getParameterListDetails)(newMethodType);
|
11815
|
+
if (paramListDetails.firstKeywordOnlyIndex !== undefined) {
|
11816
|
+
// Build a map of the keyword-only parameters.
|
11817
|
+
const paramMap = new Map();
|
11818
|
+
for (let i = paramListDetails.firstKeywordOnlyIndex; i < paramListDetails.params.length; i++) {
|
11819
|
+
const paramInfo = paramListDetails.params[i];
|
11820
|
+
if (paramInfo.param.category === 0 /* Simple */ && paramInfo.param.name) {
|
11821
|
+
paramMap.set(paramInfo.param.name, i);
|
11863
11822
|
}
|
11864
|
-
|
11865
|
-
|
11866
|
-
|
11867
|
-
|
11868
|
-
|
11869
|
-
|
11870
|
-
|
11871
|
-
|
11872
|
-
|
11873
|
-
|
11874
|
-
|
11875
|
-
|
11876
|
-
|
11877
|
-
|
11878
|
-
|
11879
|
-
|
11880
|
-
|
11881
|
-
else {
|
11882
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), (_c = arg.name) !== null && _c !== void 0 ? _c : errorNode);
|
11883
|
-
}
|
11823
|
+
}
|
11824
|
+
argList.forEach((arg) => {
|
11825
|
+
var _a, _b, _c;
|
11826
|
+
const signatureTracker = new typeUtils_1.UniqueSignatureTracker();
|
11827
|
+
if (arg.argumentCategory === 0 /* Simple */ && arg.name) {
|
11828
|
+
const paramIndex = (_a = paramMap.get(arg.name.value)) !== null && _a !== void 0 ? _a : paramListDetails.kwargsIndex;
|
11829
|
+
if (paramIndex !== undefined) {
|
11830
|
+
const paramInfo = paramListDetails.params[paramIndex];
|
11831
|
+
const argParam = {
|
11832
|
+
paramCategory: paramInfo.param.category,
|
11833
|
+
paramType: types_1.FunctionType.getEffectiveParameterType(newMethodType, paramInfo.index),
|
11834
|
+
requiresTypeVarMatching: false,
|
11835
|
+
argument: arg,
|
11836
|
+
errorNode: (_b = arg.valueExpression) !== null && _b !== void 0 ? _b : errorNode,
|
11837
|
+
};
|
11838
|
+
validateArgType(argParam, new typeVarContext_1.TypeVarContext(), signatureTracker, { type: newMethodType }, { skipUnknownArgCheck: true, skipOverloadArg: true });
|
11839
|
+
paramMap.delete(arg.name.value);
|
11884
11840
|
}
|
11885
|
-
|
11886
|
-
|
11887
|
-
// default values.
|
11888
|
-
const unassignedParams = [];
|
11889
|
-
paramMap.forEach((index, paramName) => {
|
11890
|
-
const paramInfo = paramListDetails.params[index];
|
11891
|
-
if (!paramInfo.param.hasDefault) {
|
11892
|
-
unassignedParams.push(paramName);
|
11841
|
+
else {
|
11842
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.paramNameMissing().format({ name: arg.name.value }), (_c = arg.name) !== null && _c !== void 0 ? _c : errorNode);
|
11893
11843
|
}
|
11894
|
-
}
|
11895
|
-
|
11896
|
-
|
11897
|
-
|
11898
|
-
|
11899
|
-
|
11844
|
+
}
|
11845
|
+
});
|
11846
|
+
// See if we have any remaining unmatched parameters without
|
11847
|
+
// default values.
|
11848
|
+
const unassignedParams = [];
|
11849
|
+
paramMap.forEach((index, paramName) => {
|
11850
|
+
const paramInfo = paramListDetails.params[index];
|
11851
|
+
if (!paramInfo.param.hasDefault) {
|
11852
|
+
unassignedParams.push(paramName);
|
11853
|
+
}
|
11854
|
+
});
|
11855
|
+
if (unassignedParams.length > 0) {
|
11856
|
+
const missingParamNames = unassignedParams.map((p) => `"${p}"`).join(', ');
|
11857
|
+
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, unassignedParams.length === 1
|
11858
|
+
? localize_1.Localizer.Diagnostic.argMissingForParam().format({ name: missingParamNames })
|
11859
|
+
: localize_1.Localizer.Diagnostic.argMissingForParams().format({ names: missingParamNames }), errorNode);
|
11860
|
+
}
|
11861
|
+
}
|
11862
|
+
}
|
11863
|
+
}
|
11864
|
+
else {
|
11865
|
+
// If there was no custom metaclass __new__ method, see if there is an __init_subclass__
|
11866
|
+
// method present somewhere in the class hierarchy.
|
11867
|
+
const initSubclassMethodInfo = getTypeOfBoundMember(errorNode, classType, '__init_subclass__',
|
11868
|
+
/* usage */ undefined,
|
11869
|
+
/* diag */ undefined, 32 /* SkipClassMembers */ |
|
11870
|
+
1 /* SkipOriginalClass */ |
|
11871
|
+
512 /* SkipAttributeAccessOverride */);
|
11872
|
+
if (initSubclassMethodInfo) {
|
11873
|
+
const initSubclassMethodType = initSubclassMethodInfo.type;
|
11874
|
+
if (initSubclassMethodType && initSubclassMethodInfo.classType) {
|
11875
|
+
const callResult = validateCallArguments(errorNode, argList, { type: initSubclassMethodType },
|
11876
|
+
/* typeVarContext */ undefined,
|
11877
|
+
/* skipUnknownArgCheck */ false, (0, typeUtils_1.makeInferenceContext)(getNoneType()));
|
11878
|
+
if (callResult.argumentErrors) {
|
11879
|
+
const diag = addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.initSubclassCallFailed(), node.name);
|
11880
|
+
const initSubclassFunction = (0, types_1.isOverloadedFunction)(initSubclassMethodType)
|
11881
|
+
? types_1.OverloadedFunctionType.getOverloads(initSubclassMethodType)[0]
|
11882
|
+
: initSubclassMethodType;
|
11883
|
+
const initSubclassDecl = (0, types_1.isFunction)(initSubclassFunction)
|
11884
|
+
? initSubclassFunction.details.declaration
|
11885
|
+
: undefined;
|
11886
|
+
if (diag && initSubclassDecl) {
|
11887
|
+
diag.addRelatedInfo(localize_1.Localizer.DiagnosticAddendum.initSubclassLocation().format({
|
11888
|
+
name: printType((0, typeUtils_1.convertToInstance)(initSubclassMethodInfo.classType)),
|
11889
|
+
}), initSubclassDecl.path, initSubclassDecl.range);
|
11900
11890
|
}
|
11901
11891
|
}
|
11902
11892
|
}
|
@@ -12060,7 +12050,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
12060
12050
|
// accumulate the list of type parameters upfront.
|
12061
12051
|
const typeParametersSeen = [];
|
12062
12052
|
if (node.typeParameters) {
|
12063
|
-
functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters);
|
12053
|
+
functionType.details.typeParameters = evaluateTypeParameterList(node.typeParameters).map((typeParam) => (0, typeUtils_1.convertToInstance)(typeParam));
|
12064
12054
|
}
|
12065
12055
|
else {
|
12066
12056
|
functionType.details.typeParameters = typeParametersSeen;
|
@@ -13945,6 +13935,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13945
13935
|
else {
|
13946
13936
|
// Avoid emitting this error for a partially-constructed class.
|
13947
13937
|
if (!(0, types_1.isClassInstance)(typeArgType) || !types_1.ClassType.isPartiallyEvaluated(typeArgType)) {
|
13938
|
+
(0, debug_1.assert)(typeArgs !== undefined);
|
13948
13939
|
const fileInfo = AnalyzerNodeInfo.getFileInfo(typeArgs[index].node);
|
13949
13940
|
addDiagnostic(fileInfo.diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.typeVarAssignmentMismatch().format({
|
13950
13941
|
type: printType(typeArgType),
|
@@ -13986,6 +13977,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
13986
13977
|
}
|
13987
13978
|
// If there was no defined type provided, there should always
|
13988
13979
|
// be a value expression from which we can retrieve the type.
|
13980
|
+
(0, debug_1.assert)(arg.valueExpression !== undefined);
|
13989
13981
|
return getTypeOfExpressionExpectingType(arg.valueExpression, options);
|
13990
13982
|
}
|
13991
13983
|
function getTypeOfExpressionExpectingType(node, options) {
|
@@ -14371,8 +14363,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14371
14363
|
});
|
14372
14364
|
}
|
14373
14365
|
else if ((0, types_1.isInstantiableClass)(baseType)) {
|
14374
|
-
const initMethodType = (_b =
|
14375
|
-
/* diag */ undefined, 4 /* SkipObjectBaseClass */)) === null || _b === void 0 ? void 0 : _b.type;
|
14366
|
+
const initMethodType = (_b = (0, constructors_1.getBoundInitMethod)(evaluatorInterface, argNode.parent.leftExpression, types_1.ClassType.cloneAsInstance(baseType))) === null || _b === void 0 ? void 0 : _b.type;
|
14376
14367
|
if (initMethodType && (0, types_1.isFunction)(initMethodType)) {
|
14377
14368
|
const paramDecl = getDeclarationFromFunctionNamedParameter(initMethodType, paramName);
|
14378
14369
|
if (paramDecl) {
|
@@ -14754,6 +14745,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14754
14745
|
// If the resolved declaration had no defined type, use the
|
14755
14746
|
// inferred type for this node.
|
14756
14747
|
if (resolvedDecl.type === 2 /* Parameter */) {
|
14748
|
+
(0, debug_1.assert)(resolvedDecl.node.name !== undefined);
|
14757
14749
|
return (_b = evaluateTypeForSubnode(resolvedDecl.node.name, () => {
|
14758
14750
|
evaluateTypeOfParameter(resolvedDecl.node);
|
14759
14751
|
})) === null || _b === void 0 ? void 0 : _b.type;
|
@@ -14772,8 +14764,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
14772
14764
|
// See if this is an enum member. If so, we need to handle it as a special case.
|
14773
14765
|
const enumMemberType = (0, enums_1.transformTypeForPossibleEnumClass)(evaluatorInterface, resolvedDecl.node, () => {
|
14774
14766
|
var _a, _b;
|
14775
|
-
|
14776
|
-
|
14767
|
+
(0, debug_1.assert)(resolvedDecl.inferredTypeSource !== undefined);
|
14768
|
+
const inferredTypeSource = resolvedDecl.inferredTypeSource;
|
14769
|
+
return ((_b = (_a = evaluateTypeForSubnode(inferredTypeSource, () => {
|
14770
|
+
evaluateTypesForStatement(inferredTypeSource);
|
14777
14771
|
})) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : types_1.UnknownType.create());
|
14778
14772
|
});
|
14779
14773
|
if (enumMemberType) {
|
@@ -15221,7 +15215,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15221
15215
|
// the return type. If a list of args is provided, the inference logic may take
|
15222
15216
|
// into account argument types to infer the return type.
|
15223
15217
|
function getFunctionEffectiveReturnType(type, args, inferTypeIfNeeded = true) {
|
15224
|
-
const specializedReturnType = types_1.FunctionType.getSpecializedReturnType(type);
|
15218
|
+
const specializedReturnType = types_1.FunctionType.getSpecializedReturnType(type, /* includeInferred */ false);
|
15225
15219
|
if (specializedReturnType) {
|
15226
15220
|
return adjustCallableReturnType(specializedReturnType, /* trackedSignatures */ undefined);
|
15227
15221
|
}
|
@@ -15544,8 +15538,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15544
15538
|
// derive from the source. We also need to use this path if we're
|
15545
15539
|
// testing to see if the metaclass matches the protocol.
|
15546
15540
|
if (types_1.ClassType.isProtocolClass(destType) && !isDerivedFrom) {
|
15547
|
-
if (!(0, protocols_1.assignClassToProtocol)(evaluatorInterface, destType, srcType, diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags,
|
15548
|
-
/* treatSourceAsInstantiable */ false, recursionCount)) {
|
15541
|
+
if (!(0, protocols_1.assignClassToProtocol)(evaluatorInterface, destType, types_1.ClassType.cloneAsInstance(srcType), diag === null || diag === void 0 ? void 0 : diag.createAddendum(), destTypeVarContext, srcTypeVarContext, flags, recursionCount)) {
|
15549
15542
|
diag === null || diag === void 0 ? void 0 : diag.addMessage(localize_1.Localizer.DiagnosticAddendum.protocolIncompatible().format({
|
15550
15543
|
sourceType: printType((0, typeUtils_1.convertToInstance)(srcType)),
|
15551
15544
|
destType: printType((0, typeUtils_1.convertToInstance)(destType)),
|
@@ -15797,9 +15790,13 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15797
15790
|
for (let ancestorIndex = inheritanceChain.length - 1; ancestorIndex >= 0; ancestorIndex--) {
|
15798
15791
|
const ancestorType = inheritanceChain[ancestorIndex];
|
15799
15792
|
// If we've hit an "unknown", all bets are off, and we need to assume
|
15800
|
-
// that the type is assignable.
|
15793
|
+
// that the type is assignable. If the destType is marked "@final",
|
15794
|
+
// we should be able to assume that it's not assignable, but we can't do
|
15795
|
+
// this in the general case because it breaks assumptions with the
|
15796
|
+
// NotImplemented symbol exported by typeshed's builtins.pyi. Instead,
|
15797
|
+
// we'll special-case only None.
|
15801
15798
|
if ((0, types_1.isUnknown)(ancestorType)) {
|
15802
|
-
return
|
15799
|
+
return !(0, typeUtils_1.isNoneTypeClass)(destType);
|
15803
15800
|
}
|
15804
15801
|
// If this isn't the first time through the loop, specialize
|
15805
15802
|
// for the next ancestor in the chain.
|
@@ -15852,24 +15849,20 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
15852
15849
|
const srcTypeArgs = curSrcType.typeArguments;
|
15853
15850
|
for (let i = 0; i < destType.details.typeParameters.length; i++) {
|
15854
15851
|
const typeArgType = i < srcTypeArgs.length ? srcTypeArgs[i] : types_1.UnknownType.create();
|
15855
|
-
|
15856
|
-
|
15857
|
-
/*
|
15852
|
+
const typeParam = destType.details.typeParameters[i];
|
15853
|
+
const variance = types_1.TypeVarType.getVariance(typeParam);
|
15854
|
+
(0, constraintSolver_1.updateTypeVarType)(evaluatorInterface, destTypeVarContext, typeParam, variance !== 4 /* Contravariant */ ? typeArgType : undefined, variance !== 3 /* Covariant */ ? typeArgType : undefined,
|
15855
|
+
/* forceRetainLiterals */ true);
|
15858
15856
|
}
|
15859
15857
|
}
|
15860
15858
|
return true;
|
15861
15859
|
}
|
15862
15860
|
function getGetterTypeFromProperty(propertyClass, inferTypeIfNeeded) {
|
15863
|
-
var _a;
|
15864
15861
|
if (!types_1.ClassType.isPropertyClass(propertyClass)) {
|
15865
15862
|
return undefined;
|
15866
15863
|
}
|
15867
|
-
|
15868
|
-
|
15869
|
-
const fgetType = (_a = getDeclaredTypeOfSymbol(fgetSymbol)) === null || _a === void 0 ? void 0 : _a.type;
|
15870
|
-
if (fgetType && (0, types_1.isFunction)(fgetType)) {
|
15871
|
-
return getFunctionEffectiveReturnType(fgetType, /* args */ undefined, inferTypeIfNeeded);
|
15872
|
-
}
|
15864
|
+
if (propertyClass.fgetFunction) {
|
15865
|
+
return getFunctionEffectiveReturnType(propertyClass.fgetFunction, /* args */ undefined, inferTypeIfNeeded);
|
15873
15866
|
}
|
15874
15867
|
return undefined;
|
15875
15868
|
}
|
@@ -16390,8 +16383,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16390
16383
|
// If the destType is an instantiation of a Protocol,
|
16391
16384
|
// see if the class type itself satisfies the protocol.
|
16392
16385
|
if (types_1.ClassType.isProtocolClass(destType)) {
|
16393
|
-
return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags,
|
16394
|
-
/* treatSourceAsInstantiable */ true, recursionCount);
|
16386
|
+
return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), concreteSrcType, diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
|
16395
16387
|
}
|
16396
16388
|
// Determine if the metaclass can be assigned to the object.
|
16397
16389
|
const metaclass = concreteSrcType.details.effectiveMetaclass;
|
@@ -16415,14 +16407,15 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16415
16407
|
if ((0, types_1.isFunction)(destType)) {
|
16416
16408
|
let concreteSrcType = makeTopLevelTypeVarsConcrete(srcType);
|
16417
16409
|
if ((0, types_1.isClassInstance)(concreteSrcType)) {
|
16418
|
-
const boundMethod =
|
16410
|
+
const boundMethod = getBoundMagicMethod(concreteSrcType, '__call__',
|
16411
|
+
/* selfType */ undefined, recursionCount);
|
16419
16412
|
if (boundMethod) {
|
16420
16413
|
concreteSrcType = (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
|
16421
16414
|
}
|
16422
16415
|
}
|
16423
16416
|
// If it's a class, use the constructor for type compatibility checking.
|
16424
16417
|
if ((0, types_1.isInstantiableClass)(concreteSrcType) && concreteSrcType.literalValue === undefined) {
|
16425
|
-
const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, recursionCount);
|
16418
|
+
const constructor = (0, constructors_1.createFunctionFromConstructor)(evaluatorInterface, concreteSrcType, (0, types_1.isTypeVar)(srcType) ? (0, typeUtils_1.convertToInstance)(srcType) : undefined, recursionCount);
|
16426
16419
|
if (constructor) {
|
16427
16420
|
concreteSrcType = constructor;
|
16428
16421
|
}
|
@@ -16517,8 +16510,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16517
16510
|
// Are we trying to assign None to a protocol?
|
16518
16511
|
if ((0, typeUtils_1.isNoneInstance)(srcType) && (0, types_1.isClassInstance)(destType) && types_1.ClassType.isProtocolClass(destType)) {
|
16519
16512
|
if (noneClassType && (0, types_1.isInstantiableClass)(noneClassType)) {
|
16520
|
-
return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), noneClassType, diag, destTypeVarContext, srcTypeVarContext, flags,
|
16521
|
-
/* treatSourceAsInstantiable */ false, recursionCount);
|
16513
|
+
return (0, protocols_1.assignClassToProtocol)(evaluatorInterface, types_1.ClassType.cloneAsInstantiable(destType), types_1.ClassType.cloneAsInstance(noneClassType), diag, destTypeVarContext, srcTypeVarContext, flags, recursionCount);
|
16522
16514
|
}
|
16523
16515
|
}
|
16524
16516
|
if ((0, typeUtils_1.isNoneInstance)(destType)) {
|
@@ -16907,7 +16899,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16907
16899
|
}
|
16908
16900
|
}
|
16909
16901
|
}
|
16910
|
-
const boundMethod =
|
16902
|
+
const boundMethod = getBoundMagicMethod(objType, '__call__', /* selfType */ undefined, recursionCount);
|
16911
16903
|
if (boundMethod) {
|
16912
16904
|
return (0, typeUtils_1.removeParamSpecVariadicsFromSignature)(boundMethod);
|
16913
16905
|
}
|
@@ -16993,7 +16985,10 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
16993
16985
|
if (srcDetails.params.length < destDetails.argsIndex) {
|
16994
16986
|
return;
|
16995
16987
|
}
|
16996
|
-
let srcLastToPackIndex = srcDetails.params.findIndex((p, i) =>
|
16988
|
+
let srcLastToPackIndex = srcDetails.params.findIndex((p, i) => {
|
16989
|
+
(0, debug_1.assert)(destDetails.argsIndex !== undefined);
|
16990
|
+
return i >= destDetails.argsIndex && p.source === parameterUtils_1.ParameterSource.KeywordOnly;
|
16991
|
+
});
|
16997
16992
|
if (srcLastToPackIndex < 0) {
|
16998
16993
|
srcLastToPackIndex = srcDetails.params.length;
|
16999
16994
|
}
|
@@ -17655,7 +17650,7 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
17655
17650
|
matchIndex = possibleMatchIndex;
|
17656
17651
|
}
|
17657
17652
|
if (matchIndex < 0) {
|
17658
|
-
|
17653
|
+
break;
|
17659
17654
|
}
|
17660
17655
|
if (matchIndex < previousMatchIndex) {
|
17661
17656
|
diag.addMessage(localize_1.Localizer.DiagnosticAddendum.overrideOverloadOrder());
|
@@ -18109,14 +18104,6 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18109
18104
|
});
|
18110
18105
|
return methodList;
|
18111
18106
|
}
|
18112
|
-
function bindFunctionToClassOrObjectWithErrors(baseType, memberType, memberClass, errorNode, treatConstructorAsClassMember = false, selfType) {
|
18113
|
-
const diag = errorNode ? new diagnostic_1.DiagnosticAddendum() : undefined;
|
18114
|
-
const result = bindFunctionToClassOrObject(baseType, memberType, memberClass, treatConstructorAsClassMember, selfType, diag);
|
18115
|
-
if (!result && errorNode && diag) {
|
18116
|
-
addDiagnostic(AnalyzerNodeInfo.getFileInfo(errorNode).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, diag.getString(), errorNode);
|
18117
|
-
}
|
18118
|
-
return result;
|
18119
|
-
}
|
18120
18107
|
// If the memberType is an instance or class method, creates a new
|
18121
18108
|
// version of the function that has the "self" or "cls" parameter bound
|
18122
18109
|
// to it. If treatConstructorAsClassMember is true, the function is
|
@@ -18135,9 +18122,9 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18135
18122
|
if ((0, typeUtils_1.isInstantiableMetaclass)(baseType)) {
|
18136
18123
|
return functionType;
|
18137
18124
|
}
|
18138
|
-
const baseObj = (0, types_1.
|
18139
|
-
?
|
18140
|
-
: baseType;
|
18125
|
+
const baseObj = (0, types_1.isClassInstance)(baseType)
|
18126
|
+
? baseType
|
18127
|
+
: types_1.ClassType.cloneAsInstance((0, typeUtils_1.specializeClassType)(baseType));
|
18141
18128
|
return partiallySpecializeFunctionForBoundClassOrObject(baseType, functionType, memberClass !== null && memberClass !== void 0 ? memberClass : types_1.ClassType.cloneAsInstantiable(baseObj), diag, recursionCount, selfType !== null && selfType !== void 0 ? selfType : baseObj,
|
18142
18129
|
/* stripFirstParam */ (0, types_1.isClassInstance)(baseType));
|
18143
18130
|
}
|
@@ -18444,8 +18431,8 @@ function createTypeEvaluator(importLookup, evaluatorOptions) {
|
|
18444
18431
|
getBestOverloadForArguments,
|
18445
18432
|
getBuiltInType,
|
18446
18433
|
getTypeOfMember,
|
18447
|
-
|
18448
|
-
|
18434
|
+
getTypeOfBoundMember,
|
18435
|
+
getBoundMagicMethod,
|
18449
18436
|
getTypeOfMagicMethodCall,
|
18450
18437
|
bindFunctionToClassOrObject,
|
18451
18438
|
getCallSignatureInfo,
|