mirror of
https://github.com/microsoft/pyright.git
synced 2024-09-11 07:55:56 +03:00
Fixed a bug in bindFunctionToClassOrObject function that resulted in incorrect results when binding a class object to a method in its metaclass. Also renamed the treatConstructorAsClassMethod
parameter for clarity.
This commit is contained in:
parent
975c846895
commit
19183640d8
@ -837,7 +837,7 @@ function createFunctionFromNewMethod(
|
||||
classType,
|
||||
newSubtype,
|
||||
newInfo && isInstantiableClass(newInfo.classType) ? newInfo.classType : undefined,
|
||||
/* treatConstructorAsClassMember */ true,
|
||||
/* treatConstructorAsClassMethod */ true,
|
||||
selfType,
|
||||
/* diag */ undefined,
|
||||
recursionCount
|
||||
@ -926,7 +926,7 @@ function createFunctionFromInitMethod(
|
||||
objectType,
|
||||
initSubtype,
|
||||
initInfo && isInstantiableClass(initInfo.classType) ? initInfo.classType : undefined,
|
||||
/* treatConstructorAsClassMember */ undefined,
|
||||
/* treatConstructorAsClassMethod */ undefined,
|
||||
selfType,
|
||||
/* diag */ undefined,
|
||||
recursionCount
|
||||
|
@ -545,7 +545,7 @@ export function assignProperty(
|
||||
destObjectToBind,
|
||||
destAccessType,
|
||||
/* memberClass */ undefined,
|
||||
/* treatConstructorAsClassMember */ undefined,
|
||||
/* treatConstructorAsClassMethod */ undefined,
|
||||
/* firstParamType */ undefined,
|
||||
diag?.createAddendum(),
|
||||
recursionCount
|
||||
@ -555,7 +555,7 @@ export function assignProperty(
|
||||
srcObjectToBind,
|
||||
srcAccessType,
|
||||
/* memberClass */ undefined,
|
||||
/* treatConstructorAsClassMember */ undefined,
|
||||
/* treatConstructorAsClassMethod */ undefined,
|
||||
/* firstParamType */ undefined,
|
||||
diag?.createAddendum(),
|
||||
recursionCount
|
||||
|
@ -447,7 +447,7 @@ function assignClassToProtocolInternal(
|
||||
: ClassType.cloneAsInstance(srcType),
|
||||
srcMemberType,
|
||||
isMemberFromMetaclass ? undefined : (srcMemberInfo.classType as ClassType),
|
||||
/* treatConstructorAsClassMember */ undefined,
|
||||
/* treatConstructorAsClassMethod */ undefined,
|
||||
isMemberFromMetaclass ? srcType : selfType,
|
||||
diag?.createAddendum(),
|
||||
recursionCount
|
||||
@ -493,7 +493,7 @@ function assignClassToProtocolInternal(
|
||||
ClassType.cloneAsInstance(srcType),
|
||||
destMemberType,
|
||||
isMemberFromMetaclass ? undefined : (srcMemberInfo.classType as ClassType),
|
||||
/* treatConstructorAsClassMember */ undefined,
|
||||
/* treatConstructorAsClassMethod */ undefined,
|
||||
isMemberFromMetaclass ? srcType : selfType,
|
||||
diag,
|
||||
recursionCount
|
||||
@ -504,7 +504,7 @@ function assignClassToProtocolInternal(
|
||||
ClassType.cloneAsInstance(destType),
|
||||
destMemberType,
|
||||
destType,
|
||||
/* treatConstructorAsClassMember */ undefined,
|
||||
/* treatConstructorAsClassMethod */ undefined,
|
||||
/* firstParamType */ undefined,
|
||||
diag,
|
||||
recursionCount
|
||||
|
@ -26481,7 +26481,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
|
||||
// If the memberType is an instance or class method, creates a new
|
||||
// version of the function that has the "self" or "cls" parameter bound
|
||||
// to it. If treatConstructorAsClassMember is true, the function is
|
||||
// to it. If treatConstructorAsClassMethod is true, the function is
|
||||
// treated like a class method even if it's not marked as such. That's
|
||||
// needed to special-case the __new__ magic method when it's invoked as
|
||||
// a constructor (as opposed to by name).
|
||||
@ -26489,7 +26489,7 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
baseType: ClassType | undefined,
|
||||
memberType: FunctionType | OverloadedFunctionType,
|
||||
memberClass?: ClassType,
|
||||
treatConstructorAsClassMember = false,
|
||||
treatConstructorAsClassMethod = false,
|
||||
selfType?: ClassType | TypeVarType,
|
||||
diag?: DiagnosticAddendum,
|
||||
recursionCount = 0
|
||||
@ -26511,6 +26511,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
? baseType
|
||||
: ClassType.cloneAsInstance(specializeClassType(baseType));
|
||||
|
||||
let stripFirstParam = false;
|
||||
if (isClassInstance(baseType)) {
|
||||
stripFirstParam = true;
|
||||
} else if (memberClass && isInstantiableMetaclass(memberClass)) {
|
||||
stripFirstParam = true;
|
||||
}
|
||||
|
||||
return partiallySpecializeFunctionForBoundClassOrObject(
|
||||
baseType,
|
||||
functionType,
|
||||
@ -26518,13 +26525,13 @@ export function createTypeEvaluator(importLookup: ImportLookup, evaluatorOptions
|
||||
diag,
|
||||
recursionCount,
|
||||
selfType ?? baseObj,
|
||||
/* stripFirstParam */ isClassInstance(baseType)
|
||||
stripFirstParam
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
FunctionType.isClassMethod(functionType) ||
|
||||
(treatConstructorAsClassMember && FunctionType.isConstructorMethod(functionType))
|
||||
(treatConstructorAsClassMethod && FunctionType.isConstructorMethod(functionType))
|
||||
) {
|
||||
const baseClass = isInstantiableClass(baseType) ? baseType : ClassType.cloneAsInstantiable(baseType);
|
||||
const clsType = selfType ? (convertToInstantiable(selfType) as ClassType | TypeVarType) : undefined;
|
||||
|
@ -583,7 +583,7 @@ export interface TypeEvaluator {
|
||||
baseType: ClassType | undefined,
|
||||
memberType: FunctionType | OverloadedFunctionType,
|
||||
memberClass?: ClassType,
|
||||
treatConstructorAsClassMember?: boolean,
|
||||
treatConstructorAsClassMethod?: boolean,
|
||||
selfType?: ClassType | TypeVarType,
|
||||
diag?: DiagnosticAddendum,
|
||||
recursionCount?: number
|
||||
|
@ -442,13 +442,13 @@ export function getClassAndConstructorTypes(node: NameNode, evaluator: TypeEvalu
|
||||
|
||||
// Prefer `__new__` if it doesn't have default params (*args: Any, **kwargs: Any) or no params ().
|
||||
if (isFunction(newMemberType) || isOverloadedFunction(newMemberType)) {
|
||||
// Set `treatConstructorAsClassMember` to true to exclude `cls` as a parameter.
|
||||
// Set `treatConstructorAsClassMethod` to true to exclude `cls` as a parameter.
|
||||
methodType = bindFunctionToClassOrObjectToolTip(
|
||||
evaluator,
|
||||
node,
|
||||
instanceType,
|
||||
newMemberType,
|
||||
/* treatConstructorAsClassMember */ true
|
||||
/* treatConstructorAsClassMethod */ true
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -462,13 +462,13 @@ export function bindFunctionToClassOrObjectToolTip(
|
||||
node: ExpressionNode,
|
||||
baseType: ClassType | undefined,
|
||||
memberType: FunctionType | OverloadedFunctionType,
|
||||
treatConstructorAsClassMember?: boolean
|
||||
treatConstructorAsClassMethod?: boolean
|
||||
): FunctionType | OverloadedFunctionType | undefined {
|
||||
const methodType = evaluator.bindFunctionToClassOrObject(
|
||||
baseType,
|
||||
memberType,
|
||||
/* memberClass */ undefined,
|
||||
treatConstructorAsClassMember
|
||||
treatConstructorAsClassMethod
|
||||
);
|
||||
|
||||
if (!methodType) {
|
||||
|
Loading…
Reference in New Issue
Block a user