Skip to content

Commit 7c48831

Browse files
committed
tools.memories, test: codify SopelIdentifierMemory == dict behavior
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.
1 parent e803541 commit 7c48831

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

sopel/tools/memories.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,11 @@ def __ior__(self, other):
275275
return NotImplemented
276276
self.update(other)
277277
return self
278+
279+
def __eq__(self, other):
280+
if not isinstance(other, dict):
281+
return NotImplemented
282+
return super().__eq__(other)
283+
284+
def __ne__(self, other):
285+
return not self.__eq__(other)

test/tools/test_tools_memories.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,3 +441,37 @@ def test_sopel_identifier_memory_ior_op_dict():
441441
assert memory['fROmMemorY'] is True
442442
assert memory['fROmDicT'] is True
443443
assert 'FromTuple' not in memory
444+
445+
446+
def test_sopel_identifier_memory_eq():
447+
"""Test equality checks between two `SopelIdentifierMemory` instances."""
448+
memory = memories.SopelIdentifierMemory({'Foo': 'bar', 'Baz': 'Luhrmann'})
449+
other_memory = memories.SopelIdentifierMemory((('Foo', 'bar'), ('Baz', 'Luhrmann')))
450+
451+
assert memory == other_memory
452+
assert other_memory == memory # cover our bases vis-a-vis operand precedence
453+
454+
455+
def test_sopel_identifier_memory_eq_dict_id():
456+
"""Test ``SopelIdentifierMemory`` comparison to ``dict[Identifier, Any]``.
457+
458+
These can be equivalent, just like two ``dict`` objects with identical
459+
``Identifier`` keys can be.
460+
"""
461+
memory = memories.SopelIdentifierMemory({'Foo': 'bar', 'Baz': 'Luhrmann'})
462+
dictionary = dict(memory)
463+
464+
assert dictionary == memory
465+
assert memory == dictionary # cover our bases vis-a-vis operand precedence
466+
467+
468+
def test_sopel_identifier_memory_eq_dict_str():
469+
"""Test ``SopelIdentifierMemory`` comparison to ``dict[str, Any]``.
470+
471+
These are intentionally not considered equivalent.
472+
"""
473+
dictionary = {'Foo': 'bar', 'Baz': 'Luhrmann'}
474+
memory = memories.SopelIdentifierMemory(dictionary)
475+
476+
assert dictionary != memory
477+
assert memory != dictionary # cover our bases vis-a-vis operand precedence

0 commit comments

Comments
 (0)