Skip to content

Commit be69843

Browse files
Copilotnstarman
andauthored
Fix hash/equality contract and add mapping equality tests
Agent-Logs-Url: https://github.com/GalacticDynamics/xmmutablemap/sessions/f39253f1-d8ea-46eb-8a8e-f004866a473d Co-authored-by: nstarman <8949649+nstarman@users.noreply.github.com>
1 parent 0c5e0f8 commit be69843

2 files changed

Lines changed: 15 additions & 8 deletions

File tree

src/xmmutablemap/_core.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,10 @@ def __eq__(self, other: object) -> bool:
9393
"""Return whether two mappings contain the same items."""
9494
if isinstance(other, ImmutableMap):
9595
return self._data == other._data
96-
if isinstance(other, dict):
97-
return self._data = other
9896
if isinstance(other, Mapping):
9997
return self._data == dict(other.items())
10098
return NotImplemented
10199

102-
def __hash__(self) -> int:
103-
"""Return an order-insensitive hash based on the mapping contents."""
104-
return hash(frozenset(self._data.items()))
105-
106100
# ===========================================
107101
# Mapping Protocol
108102

@@ -229,7 +223,7 @@ def __hash__(self) -> int:
229223
True
230224
231225
"""
232-
return hash(tuple(self._data.items()))
226+
return hash(frozenset(self._data.items()))
233227

234228
def __repr__(self) -> str:
235229
"""Return the representation.

tests/test_immutablemap.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,26 @@ def test_len(self, d: ImmutableMap[str, Any]) -> None:
5757

5858
def test_hash(self, d: ImmutableMap[str, Any]) -> None:
5959
"""Test `__hash__`."""
60-
assert hash(d) == hash(tuple(d.items()))
60+
assert hash(d) == hash(frozenset(d.items()))
6161

6262
# Not hashable if values aren't hashable.
6363
d = ImmutableMap(a=1, b={"c"})
6464
with pytest.raises(TypeError, match="unhashable type: 'set'"):
6565
hash(d)
6666

67+
def test_eq_with_other_mappings(self, d: ImmutableMap[str, Any]) -> None:
68+
"""Test mapping interoperability for `__eq__`."""
69+
assert d == {"a": 1, "b": 2}
70+
assert d == OrderedDict([("a", 1), ("b", 2)])
71+
assert d == MappingProxyType({"a": 1, "b": 2})
72+
73+
def test_eq_and_hash_ignore_insertion_order(self) -> None:
74+
"""Test equality/hash contract for same items in different orders."""
75+
d1 = ImmutableMap(a=1, b=2)
76+
d2 = ImmutableMap(b=2, a=1)
77+
assert d1 == d2
78+
assert hash(d1) == hash(d2)
79+
6780
def test_keys(self, d: ImmutableMap[str, Any]) -> None:
6881
"""Test `keys`."""
6982
assert list(d.keys()) == ["a", "b"]

0 commit comments

Comments
 (0)