问题描述
我正在创建一个匹配器库,通过与 ==
的值进行比较来使用这些匹配器。不幸的是,当将包含匹配器实例的复合类型与具有非 Any
类型的值进行比较时,如下所示:
assert {"foo": SomeMatcher(arg)} == {"foo": 3}
然后带有 --strict-equality
标志的 mypy 会抱怨“非重叠相等性检查”。目前,我正在通过调用构造函数来解决这个问题,这些函数的返回类型被注释为 Any
,但我想知道是否有可能让 mypy 像往常一样自动处理我的匹配器实例 Any
.我知道这样的事情是可能的,因为 mypy 允许传递 unittest.mock.Mock
实例代替非 Mock
参数,好像 Mock
实例都具有类型 Any
—还是硬编码到 mypy 中的东西?
我已经尝试通过给我的匹配器一个简单的 __new__
来让它工作,它用返回类型 Any
进行注释,以及使用一个 __new__
具有返回类型 { 的元类{1}},但都不起作用。
失败匹配器的 MVCE:
Any
解决方法
Mypy 确实有一些针对 certain cases,for example set
and frozenset
的硬编码异常。虽然不是为了 unittest.mock.Mock
,但它已经解决了 by subclassing Any
。
子类化 Any
适用于类型存根,但在运行时 python 抛出错误:TypeError: Cannot subclass typing.Any
。下面解决了这个问题:
from typing import TYPE_CHECKING,Any
if TYPE_CHECKING:
Base = Any
else:
Base = object
class InRange(Base):
def __init__(self,start: int,end: int) -> None:
self.start = start
self.end = end
def __eq__(self,other: Any) -> bool:
try:
return bool(self.start <= other <= self.end)
except (TypeError,ValueError):
return False
assert {"foo": InRange(1,5)} == {"foo": 3}
assert {"foo": 3} == {"foo": InRange(1,5)}