mbox series

[libgpiod,v2,v3,0/4] bindings: implement python bindings for libgpiod v2

Message ID 20221007145521.329614-1-brgl@bgdev.pl
Headers show
Series bindings: implement python bindings for libgpiod v2 | expand

Message

Bartosz Golaszewski Oct. 7, 2022, 2:55 p.m. UTC
This is the third iteration of python bindings for libgpiod but it really has
very little in common with the previous version.

This time the code has been split into high-level python and low-level
C layers with the latter only doing the bare minimum.

The data model is mostly based on the C++ one with the main difference
being utilizing dynamic typing and keyword arguments in place of the
builder pattern. That allows us to reduce the number of methods and
objects.

Because python doesn't have RAII, unlike C++, we provide a module-level
request_lines() helper as gpiod.Chip(path).request_lines(...) one-liner
could lead to the chip left dangling even after the last reference is
dropped.

Because python forces us to dynamically allocate objects all the time even
for fundamental types (which are also immutable) there's no point in trying
to replicate the edge-event buffer. Instead LineRequest.read_edge_event()
just returns a list of events.

Bartosz Golaszewski (4):
  bindings: python: remove old version
  bindings: python: add examples
  bindings: python: add tests
  bindings: python: implement python bindings for libgpiod v2

 bindings/python/.gitignore                   |    8 +
 bindings/python/Makefile.am                  |   26 +-
 bindings/python/examples/Makefile.am         |   16 +-
 bindings/python/examples/gpiodetect.py       |   15 +-
 bindings/python/examples/gpiofind.py         |   14 +-
 bindings/python/examples/gpioget.py          |   34 +-
 bindings/python/examples/gpioinfo.py         |   41 +-
 bindings/python/examples/gpiomon.py          |   52 +-
 bindings/python/examples/gpioset.py          |   46 +-
 bindings/python/gpiod/Makefile.am            |   17 +
 bindings/python/gpiod/__init__.py            |   53 +
 bindings/python/gpiod/chip.py                |  308 ++
 bindings/python/gpiod/chip_info.py           |   21 +
 bindings/python/gpiod/edge_event.py          |   46 +
 bindings/python/gpiod/exception.py           |   20 +
 bindings/python/gpiod/ext/Makefile.am        |   11 +
 bindings/python/gpiod/ext/chip.c             |  335 +++
 bindings/python/gpiod/ext/common.c           |   92 +
 bindings/python/gpiod/ext/internal.h         |   20 +
 bindings/python/gpiod/ext/line-config.c      |  133 +
 bindings/python/gpiod/ext/line-settings.c    |  130 +
 bindings/python/gpiod/ext/module.c           |  193 ++
 bindings/python/gpiod/ext/request.c          |  402 +++
 bindings/python/gpiod/info_event.py          |   33 +
 bindings/python/gpiod/internal.py            |   19 +
 bindings/python/gpiod/line.py                |   56 +
 bindings/python/gpiod/line_info.py           |   73 +
 bindings/python/gpiod/line_request.py        |  258 ++
 bindings/python/gpiod/line_settings.py       |   62 +
 bindings/python/gpiodmodule.c                | 2662 ------------------
 bindings/python/setup.py                     |   47 +
 bindings/python/tests/Makefile.am            |   26 +-
 bindings/python/tests/__init__.py            |   17 +
 bindings/python/tests/__main__.py            |   16 +
 bindings/python/tests/gpiod_py_test.py       |  832 ------
 bindings/python/tests/gpiomockupmodule.c     |  309 --
 bindings/python/tests/gpiosim/Makefile.am    |    7 +
 bindings/python/tests/gpiosim/__init__.py    |    4 +
 bindings/python/tests/gpiosim/chip.py        |   66 +
 bindings/python/tests/gpiosim/ext.c          |  345 +++
 bindings/python/tests/helpers.py             |   16 +
 bindings/python/tests/tests_chip.py          |  231 ++
 bindings/python/tests/tests_chip_info.py     |   52 +
 bindings/python/tests/tests_edge_event.py    |  219 ++
 bindings/python/tests/tests_info_event.py    |  189 ++
 bindings/python/tests/tests_line_info.py     |  101 +
 bindings/python/tests/tests_line_request.py  |  449 +++
 bindings/python/tests/tests_line_settings.py |   79 +
 bindings/python/tests/tests_module.py        |   59 +
 configure.ac                                 |    3 +
 50 files changed, 4338 insertions(+), 3925 deletions(-)
 create mode 100644 bindings/python/.gitignore
 create mode 100644 bindings/python/gpiod/Makefile.am
 create mode 100644 bindings/python/gpiod/__init__.py
 create mode 100644 bindings/python/gpiod/chip.py
 create mode 100644 bindings/python/gpiod/chip_info.py
 create mode 100644 bindings/python/gpiod/edge_event.py
 create mode 100644 bindings/python/gpiod/exception.py
 create mode 100644 bindings/python/gpiod/ext/Makefile.am
 create mode 100644 bindings/python/gpiod/ext/chip.c
 create mode 100644 bindings/python/gpiod/ext/common.c
 create mode 100644 bindings/python/gpiod/ext/internal.h
 create mode 100644 bindings/python/gpiod/ext/line-config.c
 create mode 100644 bindings/python/gpiod/ext/line-settings.c
 create mode 100644 bindings/python/gpiod/ext/module.c
 create mode 100644 bindings/python/gpiod/ext/request.c
 create mode 100644 bindings/python/gpiod/info_event.py
 create mode 100644 bindings/python/gpiod/internal.py
 create mode 100644 bindings/python/gpiod/line.py
 create mode 100644 bindings/python/gpiod/line_info.py
 create mode 100644 bindings/python/gpiod/line_request.py
 create mode 100644 bindings/python/gpiod/line_settings.py
 delete mode 100644 bindings/python/gpiodmodule.c
 create mode 100644 bindings/python/setup.py
 create mode 100644 bindings/python/tests/__init__.py
 create mode 100644 bindings/python/tests/__main__.py
 delete mode 100755 bindings/python/tests/gpiod_py_test.py
 delete mode 100644 bindings/python/tests/gpiomockupmodule.c
 create mode 100644 bindings/python/tests/gpiosim/Makefile.am
 create mode 100644 bindings/python/tests/gpiosim/__init__.py
 create mode 100644 bindings/python/tests/gpiosim/chip.py
 create mode 100644 bindings/python/tests/gpiosim/ext.c
 create mode 100644 bindings/python/tests/helpers.py
 create mode 100644 bindings/python/tests/tests_chip.py
 create mode 100644 bindings/python/tests/tests_chip_info.py
 create mode 100644 bindings/python/tests/tests_edge_event.py
 create mode 100644 bindings/python/tests/tests_info_event.py
 create mode 100644 bindings/python/tests/tests_line_info.py
 create mode 100644 bindings/python/tests/tests_line_request.py
 create mode 100644 bindings/python/tests/tests_line_settings.py
 create mode 100644 bindings/python/tests/tests_module.py

