Skip to content

Commit 58d7a69

Browse files
committed
Remove .check_parameters() method from signatures.
Since RFC 38, the signature of a component can only be assigned within its constructor. It is no longer useful to decouple the validation of signature parameters from its constructor.
1 parent 2dfd84c commit 58d7a69

File tree

6 files changed

+51
-177
lines changed

6 files changed

+51
-177
lines changed

amaranth_soc/csr/bus.py

Lines changed: 15 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,17 @@ class Signature(wiring.Signature):
4949
w_stb : Signal()
5050
Write strobe. Registers should update their value or perform the write side effect when
5151
this strobe is asserted.
52-
53-
Raises
54-
------
55-
See :meth:`Element.Signature.check_parameters`.
5652
"""
5753
def __init__(self, width, access):
58-
self.check_parameters(width, access)
54+
if not isinstance(width, int) or width < 0:
55+
raise TypeError(f"Width must be a non-negative integer, not {width!r}")
56+
# TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
57+
# instead of cls.__qualname__.
58+
# Element.Access(access)
59+
try:
60+
Element.Access(access)
61+
except ValueError as e:
62+
raise ValueError(f"{access!r} is not a valid Element.Access") from e
5963

6064
self._width = width
6165
self._access = Element.Access(access)
@@ -81,27 +85,6 @@ def width(self):
8185
def access(self):
8286
return self._access
8387

84-
@classmethod
85-
def check_parameters(cls, width, access):
86-
"""Validate signature parameters.
87-
88-
Raises
89-
------
90-
:exc:`TypeError`
91-
If ``width`` is not an integer greater than or equal to 0.
92-
:exc:`ValueError`
93-
If ``access`` is not a member of :class:`Element.Access`.
94-
"""
95-
if not isinstance(width, int) or width < 0:
96-
raise TypeError(f"Width must be a non-negative integer, not {width!r}")
97-
# TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
98-
# instead of cls.__qualname__.
99-
# Element.Access(access)
100-
try:
101-
Element.Access(access)
102-
except ValueError as e:
103-
raise ValueError(f"{access!r} is not a valid Element.Access") from e
104-
10588
def create(self, *, path=None, src_loc_at=0):
10689
"""Create a compatible interface.
10790
@@ -139,10 +122,6 @@ def __repr__(self):
139122
Register access mode.
140123
path : iter(:class:`str`)
141124
Path to this CSR interface. Optional. See :class:`wiring.PureInterface`.
142-
143-
Raises
144-
------
145-
See :meth:`Element.Signature.check_parameters`
146125
"""
147126
def __init__(self, width, access, *, path=None, src_loc_at=0):
148127
super().__init__(Element.Signature(width=width, access=access), path=path, src_loc_at=1 + src_loc_at)
@@ -188,13 +167,12 @@ class Signature(wiring.Signature):
188167
to the register and causes write side effects to be performed (if any). If ``addr`` points
189168
to any chunk of a register, latches ``w_data`` to the captured value. Otherwise, does
190169
nothing.
191-
192-
Raises
193-
------
194-
See :meth:`Signature.check_parameters`.
195170
"""
196171
def __init__(self, *, addr_width, data_width):
197-
self.check_parameters(addr_width=addr_width, data_width=data_width)
172+
if not isinstance(addr_width, int) or addr_width <= 0:
173+
raise TypeError(f"Address width must be a positive integer, not {addr_width!r}")
174+
if not isinstance(data_width, int) or data_width <= 0:
175+
raise TypeError(f"Data width must be a positive integer, not {data_width!r}")
198176

199177
self._addr_width = addr_width
200178
self._data_width = data_width
@@ -216,22 +194,6 @@ def addr_width(self):
216194
def data_width(self):
217195
return self._data_width
218196

