Skip to content

Commit e546b8e

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 86ac703 commit e546b8e

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
@@ -276,3 +276,11 @@ def __ior__(self, other):
276276
return NotImplemented
277277
self.update(other)
278278
return self
279+
280+
def __eq__(self, other):
281+
if not isinstance(other, dict):
282+
return NotImplemented
283+
return super().__eq__(other)
284+
285+
def __ne__(self, other):
286+
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
@@ -440,3 +440,37 @@ def test_sopel_identifier_memory_ior_op_dict():
440440
assert memory['fROmMemorY'] is True
441441
assert memory['fROmDicT'] is True
442442
assert 'FromTuple' not in memory
443+
444+
445+
def test_sopel_identifier_memory_eq():
446+
"""Test equality checks between two `SopelIdentifierMemory` instances."""
447+
memory = memories.SopelIdentifierMemory({'Foo': 'bar', 'Baz': 'Luhrmann'})
448+
other_memory = memories.SopelIdentifierMemory((('Foo', 'bar'), ('Baz', 'Luhrmann')))
449+
450+
assert memory == other_memory
451+
assert other_memory == memory # cover our bases vis-a-vis operand precedence
452+
453+
454+
def test_sopel_identifier_memory_eq_dict_id():
455+
"""Test ``SopelIdentifierMemory`` comparison to ``dict[Identifier, Any]``.
456+
457+
These can be equivalent, just like two ``dict`` objects with identical
458+
``Identifier`` keys can be.
459+
"""
460+
memory = memories.SopelIdentifierMemory({'Foo': 'bar', 'Baz': 'Luhrmann'})
461+
dictionary = dict(memory)
462+
463+
assert dictionary == memory
464+
assert memory == dictionary # cover our bases vis-a-vis operand precedence
465+
466+
467+
def test_sopel_identifier_memory_eq_dict_str():
468+
"""Test ``SopelIdentifierMemory`` comparison to ``dict[str, Any]``.
469+
470+
These are intentionally not considered equivalent.
471+
"""
472+
dictionary = {'Foo': 'bar', 'Baz': 'Luhrmann'}
473+
memory = memories.SopelIdentifierMemory(dictionary)
474+
475+
assert dictionary != memory
476+
assert memory != dictionary # cover our bases vis-a-vis operand precedence

0 commit comments

Comments
 (0)