Comments

Bartosz Golaszewski Oct. 12, 2022, 12:34 p.m. UTC | #1
On Fri, Oct 7, 2022 at 4:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
>
> This is the third iteration of python bindings for libgpiod but it really has
> very little in common with the previous version.
>
> This time the code has been split into high-level python and low-level
> C layers with the latter only doing the bare minimum.
>
> The data model is mostly based on the C++ one with the main difference
> being utilizing dynamic typing and keyword arguments in place of the
> builder pattern. That allows us to reduce the number of methods and
> objects.
>
> Because python doesn't have RAII, unlike C++, we provide a module-level
> request_lines() helper as gpiod.Chip(path).request_lines(...) one-liner
> could lead to the chip left dangling even after the last reference is
> dropped.
>
> Because python forces us to dynamically allocate objects all the time even
> for fundamental types (which are also immutable) there's no point in trying
> to replicate the edge-event buffer. Instead LineRequest.read_edge_event()
> just returns a list of events.
>
> Bartosz Golaszewski (4):
>   bindings: python: remove old version
>   bindings: python: add examples
>   bindings: python: add tests
>   bindings: python: implement python bindings for libgpiod v2
>
>  bindings/python/.gitignore                   |    8 +
>  bindings/python/Makefile.am                  |   26 +-
>  bindings/python/examples/Makefile.am         |   16 +-
>  bindings/python/examples/gpiodetect.py       |   15 +-
>  bindings/python/examples/gpiofind.py         |   14 +-
>  bindings/python/examples/gpioget.py          |   34 +-
>  bindings/python/examples/gpioinfo.py         |   41 +-
>  bindings/python/examples/gpiomon.py          |   52 +-
>  bindings/python/examples/gpioset.py          |   46 +-
>  bindings/python/gpiod/Makefile.am            |   17 +
>  bindings/python/gpiod/__init__.py            |   53 +
>  bindings/python/gpiod/chip.py                |  308 ++
>  bindings/python/gpiod/chip_info.py           |   21 +
>  bindings/python/gpiod/edge_event.py          |   46 +
>  bindings/python/gpiod/exception.py           |   20 +
>  bindings/python/gpiod/ext/Makefile.am        |   11 +
>  bindings/python/gpiod/ext/chip.c             |  335 +++
>  bindings/python/gpiod/ext/common.c           |   92 +
>  bindings/python/gpiod/ext/internal.h         |   20 +
>  bindings/python/gpiod/ext/line-config.c      |  133 +
>  bindings/python/gpiod/ext/line-settings.c    |  130 +
>  bindings/python/gpiod/ext/module.c           |  193 ++
>  bindings/python/gpiod/ext/request.c          |  402 +++
>  bindings/python/gpiod/info_event.py          |   33 +
>  bindings/python/gpiod/internal.py            |   19 +
>  bindings/python/gpiod/line.py                |   56 +
>  bindings/python/gpiod/line_info.py           |   73 +
>  bindings/python/gpiod/line_request.py        |  258 ++
>  bindings/python/gpiod/line_settings.py       |   62 +
>  bindings/python/gpiodmodule.c                | 2662 ------------------
>  bindings/python/setup.py                     |   47 +
>  bindings/python/tests/Makefile.am            |   26 +-
>  bindings/python/tests/__init__.py            |   17 +
>  bindings/python/tests/__main__.py            |   16 +
>  bindings/python/tests/gpiod_py_test.py       |  832 ------
>  bindings/python/tests/gpiomockupmodule.c     |  309 --
>  bindings/python/tests/gpiosim/Makefile.am    |    7 +
>  bindings/python/tests/gpiosim/__init__.py    |    4 +
>  bindings/python/tests/gpiosim/chip.py        |   66 +
>  bindings/python/tests/gpiosim/ext.c          |  345 +++
>  bindings/python/tests/helpers.py             |   16 +
>  bindings/python/tests/tests_chip.py          |  231 ++
>  bindings/python/tests/tests_chip_info.py     |   52 +
>  bindings/python/tests/tests_edge_event.py    |  219 ++
>  bindings/python/tests/tests_info_event.py    |  189 ++
>  bindings/python/tests/tests_line_info.py     |  101 +
>  bindings/python/tests/tests_line_request.py  |  449 +++
>  bindings/python/tests/tests_line_settings.py |   79 +
>  bindings/python/tests/tests_module.py        |   59 +
>  configure.ac                                 |    3 +
>  50 files changed, 4338 insertions(+), 3925 deletions(-)
>  create mode 100644 bindings/python/.gitignore
>  create mode 100644 bindings/python/gpiod/Makefile.am
>  create mode 100644 bindings/python/gpiod/__init__.py
>  create mode 100644 bindings/python/gpiod/chip.py
>  create mode 100644 bindings/python/gpiod/chip_info.py
>  create mode 100644 bindings/python/gpiod/edge_event.py
>  create mode 100644 bindings/python/gpiod/exception.py
>  create mode 100644 bindings/python/gpiod/ext/Makefile.am
>  create mode 100644 bindings/python/gpiod/ext/chip.c
>  create mode 100644 bindings/python/gpiod/ext/common.c
>  create mode 100644 bindings/python/gpiod/ext/internal.h
>  create mode 100644 bindings/python/gpiod/ext/line-config.c
>  create mode 100644 bindings/python/gpiod/ext/line-settings.c
>  create mode 100644 bindings/python/gpiod/ext/module.c
>  create mode 100644 bindings/python/gpiod/ext/request.c
>  create mode 100644 bindings/python/gpiod/info_event.py
>  create mode 100644 bindings/python/gpiod/internal.py
>  create mode 100644 bindings/python/gpiod/line.py
>  create mode 100644 bindings/python/gpiod/line_info.py
>  create mode 100644 bindings/python/gpiod/line_request.py
>  create mode 100644 bindings/python/gpiod/line_settings.py
>  delete mode 100644 bindings/python/gpiodmodule.c
>  create mode 100644 bindings/python/setup.py
>  create mode 100644 bindings/python/tests/__init__.py
>  create mode 100644 bindings/python/tests/__main__.py
>  delete mode 100755 bindings/python/tests/gpiod_py_test.py
>  delete mode 100644 bindings/python/tests/gpiomockupmodule.c
>  create mode 100644 bindings/python/tests/gpiosim/Makefile.am
>  create mode 100644 bindings/python/tests/gpiosim/__init__.py
>  create mode 100644 bindings/python/tests/gpiosim/chip.py
>  create mode 100644 bindings/python/tests/gpiosim/ext.c
>  create mode 100644 bindings/python/tests/helpers.py
>  create mode 100644 bindings/python/tests/tests_chip.py
>  create mode 100644 bindings/python/tests/tests_chip_info.py
>  create mode 100644 bindings/python/tests/tests_edge_event.py
>  create mode 100644 bindings/python/tests/tests_info_event.py
>  create mode 100644 bindings/python/tests/tests_line_info.py
>  create mode 100644 bindings/python/tests/tests_line_request.py
>  create mode 100644 bindings/python/tests/tests_line_settings.py
>  create mode 100644 bindings/python/tests/tests_module.py
>
> --
> 2.34.1
>

