如何正确键入提示类装饰器?

问题描述 投票:0回答:1

假设我们有一些函数

func
将类
A
的实例映射到类
B
的实例,即它具有签名
Callable[[A], B]

我想为

autofunc
的子类编写一个类装饰器
A
,它会在创建实例时自动将
func
应用于实例。例如,考虑基于全局环境变量的自动 jit 编译。这可以通过

完成
from functools import wraps

def autofunc(basecls):
    @wraps(basecls, updated=())

    class WrappedClass(basecls):
        def __new__(cls, *args, **kwargs):
            instance = basecls(*args, **kwargs)
            return func(instance)
    return WrappedClass

那么下面两个大致等价:

class C(A):         

   ...              

                    

instance = func(C())

                    

@autofunc           

class C(A):         

    ...             

                    

instance = C()      

我天真地尝试过

def autofunc(basecls: type[A]) -> type[B]:

    @wraps(basecls, updated=())
    class WrappedClass(basecls):

        def __new__(cls, *args, **kwargs):
            instance = basecls(*args, **kwargs)
            return func(instance)

    return WrappedClass

哪个

mypy
真的不喜欢,引发错误:

  • error: Variable "basecls" is not valid as a type  [valid-type]
  • error: Invalid base class "basecls"  [misc]
  • 此外,还有一个问题是
    WrapperClass.__new__
    返回
    B
    的实例,而不是
    WrapperClass
    的实例。

目前有什么方法可以正确键入提示这样的类装饰器,或者

mypy
还无法执行此操作?


示例代码:
from functools import wraps


class A:
    pass


class B:
    pass


def func(cl: A) -> B:
    print(f"Replacing {cl=}")
    return B()


def autofunc(basecls: type[A]) -> type[B]:

    @wraps(basecls, updated=())
    class WrappedClass(basecls):

        def __new__(cls, *args, **kwargs):
            instance = basecls()
            return func(instance)

    return WrappedClass
python mypy python-typing
1个回答
3
投票

这只是

mypy
中的一个错误:https://github.com/python/mypy/issues/5865

© www.soinside.com 2019 - 2024. All rights reserved.