Skip to content

Commit 238f81f

Browse files
committed
refactor(bits_per_word)!: validate property in Python class
BREAKING CHANGE: bits_per_word raises a ValueError instead of a TypeError when its value is not between 8 and 32.
1 parent 57f9c4a commit 238f81f

File tree

2 files changed

+24
-24
lines changed

2 files changed

+24
-24
lines changed

spidev/_cspi.c

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,33 +1182,13 @@ SpiDev_get_bits_per_word(SpiDevObject *self, void *closure)
11821182
static int
11831183
SpiDev_set_bits_per_word(SpiDevObject *self, PyObject *val, void *closure)
11841184
{
1185-
uint8_t bits;
1186-
11871185
if (val == NULL) {
11881186
PyErr_SetString(PyExc_TypeError,
11891187
"Cannot delete attribute");
11901188
return -1;
11911189
}
1192-
#if PY_MAJOR_VERSION < 3
1193-
if (PyInt_Check(val)) {
1194-
bits = PyInt_AS_LONG(val);
1195-
} else
1196-
#endif
1197-
{
1198-
if (PyLong_Check(val)) {
1199-
bits = PyLong_AS_LONG(val);
1200-
} else {
1201-
PyErr_SetString(PyExc_TypeError,
1202-
"The bits_per_word attribute must be an integer");
1203-
return -1;
1204-
}
1205-
}
12061190

1207-
if (bits < 8 || bits > 32) {
1208-
PyErr_SetString(PyExc_TypeError,
1209-
"invalid bits_per_word (8 to 32)");
1210-
return -1;
1211-
}
1191+
uint8_t bits = PyLong_AS_LONG(val);
12121192

12131193
if (self->bits_per_word != bits) {
12141194
if (ioctl(self->fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {

spidev/_spi.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ def __init__(
1717
bus: int | None,
1818
client: int | None,
1919
device: int | None = None,
20-
mode: int | None = None,
2120
path: StrPath | None = None,
21+
mode: int | None = None,
22+
bits_per_word: int | None = None,
2223
):
2324
super().__init__(bus, client)
2425
self.bus = bus
2526
self.client = client
2627
self.device = device
2728
if mode is not None:
2829
self.mode = mode
30+
if bits_per_word is not None:
31+
self.bits_per_word = bits_per_word
2932

3033
if path and (bus or device):
3134
raise ValueError(
@@ -43,17 +46,34 @@ def mode(self) -> int:
4346
return super().mode
4447

4548
@mode.setter
46-
def mode(self, value: int) -> None:
49+
def mode(self, value: int, /) -> None:
4750
try:
4851
v = int(value)
4952
except (TypeError, ValueError):
50-
raise TypeError(f"mode must be an integer, but is {value}")
53+
raise TypeError(f"mode must be an integer, but is {type(value)}")
5154

5255
if not 0 <= v <= 3:
5356
raise ValueError(f"mode must be between 0 and 3, but is {v}")
5457

5558
super().__setattr__("mode", v)
5659

60+
@property
61+
def bits_per_word(self) -> int:
62+
"""Bits per word used in the xfer methods."""
63+
return super().bits_per_word
64+
65+
@bits_per_word.setter
66+
def bits_per_word(self, value: int, /) -> None:
67+
try:
68+
v = int(value)
69+
except (TypeError, ValueError):
70+
raise TypeError(f"bits_per_word must be an integer, but is {type(value)}")
71+
72+
if not (8 <= value <= 32):
73+
raise ValueError(f"bits_per_word must be between 8 and 32, but is {v}")
74+
75+
super().__setattr__("bits_per_word", v)
76+
5777
def closed(self) -> bool:
5878
"""True if the connection is closed."""
5979
try:

0 commit comments

Comments
 (0)