* [libgpiod][PATCH] bindings: python: parse non-tuple Iterable keys
@ 2025-09-02 12:39 Vincent Fazio
0 siblings, 0 replies; only message in thread
From: Vincent Fazio @ 2025-09-02 12:39 UTC (permalink / raw)
To: linux-gpio; +Cc: Vincent Fazio, Vincent Fazio
When `chip.request_lines` was modified to allow `Iterable`s instead of
only `tuple`s, the code that checked for duplicate line entries in the
`config` argument was not updated to account for the expanded types.
If the `config` argument had a key that was not a `tuple`, `str`, or
`int`, a `TypeError` would be raised when resolving the line offset.
Refactor the code the resolves IDs to offsets into a separate function
to make the logic a bit clearer and to account for the widened types.
Fixes: 8f62e6c45355 ("bindings: python: loosen type requirements in public API")
Closes: https://github.com/brgl/libgpiod/issues/148
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
---
bindings/python/gpiod/chip.py | 23 ++++++++++++++-------
bindings/python/tests/tests_line_request.py | 4 ++++
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/bindings/python/gpiod/chip.py b/bindings/python/gpiod/chip.py
index 5641343..cccfb03 100644
--- a/bindings/python/gpiod/chip.py
+++ b/bindings/python/gpiod/chip.py
@@ -236,6 +236,20 @@ class Chip:
self._check_closed()
return cast(_ext.Chip, self._chip).read_info_event()
+ def _resolve_config_keys_to_offsets(
+ self,
+ config_keys: Iterable[Union[Iterable[Union[int, str]], int, str]],
+ ) -> list[int]:
+ offsets: list[int] = list()
+ for key in config_keys:
+ # perform strict int/str check since str is also Iterable
+ if isinstance(key, (int, str)):
+ offsets.append(self.line_offset_from_id(key))
+ else: # key is an iterable with multiple IDs to resolve
+ for item in key:
+ offsets.append(self.line_offset_from_id(item))
+ return offsets
+
def request_lines(
self,
config: dict[
@@ -271,14 +285,7 @@ class Chip:
# Sanitize lines - don't allow offset repetitions or offset-name conflicts.
for offset, count in Counter(
- [
- self.line_offset_from_id(line)
- for line in (
- lambda t: [
- j for i in (t) for j in (i if isinstance(i, tuple) else (i,))
- ]
- )(tuple(config.keys()))
- ]
+ self._resolve_config_keys_to_offsets(config_keys=config.keys())
).items():
if count != 1:
raise ValueError(
diff --git a/bindings/python/tests/tests_line_request.py b/bindings/python/tests/tests_line_request.py
index afee644..217c299 100644
--- a/bindings/python/tests/tests_line_request.py
+++ b/bindings/python/tests/tests_line_request.py
@@ -101,6 +101,10 @@ class ChipLineRequestWorks(TestCase):
with self.chip.request_lines(config={(4): None}) as req:
self.assertEqual(req.offsets, [4])
+ def test_request_single_offset_as_frozenset(self) -> None:
+ with self.chip.request_lines(config={frozenset([4]): None}) as req:
+ self.assertEqual(req.offsets, [4])
+
def test_request_by_name(self) -> None:
with self.chip.request_lines(config={(1, 2, "foo", "bar"): None}) as req:
self.assertEqual(req.offsets, [1, 2, 5, 7])
--
2.43.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2025-09-02 12:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-02 12:39 [libgpiod][PATCH] bindings: python: parse non-tuple Iterable keys Vincent Fazio
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).