Skip to content

Commit 9b4ad4e

Browse files
rroohhhwhitequark
authored andcommitted
lib.data.{Field, Layout, Const}: add __hash__
1 parent 5689b6b commit 9b4ad4e

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

amaranth/lib/data.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ def width(self):
6565
"""
6666
return Shape.cast(self.shape).width
6767

68+
def __hash__(self):
69+
return hash((self.shape, self.offset))
70+
6871
def __eq__(self, other):
6972
"""Compare fields.
7073
@@ -166,6 +169,11 @@ def as_shape(self):
166169
"""
167170
return unsigned(self.size)
168171

172+
def __hash__(self):
173+
if not hasattr(self, "_Layout__hash"):
174+
setattr(self, "_Layout__hash", hash((self.size, frozenset(iter(self)))))
175+
return self.__hash
176+
169177
def __eq__(self, other):
170178
"""Compare layouts.
171179
@@ -1123,6 +1131,9 @@ def __len__(self):
11231131
f"`len()` can only be used on constants of array layout, not {self.__layout!r}")
11241132
return self.__layout.length
11251133

1134+
def __hash__(self):
1135+
return hash((self.__target, self.__layout))
1136+
11261137
def __eq__(self, other):
11271138
if isinstance(other, View) and self.__layout == other._View__layout:
11281139
return self.as_value() == other._View__target

docs/changes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Standard library changes
6464

6565
* Added: :py:`payload_init=` argument in :class:`amaranth.lib.stream.Signature`.
6666
* Added: :meth:`enum.EnumView.matches`. (`RFC 71`_)
67+
* Added: :class:`data.Field`, :class:`data.Layout` and :class:`data.Const` are hashable.
6768
* Changed: (deprecated in 0.5.1) providing :meth:`io.PortLike.__add__` is now mandatory. (`RFC 69`_)
6869
* Removed: (deprecated in 0.5.0) :mod:`amaranth.lib.coding`. (`RFC 63`_)
6970

tests/test_lib_data.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ def test_immutable(self):
7474
with self.assertRaises(AttributeError):
7575
data.Field(1, 0).offset = 1
7676

77+
def test_hash(self):
78+
hash(data.Field(unsigned(2), 1))
79+
7780

7881
class StructLayoutTestCase(FHDLTestCase):
7982
def test_construct(self):
@@ -520,6 +523,9 @@ def test_signal_init(self):
520523
self.assertEqual(Signal(sl).as_value().init, 0)
521524
self.assertEqual(Signal(sl, init={"a": 0b1, "b": 0b10}).as_value().init, 5)
522525

526+
def test_hash(self):
527+
hash(data.StructLayout({}))
528+
523529

524530
class ViewTestCase(FHDLTestCase):
525531
def test_construct(self):
@@ -1167,6 +1173,9 @@ def test_repr(self):
11671173
s1 = data.Const(data.StructLayout({"a": unsigned(2)}), 2)
11681174
self.assertRepr(s1, "Const(StructLayout({'a': unsigned(2)}), 2)")
11691175

1176+
def test_hash(self):
1177+
hash(data.Const(data.StructLayout({"a": unsigned(2)}), 2))
1178+
11701179

11711180
class StructTestCase(FHDLTestCase):
11721181
def test_construct(self):

0 commit comments

Comments
 (0)