Python 中的依赖类型和多态性与 mypy

Dependent types and polymorphism in Python with mypy

对于下面的例子,mypy returns 一个错误:

error: Incompatible types in assignment (expression has type "A", variable has type "A1")

from typing import Type

class A:
    pass

class A1(A):
    pass

class A2(A):
    pass

def fun(A_type: Type[A]) -> A:
    if A_type == A1:
        return A1()
    else:
        return A2()

a1: A1 = fun(A1)

我最想做的是在 fun:

的签名中强制执行依赖
def fun(A_type: Type[A]) -> A_type

这可能吗?如果不是,推荐什么(注意:我希望它适用于 A 的尚未定义的子 类,所以我认为我不能使用 overload 装饰器)?我最好的选择是使用 cast 吗?

使用带有边界的 TypeVar:

https://mypy.readthedocs.io/en/latest/generics.html#type-variables-with-upper-bounds

from typing import Type, TypeVar

class A:
    pass

class A1(A):
    pass

class A2(A):
    pass

T_A = TypeVar('T_A', bound='A')

def fun(A_type: Type[T_A]) -> T_A:
    if A_type == A1:
        r1 = A1()
        assert isinstance(r1, A_type)
        return r1
    else:
        r2 = A2()
        assert isinstance(r2, A_type)
        return r2

a1: A1 = fun(A1)
a2: A2 = fun(A2)
print("winner winner chicken dinner")

typechecks clean and runs without failing any type assert:

C:\test\python>mypy polymorph.py
Success: no issues found in 1 source file

C:\test\python>python polymorph.py
winner winner chicken dinner

在这个例子中,类型 T_A 必须是 A 的子类,但它是一个 特定的 类型,fun 要求它 returns 与作为参数接收的类型相同。

不幸的是,静态类型检查器相当不够智能,无法绑定类型,除非您在其中添加运行时断言(可能有一些方法可以通过Generic 键入但它让我望而却步)。