为什么不允许子类上的属性返回与超类上相同属性一致的类型

Jos*_*osh 5 python inheritance typing typechecking mypy

class Foo:
    bar: str

class Bat(Foo):
    @property
    def bar(self) -> str:
        ...
Run Code Online (Sandbox Code Playgroud)

鉴于上面的代码,我的类型检查器(mypy)提出了以下抱怨:

error: Signature of "bar" incompatible with supertype "Foo"  [override]
Run Code Online (Sandbox Code Playgroud)

这让我感到惊讶,因为从访问属性/属性的调用者的角度来看,Foo或的实例的Bat行为是相同的bar。类型检查器通过拒绝此代码来防止什么问题?

Bor*_*jaX 6

扩展对OP的评论:

旧版本的 Mypy 存在某种与此无关的问题/错误,这导致了该项目的 GitHub 上的一些讨论:Mypy 不允许使用属性覆盖属性,并且应该在 >=v0.990 的版本上修复该问题

还有一个讨论,感觉更接近当前的 OP 阐述:用属性重写变量:错误签名与超类型不兼容

在第二种情况下,发生的事情是......

class Foo:
    bar: str
Run Code Online (Sandbox Code Playgroud)

...告诉 Mypy 这.bar将是一个可写属性,而只是@property在子类中声明Bat...

class Bat(Foo):
    @property
    def bar(self) -> str:
Run Code Online (Sandbox Code Playgroud)

...将使该属性成为只读。在这种情况下,最直接的修复可能是为.bar.

下面的代码:

class Foo:
    bar: str
Run Code Online (Sandbox Code Playgroud)

生产:

Success: no issues found in 1 source file
Run Code Online (Sandbox Code Playgroud)