219-
@classmethod
220-
def check_parameters(cls, *, addr_width, data_width):
221-
"""Validate signature parameters.
222-
223-
Raises
224-
------
225-
:exc:`TypeError`
226-
If ``addr_width`` is not an integer greater than 0.
227-
:exc:`TypeError`
228-
If ``data_width`` is not an integer greater than 0.
229-
"""
230-
if not isinstance(addr_width, int) or addr_width <= 0:
231-
raise TypeError(f"Address width must be a positive integer, not {addr_width!r}")
232-
if not isinstance(data_width, int) or data_width <= 0:
233-
raise TypeError(f"Data width must be a positive integer, not {data_width!r}")
234-
235197
def create(self, *, path=None, src_loc_at=0):
236198
"""Create a compatible interface.
237199
@@ -288,14 +250,10 @@ class Interface(wiring.PureInterface):
288250
----------
289251
memory_map: :class:`MemoryMap`
290252
Memory map of the bus. Optional.
291-
292-
Raises
293-
------
294-
See :meth:`Signature.check_parameters`.
295253
"""
296254
def __init__(self, *, addr_width, data_width, path=None, src_loc_at=0):
297-
sig = Signature(addr_width=addr_width, data_width=data_width)
298-
super().__init__(sig, path=path, src_loc_at=1 + src_loc_at)
255+
super().__init__(Signature(addr_width=addr_width, data_width=data_width),
256+
path=path, src_loc_at=1 + src_loc_at)
299257
self._memory_map = None
300258

301259
@property

amaranth_soc/csr/reg.py

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,20 @@ class Signature(wiring.Signature):
5151
w_stb : Signal()
5252
Write strobe. Fields should update their value or perform the write side effect when
5353
this strobe is asserted.
54-
55-
Raises
56-
------
57-
See :meth:`FieldPort.Signature.check_parameters`.
5854
"""
5955
def __init__(self, shape, access):
60-
self.check_parameters(shape, access)
56+
try:
57+
Shape.cast(shape)
58+
except TypeError as e:
59+
raise TypeError(f"Field shape must be a shape-castable object, not {shape!r}") from e
60+
# TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
61+
# instead of cls.__qualname__.
62+
# FieldPort.Access(access)
63+
try:
64+
FieldPort.Access(access)
65+
except ValueError as e:
66+
raise ValueError(f"{access!r} is not a valid FieldPort.Access") from e
67+
6168
self._shape = Shape.cast(shape)
6269
self._access = FieldPort.Access(access)
6370

@@ -76,29 +83,6 @@ def shape(self):
7683
def access(self):
7784
return self._access
7885

79-
@classmethod
80-
def check_parameters(cls, shape, access):
81-
"""Validate signature parameters.
82-
83-
Raises
84-
------
85-
:exc:`TypeError`
86-
If ``shape`` is not a shape-castable object.
87-
:exc:`ValueError`
88-
If ``access`` is not a member of :class:`FieldPort.Access`.
89-
"""
90-
try:
91-
Shape.cast(shape)
92-
except TypeError as e:
93-
raise TypeError(f"Field shape must be a shape-castable object, not {shape!r}") from e
94-
# TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
95-
# instead of cls.__qualname__.
96-
# FieldPort.Access(access)
97-
try:
98-
FieldPort.Access(access)
99-
except ValueError as e:
100-
raise ValueError(f"{access!r} is not a valid FieldPort.Access") from e
101-
10286
def create(self, *, path=None, src_loc_at=0):
10387
"""Create a compatible interface.
10488

