带mypy的可变参数:方法的签名与超类型不兼容

时间:2019-03-08 21:47:25

标签: python python-3.x typing mypy

我不太确定为什么mypy在这里返回Signature of "foo" is incompatible with supertype "Base"错误。返回类型和参数类型似乎匹配。

from typing import NoReturn, Union


class Base():
    def foo(self, *args: str) -> Union[NoReturn, str]:
        raise NotImplementedError


class A(Base):
    def foo(self, x: str) -> str:
        return x

非常感谢您的帮助,谢谢!

编辑 我将A.foo更改为此:

def foo(self, *args: str) -> str:
    x = args[0]
    return x

现在mypy错误消失了。但是,使用此实现,如果NoReturn中存在Base时,被覆盖的函数只能返回str会不会出现相同的问题?

2 个答案:

答案 0 :(得分:0)

差别有点微妙。因此,我将解释它们各自的作用

reproject

def foo(self, *args: str) -> Union[NoReturn, str]: 是类foo的实例方法,它采用可变数量的字符串参数并返回BaseNoReturn

str

def foo(self, x: str) -> str: 是类foo的实例方法,它覆盖A类中foo的定义。它接受一个Base参数,并返回一个str

这意味着我可以调用str之类的Base版本,但是在foo('bar', 'baz')中的相同调用会引发错误。

类似地,我无法在A中返回,而被覆盖的函数调用仅返回Base

这里的问题是该函数具有不同的行为和类型,但名称相同,这具有误导性。

答案 1 :(得分:0)

没有您的编辑,您遇到了@Skam描述的问题: https://stackoverflow.com/a/55071593/369009

使用 EDIT ,一切正常。考虑一下这段代码:

bs: Base = A() # bs is of type Base
return_value = bs.foo('test') # Return value is of type `Union[NoReturn, str]`

调用bs.foo时,我们将返回值设为NoReturnstrA总是返回str,但这很好,因为str也是Union[NoReturn, str]的一部分,因此这始终有效。在基类上调用foo的任何人都必须处理两种返回类型,而A恰好总是总是仅返回str而从不返回NoReturn

只有相反的情况才是问题: 假设A将返回Union,而Base将返回str,则Base.foo的调用者在仅期望时会突然得到NoReturn str