I fixed the one nit from Andy. If there are no objections I'd like to
apply this and squash the entire v2 patch series into one big commit
and apply it to the master branch. This way we can stop keeping this
temporary branch and continue the development (tools, rust, possible
further tweaks to the API) on master.

Bart
Kent Gibson Oct. 12, 2022, 12:41 p.m. UTC | #2
On Wed, Oct 12, 2022 at 02:34:44PM +0200, Bartosz Golaszewski wrote:
> On Fri, Oct 7, 2022 at 4:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> >
> > This is the third iteration of python bindings for libgpiod but it really has
> > very little in common with the previous version.
> >
> > This time the code has been split into high-level python and low-level
> > C layers with the latter only doing the bare minimum.
> >
> > The data model is mostly based on the C++ one with the main difference
> > being utilizing dynamic typing and keyword arguments in place of the
> > builder pattern. That allows us to reduce the number of methods and
> > objects.
> >
> > Because python doesn't have RAII, unlike C++, we provide a module-level
> > request_lines() helper as gpiod.Chip(path).request_lines(...) one-liner
> > could lead to the chip left dangling even after the last reference is
> > dropped.
> >
> > Because python forces us to dynamically allocate objects all the time even
> > for fundamental types (which are also immutable) there's no point in trying
> > to replicate the edge-event buffer. Instead LineRequest.read_edge_event()
> > just returns a list of events.
> >
> > Bartosz Golaszewski (4):
> >
> 
> I fixed the one nit from Andy. If there are no objections I'd like to
> apply this and squash the entire v2 patch series into one big commit
> and apply it to the master branch. This way we can stop keeping this
> temporary branch and continue the development (tools, rust, possible
> further tweaks to the API) on master.
> 

