当 T 的边界有可选参数时,为什么 Type[T] -> T 类方法在不支持的类型中失败?

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

我喜欢 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
的实例)这个例子)。

有什么想法吗?

python class type-hinting mypy
1个回答
0
投票

我认为这是 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
”。

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