Skip to content

Commit

Permalink
tools.memories, test: codify SopelIdentifierMemory == dict behavior
Browse files Browse the repository at this point in the history
Comparing two `SopelIdentifierMemory` instances using `==` already
worked, but if one side of the comparison was a plain `dict` it would
be almost impossible for the two to be considered equal.

It's obviously doable to override `__eq__()`/`__ne__()` and make the two
types test as equal if they have equal values associated with keys-that-
are-equivalent-when-compared-as-`Identifier`s, but we probably shouldn't
do that. I'm perfectly happy to consider objects of different types as
"not equal" even if they contain equivalent key-value pairs.

Therefore, these new tests codify the `==`/`!=` behavior as follows:

* `SopelIdentifierMemory` objects will compare as equal if their keys
  and values compare as equal, even if they use different
  `IdentifierFactory` (the `make_identifier` parameter) implementations.
* A `SopelIdentifierMemory` and a `dict[Identifier]` MAY compare as
  equal if the `Identifier` keys in each were created by compatible (but
  not necessarily identical) `IdentifierFactory` implementations.
* A `SopelIdentifierMemory` and a `dict[str]` (or any other `dict` with
  non-`Identifier` keys) are not expected to compare as equal.
  • Loading branch information
dgw committed Oct 29, 2023
1 parent e803541 commit 7c48831
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
8 changes: 8 additions & 0 deletions sopel/tools/memories.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,11 @@ def __ior__(self, other):
return NotImplemented
self.update(other)
return self

def __eq__(self, other):
if not isinstance(other, dict):
return NotImplemented
return super().__eq__(other)

def __ne__(self, other):
return not self.__eq__(other)
34 changes: 34 additions & 0 deletions test/tools/test_tools_memories.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,3 +441,37 @@ def test_sopel_identifier_memory_ior_op_dict():
assert memory['fROmMemorY'] is True
assert memory['fROmDicT'] is True
assert 'FromTuple' not in memory


def test_sopel_identifier_memory_eq():
"""Test equality checks between two `SopelIdentifierMemory` instances."""
memory = memories.SopelIdentifierMemory({'Foo': 'bar', 'Baz': 'Luhrmann'})
other_memory = memories.SopelIdentifierMemory((('Foo', 'bar'), ('Baz', 'Luhrmann')))

assert memory == other_memory
assert other_memory == memory # cover our bases vis-a-vis operand precedence


def test_sopel_identifier_memory_eq_dict_id():
"""Test ``SopelIdentifierMemory`` comparison to ``dict[Identifier, Any]``.
These can be equivalent, just like two ``dict`` objects with identical
``Identifier`` keys can be.
"""
memory = memories.SopelIdentifierMemory({'Foo': 'bar', 'Baz': 'Luhrmann'})
dictionary = dict(memory)

assert dictionary == memory
assert memory == dictionary # cover our bases vis-a-vis operand precedence


def test_sopel_identifier_memory_eq_dict_str():
"""Test ``SopelIdentifierMemory`` comparison to ``dict[str, Any]``.
These are intentionally not considered equivalent.
"""
dictionary = {'Foo': 'bar', 'Baz': 'Luhrmann'}
memory = memories.SopelIdentifierMemory(dictionary)

assert dictionary != memory
assert memory != dictionary # cover our bases vis-a-vis operand precedence

0 comments on commit 7c48831

Please sign in to comment.