I'm in the process of reviewing, so hold off for a bit if you can.

If not, at the very least  IIIIpdII -> IIIIpkII in patch 4.

Otherwise you get this on 32 bit platforms:

$ gpioget.py /dev/gpiochip0 17
*** stack smashing detected ***: terminated

Cheers,
Kent.
Bartosz Golaszewski Oct. 12, 2022, 12:51 p.m. UTC | #3
On Wed, Oct 12, 2022 at 2:42 PM Kent Gibson <warthog618@gmail.com> wrote:
>
> On Wed, Oct 12, 2022 at 02:34:44PM +0200, Bartosz Golaszewski wrote:
> > On Fri, Oct 7, 2022 at 4:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> > >
> > > This is the third iteration of python bindings for libgpiod but it really has
> > > very little in common with the previous version.
> > >
> > > This time the code has been split into high-level python and low-level
> > > C layers with the latter only doing the bare minimum.
> > >
> > > The data model is mostly based on the C++ one with the main difference
> > > being utilizing dynamic typing and keyword arguments in place of the
> > > builder pattern. That allows us to reduce the number of methods and
> > > objects.
> > >
> > > Because python doesn't have RAII, unlike C++, we provide a module-level
> > > request_lines() helper as gpiod.Chip(path).request_lines(...) one-liner
> > > could lead to the chip left dangling even after the last reference is
> > > dropped.
> > >
> > > Because python forces us to dynamically allocate objects all the time even
> > > for fundamental types (which are also immutable) there's no point in trying
> > > to replicate the edge-event buffer. Instead LineRequest.read_edge_event()
> > > just returns a list of events.
> > >
> > > Bartosz Golaszewski (4):
> > >
> >
> > I fixed the one nit from Andy. If there are no objections I'd like to
> > apply this and squash the entire v2 patch series into one big commit
> > and apply it to the master branch. This way we can stop keeping this
> > temporary branch and continue the development (tools, rust, possible
> > further tweaks to the API) on master.
> >
>
> I'm in the process of reviewing, so hold off for a bit if you can.
>
> If not, at the very least  IIIIpdII -> IIIIpkII in patch 4.
>
> Otherwise you get this on 32 bit platforms:
>
> $ gpioget.py /dev/gpiochip0 17
> *** stack smashing detected ***: terminated
>