amaranth_soc/event.py

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ class Signature(wiring.Signature):
2727
Input line. Sampled in order to detect an event.
2828
trg : Signal()
2929
Event trigger. Asserted when an event occurs, according to the trigger mode.
30-
31-
Raises
32-
------
33-
See :meth:`Source.Signature.check_parameters`.
3430
"""
3531
def __init__(self, *, trigger="level"):
36-
self.check_parameters(trigger=trigger)
32+
# TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
33+
# instead of cls.__qualname__.
34+
# Source.Trigger(trigger)
35+
try:
36+
Source.Trigger(trigger)
37+
except ValueError as e:
38+
raise ValueError(f"{trigger!r} is not a valid Source.Trigger") from e
39+
3740
super().__init__({
3841
"i": Out(1),
3942
"trg": In(1),
@@ -44,22 +47,6 @@ def __init__(self, *, trigger="level"):
4447
def trigger(self):
4548
return self._trigger
4649

47-
def check_parameters(cls, *, trigger):
48-
"""Validate signature parameters.
49-
50-
Raises
51-
------
52-
:exc:`ValueError`
53-
If ``trigger`` is not a member of :class:`Source.Trigger`.
54-
"""
55-
# TODO(py3.9): Remove this. Python 3.8 and below use cls.__name__ in the error message
56-
# instead of cls.__qualname__.
57-
# Source.Trigger(trigger)
58-
try:
59-
Source.Trigger(trigger)
60-
except ValueError as e:
61-
raise ValueError(f"{trigger!r} is not a valid Source.Trigger") from e
62-
6350
def create(self, *, path=None, src_loc_at=0):
6451
"""Create a compatible interface.
6552
@@ -94,10 +81,6 @@ def __repr__(self):
9481
----------
9582
event_map : :class:`EventMap`
9683
A collection of event sources.
97-
98-
Raises
99-
------
100-
See :meth:`Source.Signature.check_parameters`.
10184
"""
10285
def __init__(self, *, trigger="level", path=None, src_loc_at=0):
10386
super().__init__(Source.Signature(trigger=trigger), path=path, src_loc_at=1 + src_loc_at)

amaranth_soc/wishbone/bus.py

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,10 @@ class Signature(wiring.Signature):
4646
----------
4747
addr_width : int
4848
Width of the address signal.
49-
data_width : int
49+
data_width : ``8``, ``16``, ``32`` or ``64``
5050
Width of the data signals ("port size" in Wishbone terminology).
51-
One of 8, 16, 32, 64.
52-
granularity : int
51+
granularity : ``8``, ``16``, ``32``, ``64`` or ``None``
5352
Granularity of select signals ("port granularity" in Wishbone terminology).
54-
One of 8, 16, 32, 64.
5553
Optional. If ``None`` (by default), the granularity is equal to ``data_width``.
5654
features : iter(:class:`Feature`)
5755
Selects additional signals that will be a part of this interface.
@@ -94,16 +92,22 @@ class Signature(wiring.Signature):
9492
Optional. Corresponds to Wishbone signal ``CTI_O`` (initiator) or ``CTI_I`` (target).
9593
bte : Signal()
9694
Optional. Corresponds to Wishbone signal ``BTE_O`` (initiator) or ``BTE_I`` (target).
97-
98-
Raises
99-
------
100-
See :meth:`Signature.check_parameters`.
10195
"""
10296
def __init__(self, *, addr_width, data_width, granularity=None, features=frozenset()):
10397
if granularity is None:
104-
granularity = data_width
105-
self.check_parameters(addr_width=addr_width, data_width=data_width, granularity=granularity,
106-
features=features)
98+
granularity = data_width
99+
100+
if not isinstance(addr_width, int) or addr_width < 0:
101+
raise TypeError(f"Address width must be a non-negative integer, not {addr_width!r}")
102+
if data_width not in (8, 16, 32, 64):
103+
raise ValueError(f"Data width must be one of 8, 16, 32, 64, not {data_width!r}")
104+
if granularity not in (8, 16, 32, 64):
105+
raise ValueError(f"Granularity must be one of 8, 16, 32, 64, not {granularity!r}")
106+
if granularity > data_width:
107+
raise ValueError(f"Granularity {granularity} may not be greater than data width "
108+
f"{data_width}")
109+
for feature in features:
110+
Feature(feature) # raises ValueError if feature is invalid
107111

108112
self._addr_width = addr_width
109113
self._data_width = data_width
@@ -150,35 +154,6 @@ def granularity(self):
150154
def features(self):
151155
return self._features
152156

153-
@classmethod
154-
def check_parameters(cls, *, addr_width, data_width, granularity, features):
155-
"""Validate signature parameters.
156-
157-
Raises
158-
------
159-
:exc:`TypeError`
160-
If ``addr_width`` is not an integer greater than or equal to 0.
161-
:exc:`ValueError`
162-
If ``data_width`` is not 8, 16, 32 or 64.
163-
:exc:`ValueError`
164-
If ``granularity`` is not 8, 16, 32 or 64.
165-
:exc:`ValueError`
166-
If ``granularity`` is greater than ``data_width``.
167-
:exc:`ValueError`
168-
If ``features`` contains other values than :class:`Feature` members.
169-
"""
170-
if not isinstance(addr_width, int) or addr_width < 0:
171-
raise TypeError(f"Address width must be a non-negative integer, not {addr_width!r}")
172-
if data_width not in (8, 16, 32, 64):
173-
raise ValueError(f"Data width must be one of 8, 16, 32, 64, not {data_width!r}")
174-
if granularity not in (8, 16, 32, 64):
175-
raise ValueError(f"Granularity must be one of 8, 16, 32, 64, not {granularity!r}")
176-
if granularity > data_width:
177-
raise ValueError(f"Granularity {granularity} may not be greater than data width "
178-
f"{data_width}")
179-
for feature in features:
180-
Feature(feature) # raises ValueError if feature is invalid
181-
182157
def create(self, *, path=None, src_loc_at=0):
183158
"""Create a compatible interface.
184159
@@ -232,10 +207,6 @@ class Interface(wiring.PureInterface):
232207
----------
233208
memory_map: :class:`MemoryMap`
234209
Memory map of the bus. Optional.
235-
236-
Raises
237-
------
238-
See :meth:`Signature.check_parameters`.
239210
"""
240211
def __init__(self, *, addr_width, data_width, granularity=None, features=frozenset(),
241212
path=None, src_loc_at=0):

