On Fri, May 19, 2023 at 7:47 PM Nicolas Frattaroli <frattaroli.nicolas@xxxxxxxxx> wrote: > > So far, libgpiod's Python bindings had no way to state that a > user wishes to wait for events indefinitely, as a timeout of > None would intentionally be converted to 0 seconds, i.e. return > from the select call in poll_fd immediately. > > The usual Python convention and even the select convention is > to block indefinitely on a timeout=None. However, changing the > poll_fd function to do this now would change an (intentional) > API design choice by libgpiod 2.0 that API users presumably > rely on. > > By allowing float("inf") (or in fact math.inf, or your favourite > other way to get an infinite float) to mean waiting infinitely > solves this by extending the API rather than changing it. > > On gpiod Python bindings without this change, passing inf results > in an OverflowError being raised in select. API users who wish to > support older versions of the bindings can catch this exception and > act on it. > > Signed-off-by: Nicolas Frattaroli <frattaroli.nicolas@xxxxxxxxx> > --- > bindings/python/gpiod/chip.py | 3 ++- > bindings/python/gpiod/internal.py | 4 ++++ > bindings/python/gpiod/line_request.py | 3 ++- > 3 files changed, 8 insertions(+), 2 deletions(-) > > diff --git a/bindings/python/gpiod/chip.py b/bindings/python/gpiod/chip.py > index 97ff340..95c5757 100644 > --- a/bindings/python/gpiod/chip.py > +++ b/bindings/python/gpiod/chip.py > @@ -195,7 +195,8 @@ class Chip: > Args: > timeout: > Wait time limit represented as either a datetime.timedelta object > - or the number of seconds stored in a float. > + or the number of seconds stored in a float. A timeout of None > + returns immediately, use float("inf") to wait indefinitely. > > Returns: > True if an info event is ready to be read from the chip, False if the > diff --git a/bindings/python/gpiod/internal.py b/bindings/python/gpiod/internal.py > index 37e8b62..141cfe9 100644 > --- a/bindings/python/gpiod/internal.py > +++ b/bindings/python/gpiod/internal.py > @@ -2,6 +2,7 @@ > # SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@xxxxxxxx> > > from datetime import timedelta > +from math import inf > from select import select > from typing import Optional, Union > > @@ -15,5 +16,8 @@ def poll_fd(fd: int, timeout: Optional[Union[timedelta, float]] = None) -> bool: > else: > sec = timeout > > + if sec == inf: > + sec = None > + > readable, _, _ = select([fd], [], [], sec) > return True if fd in readable else False > diff --git a/bindings/python/gpiod/line_request.py b/bindings/python/gpiod/line_request.py > index a0f97b7..ae21835 100644 > --- a/bindings/python/gpiod/line_request.py > +++ b/bindings/python/gpiod/line_request.py > @@ -178,7 +178,8 @@ class LineRequest: > Args: > timeout: > Wait time limit expressed as either a datetime.timedelta object > - or the number of seconds stored in a float. > + or the number of seconds stored in a float. None returns > + immediately. Use float("inf") to wait indefinitely. > > Returns: > True if events are ready to be read. False on timeout. > -- > 2.40.1 > I like this approach too. In fact - it may be even clearer and more intuitive than converting None to infinite timeout. Any objections against using negative numbers for the same purpose as well? Bart