I'll wait in this case, thanks. Wanted to start testing the new tools
but thought about getting this behind us first.

Bart
Kent Gibson Oct. 12, 2022, 1:03 p.m. UTC | #4
On Wed, Oct 12, 2022 at 02:51:09PM +0200, Bartosz Golaszewski wrote:
> On Wed, Oct 12, 2022 at 2:42 PM Kent Gibson <warthog618@gmail.com> wrote:
> >
> > On Wed, Oct 12, 2022 at 02:34:44PM +0200, Bartosz Golaszewski wrote:
> > > On Fri, Oct 7, 2022 at 4:55 PM Bartosz Golaszewski <brgl@bgdev.pl> wrote:
> > > >
> > > > This is the third iteration of python bindings for libgpiod but it really has
> > > > very little in common with the previous version.
> > > >
> > > > This time the code has been split into high-level python and low-level
> > > > C layers with the latter only doing the bare minimum.
> > > >
> > > > The data model is mostly based on the C++ one with the main difference
> > > > being utilizing dynamic typing and keyword arguments in place of the
> > > > builder pattern. That allows us to reduce the number of methods and
> > > > objects.
> > > >
> > > > Because python doesn't have RAII, unlike C++, we provide a module-level
> > > > request_lines() helper as gpiod.Chip(path).request_lines(...) one-liner
> > > > could lead to the chip left dangling even after the last reference is
> > > > dropped.
> > > >
> > > > Because python forces us to dynamically allocate objects all the time even
> > > > for fundamental types (which are also immutable) there's no point in trying
> > > > to replicate the edge-event buffer. Instead LineRequest.read_edge_event()
> > > > just returns a list of events.
> > > >
> > > > Bartosz Golaszewski (4):
> > > >
> > >
> > > I fixed the one nit from Andy. If there are no objections I'd like to
> > > apply this and squash the entire v2 patch series into one big commit
> > > and apply it to the master branch. This way we can stop keeping this
> > > temporary branch and continue the development (tools, rust, possible
> > > further tweaks to the API) on master.
> > >
> >
> > I'm in the process of reviewing, so hold off for a bit if you can.
> >
> > If not, at the very least  IIIIpdII -> IIIIpkII in patch 4.
> >
> > Otherwise you get this on 32 bit platforms:
> >
> > $ gpioget.py /dev/gpiochip0 17
> > *** stack smashing detected ***: terminated
> >
> 
> I'll wait in this case, thanks. Wanted to start testing the new tools
> but thought about getting this behind us first.
> 

The idea of getting the tools patch out was to keep you busy while I
reviewed the python. Unfortunately I got bogged down in corner cases so
that took much longer to get out than I had intended.

I only started looking at the python today, and I don't want to commit
to a completion time at this stage, but shouldn't be too long.

So go play with the tools for a bit.

Cheers,
Kent.