Changed behavior of conversion from class constructor to callable to conform to honor the annotated type of self in the __init__ method. This addresses #7688. (#7699)

This commit is contained in:
Eric Traut 2024-04-13 22:06:32 -07:00 committed by GitHub
parent 43fe9a7e2c
commit 71a3b60960
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 18 deletions

View File

@ -993,7 +993,7 @@ function createFunctionFromInitMethod(
const objectType = ClassType.cloneAsInstance(classType);
function convertInitToConstructor(initSubtype: FunctionType) {
let constructorFunction = evaluator.bindFunctionToClassOrObject(
const boundInit = evaluator.bindFunctionToClassOrObject(
objectType,
initSubtype,
initInfo && isInstantiableClass(initInfo.classType) ? initInfo.classType : undefined,
@ -1003,25 +1003,27 @@ function createFunctionFromInitMethod(
recursionCount
) as FunctionType | undefined;
if (constructorFunction) {
constructorFunction = FunctionType.clone(constructorFunction);
constructorFunction.details.declaredReturnType = selfType ?? objectType;
constructorFunction.details.name = '';
constructorFunction.details.fullName = '';
if (constructorFunction.specializedTypes) {
constructorFunction.specializedTypes.returnType = selfType ?? objectType;
}
if (!constructorFunction.details.docString && classType.details.docString) {
constructorFunction.details.docString = classType.details.docString;
}
constructorFunction.details.flags &= ~FunctionTypeFlags.StaticMethod;
constructorFunction.details.constructorTypeVarScopeId = getTypeVarScopeId(classType);
if (!boundInit) {
return undefined;
}
return constructorFunction;
const convertedInit = FunctionType.clone(boundInit);
convertedInit.details.declaredReturnType = boundInit.strippedFirstParamType ?? selfType ?? objectType;
convertedInit.details.name = '';
convertedInit.details.fullName = '';
if (convertedInit.specializedTypes) {
convertedInit.specializedTypes.returnType = selfType ?? objectType;
}
if (!convertedInit.details.docString && classType.details.docString) {
convertedInit.details.docString = classType.details.docString;
}
convertedInit.details.flags &= ~FunctionTypeFlags.StaticMethod;
convertedInit.details.constructorTypeVarScopeId = getTypeVarScopeId(classType);
return convertedInit;
}
if (isFunction(initType)) {

View File

@ -10,6 +10,7 @@ from typing import (
ParamSpec,
Self,
TypeVar,
overload,
reveal_type,
)
@ -101,3 +102,21 @@ class Class6_2:
r6_2 = accepts_callable(Class6_2)
reveal_type(r6_2, expected_text="() -> Any")
reveal_type(r6_2(), expected_text="Any")
class Class7(Generic[T]):
@overload
def __init__(self: "Class7[int]", x: int) -> None: ...
@overload
def __init__(self: "Class7[str]", x: str) -> None: ...
def __init__(self, x: int | str) -> None:
pass
r7 = accepts_callable(Class7)
reveal_type(
r7, expected_text="Overload[(x: int) -> Class7[int], (x: str) -> Class7[str]]"
)
reveal_type(r7(0), expected_text="Class7[int]")
reveal_type(r7(""), expected_text="Class7[str]")