from dataclasses import dataclass
class Eq:
def __init__(self, v: int) -> None:
self.v = v
def __eq__(self, other: object) -> bool:
return isinstance(other, Eq) and self.v == other.v
assert Eq(1) == Eq(1)
assert not (Eq(1) == Eq(2)), 'differing values are unequal'
assert Eq(1) != Eq(2)
assert not (Eq(1) != Eq(1)), '!= is the negation of __eq__'
assert not (Eq(1) == 1), 'comparison against a foreign type'
assert Eq(1) != 1
try:
hash(Eq(1))
assert False, 'expected unhashable'
except TypeError as e:
assert str(e) == "unhashable type: 'Eq'", f'wrong message: {e!r}'
class EqHash:
def __init__(self, v: int) -> None:
self.v = v
def __eq__(self, other: object) -> bool:
return isinstance(other, EqHash) and self.v == other.v
def __hash__(self) -> int:
return hash(self.v)
assert hash(EqHash(1)) == hash(EqHash(1))
assert hash(EqHash(1)) == hash(1)
assert len({EqHash(1), EqHash(1)}) == 1
assert len({EqHash(1), EqHash(2)}) == 2
assert {EqHash(1): 'x'}[EqHash(1)] == 'x'
assert EqHash(1) in {EqHash(1): 'x'}
assert Eq(1) in [Eq(2), Eq(1)]
assert Eq(3) not in [Eq(2), Eq(1)]
assert [Eq(1), Eq(2)] == [Eq(1), Eq(2)]
assert (Eq(1),) == (Eq(1),)
class NoHash:
__hash__ = None
try:
hash(NoHash())
assert False, 'expected unhashable'
except TypeError as e:
assert str(e) == "unhashable type: 'NoHash'", f'wrong message: {e!r}'
class Plain:
def __init__(self, v: int) -> None:
self.v = v
p = Plain(1)
assert p == p
assert not (Plain(1) == Plain(1)), 'distinct instances are unequal without __eq__'
assert isinstance(hash(p), int), 'hashable by identity'
@dataclass
class DC:
x: int
def __eq__(self, other: object) -> bool:
return True
assert DC(1) == DC(2)
try:
hash(DC(1))
assert False, 'expected unhashable'
except TypeError as e:
assert str(e) == "unhashable type: 'DC'", f'wrong message: {e!r}'
@dataclass
class Synth:
x: int
assert Synth(1) == Synth(1)
assert Synth(1) != Synth(2)
class Never:
def __eq__(self, other: object) -> bool:
return False
def __hash__(self) -> int:
return 1
never = Never()
assert not (never == never), 'the operator dispatches __eq__ against self'
assert never != never
assert never in [never]
assert [never] == [never]
assert (never,) == (never,)
assert {'k': never} == {'k': never}
assert [never].index(never) == 0
@dataclass
class Holder:
f: object
holder = Holder(never)
assert holder == holder
assert not (Holder(never) == Holder(never)), 'fields compare with the == operator'