tests/test_csr_bus.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,11 @@ def test_wrong_addr_width(self):
131131
with self.assertRaisesRegex(TypeError,
132132
r"Address width must be a positive integer, not -1"):
133133
csr.Signature(addr_width=-1, data_width=8)
134-
with self.assertRaisesRegex(TypeError,
135-
r"Address width must be a positive integer, not -1"):
136-
csr.Signature.check_parameters(addr_width=-1, data_width=8)
137134

138135
def test_wrong_data_width(self):
139136
with self.assertRaisesRegex(TypeError,
140137
r"Data width must be a positive integer, not -1"):
141-
csr.Signature.check_parameters(addr_width=16, data_width=-1)
138+
csr.Signature(addr_width=16, data_width=-1)
142139

143140

144141
class InterfaceTestCase(unittest.TestCase):

tests/test_wishbone_bus.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -106,44 +106,25 @@ def test_wrong_addr_width(self):
106106
with self.assertRaisesRegex(TypeError,
107107
r"Address width must be a non-negative integer, not -1"):
108108
wishbone.Signature(addr_width=-1, data_width=8)
109-
with self.assertRaisesRegex(TypeError,
110-
r"Address width must be a non-negative integer, not -1"):
111-
wishbone.Signature.check_parameters(addr_width=-1, data_width=8, granularity=8,
112-
features=())
113109

114110
def test_wrong_data_width(self):
115111
with self.assertRaisesRegex(ValueError,
116112
r"Data width must be one of 8, 16, 32, 64, not 7"):
117113
wishbone.Signature(addr_width=0, data_width=7)
118-
with self.assertRaisesRegex(ValueError,
119-
r"Data width must be one of 8, 16, 32, 64, not 7"):
120-
wishbone.Signature.check_parameters(addr_width=0, data_width=7, granularity=7,
121-
features=())
122114

123115
def test_wrong_granularity(self):
124116
with self.assertRaisesRegex(ValueError,
125117
r"Granularity must be one of 8, 16, 32, 64, not 7"):
126118
wishbone.Signature(addr_width=0, data_width=32, granularity=7)
127-
with self.assertRaisesRegex(ValueError,
128-
r"Granularity must be one of 8, 16, 32, 64, not 7"):
129-
wishbone.Signature.check_parameters(addr_width=0, data_width=32, granularity=7,
130-
features=())
131119

132120
def test_wrong_granularity_wide(self):
133121
with self.assertRaisesRegex(ValueError,
134122
r"Granularity 32 may not be greater than data width 8"):
135123
wishbone.Signature(addr_width=0, data_width=8, granularity=32)
136-
with self.assertRaisesRegex(ValueError,
137-
r"Granularity 32 may not be greater than data width 8"):
138-
wishbone.Signature.check_parameters(addr_width=0, data_width=8, granularity=32,
139-
features=())
140124

141125
def test_wrong_features(self):
142126
with self.assertRaisesRegex(ValueError, r"'foo' is not a valid Feature"):
143127
wishbone.Signature(addr_width=0, data_width=8, features={"foo"})
144-
with self.assertRaisesRegex(ValueError, r"'foo' is not a valid Feature"):
145-
wishbone.Signature.check_parameters(addr_width=0, data_width=8, granularity=8,
146-
features={"foo"})
147128

148129

149130
class InterfaceTestCase(unittest.TestCase):

0 commit comments

Comments
 (0)