引用泛型类型的类属性

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

我有一个抽象基类,它定义了几个类属性,这些属性本身就是类型(即嵌套类型);这些属性在从抽象类继承的具体派生类中被重写。具体的派生类与其他几个被类型注释为泛型的类一起使用,其中类型参数具有必须从抽象类派生的类型约束。我希望这些其他类(泛型)引用具体类的类属性(嵌套类型)。下面的例子应该演示这个想法:

import typing

class Base:
    A: typing.Type[Base]

class One(Base):
    class A(Base):  # overrides Base.A
        pass

class Two(Base):
    class A(One):  # overrides Base.A
        pass


T = typing.TypeVar('T', bound=Base)

class Foo(typing.Generic[T]):                 # the generic
    def foo(self, a: typing.Type[T.A]) -> T:  # <-- here, see T.A
        ...

f: Foo[Two] = Foo()
f.foo(Two.A)        # line 22 is here

MyPy v0.701 在第 22 行报告错误:

“Foo”的“foo”的参数 1 具有不兼容的类型“Type[A]”;预期“类型[二]”

MyPy 似乎忽略了

T.A
处的属性引用。我如何让它理解我正在尝试通过属性
.A
引用可用的类型?该属性保证可用,因为类型变量
T
被限制为
Base
,后者具有
A
。请注意,扩展泛型类型集不是一个选项;我可以详细说明这一点,但解释对于我的应用程序来说过于具体。

更新: MyPy v0.711 与

--new-semantic-analyzer
产生更容易理解的错误消息:

名称“T.A”未定义

python python-typing mypy
1个回答
0
投票

我不确定这是否有帮助,但如果你参数化绑定到 Base 的参数,它会起作用:

class Base:
    A: typing.Type['Base']


class One(Base):
    class A(Base):  # overrides Base.A
        pass


class Two(Base):
    class A(One):  # overrides Base.A
        pass


T = typing.TypeVar('T', bound='Base')
A = typing.TypeVar('A', bound='Base')


class Foo(typing.Generic[T, A]):    # the generic
    def foo(self, a: typing.Type[A]) -> T:  # <-- here, see T.A
        pass


f: Foo[Two, Two.A] = Foo()
f.foo(Two.A)        # line 22 is here

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