I'm creating a library of matchers that are used by comparing against values with ==
. Unfortunately, when comparing a compound type containing a matcher instance against a value with a non-Any
type, like so:
assert {"foo": SomeMatcher(arg)} == {"foo": 3}
then mypy with the --strict-equality
flag complains about a "Non-overlapping equality check". For now, I'm working around this by calling the constructors via functions whose return types are annotated as Any
, but I'm wondering if it's possible to make mypy treat my matcher instances as always Any
automatically. I know something like this is possible, as mypy allows unittest.mock.Mock
instances to be passed in place of non-Mock
arguments, as though the Mock
instances all had type Any
— or is that something hardcoded into mypy?
I've already tried getting this to work by giving my matchers a trivial __new__
that's annotated with return type Any
, as well as using a metaclass whose __new__
had return type Any
, but neither worked.
An MVCE of a failing matcher:
from typing import Any
class InRange:
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)}