我喜欢 python 的类型提示,我编写了以下脚本,该脚本在 MyPy 0.590 中失败并显示
Unsupported type Type["T"]
。
from typing import Type, TypeVar
AnyT = TypeVar('AnyT')
T = TypeVar('T', bound='A')
class A:
def __init__(self, arg: AnyT = None) -> None:
pass
@classmethod
def fn(cls: Type[T]) -> T: # E: Unsupported type Type["T"]
return cls()
为什么会导致错误?
在典型用例中,
AnyT
等于T
,并且__init__(self, other)
将other
复制到self
。
请注意,以下稍有不同的程序没有错误:
from typing import Type, TypeVar
T = TypeVar('T', bound='A')
class A:
def __init__(self, arg: int = None) -> None:
pass
@classmethod
def fn(cls: Type[T]) -> T: # No errors
return cls()
和
from typing import Type, TypeVar
AnyT = TypeVar('AnyT')
T = TypeVar('T') # no bounds
class A:
def __init__(self, arg: AnyT = None) -> None:
pass
@classmethod
def fn(cls: Type[T]) -> T: # No errors
return cls()
另请注意,以下解决方案对我不起作用:
from typing import TypeVar
AnyT = TypeVar('AnyT')
class A:
def __init__(self, arg: AnyT = None) -> None:
pass
@classmethod
def fn(cls) -> 'A': # Obviously no errors
return cls()
这是因为这没有考虑
A
的继承(如果一个类B
继承自A
,B.fn()
将返回B
的实例,但MyPy认为它返回A
的实例)这个例子)。
有什么想法吗?
我认为这是 mypy 中的一个错误,因为它不再发生。
Self
类型更轻松地编写类方法的返回类型(在 Python 3.11 中引入,但通过 typing_extensions
包在早期版本中可用):
@classmethod
def fn(cls) -> Self:
return cls()
原始代码片段现在会在
__init__()
函数中导致不相关的 mypy 错误:“error: Incompatible default for argument "arg" (default has type "None", argument has type "AnyT")
”,而 Pyright 则显示“error: TypeVar "AnyT" appears only once in generic function signature
”。