Minor gpiod package release.
Changelog:
- add fileno() for Chip and LineRequest
- relax the verbosity adjustment in build_tests.sh
- fix potential PyDict_Next() crash
- fix tests failing after a kernel fix to gpio-sim
- various documentation fixes
- rework the code treewide to make it conformant with mypy and ruff
linter recommendations
- fix requesting lines by name with multiple entries
- fix a use-after-free bug in python bindings
- fix passing the event clock property to line requests in python
bindings
- improve the output of LineSettings.__repr__()
- import gpiod attributes in external module
- specify a tar extract filter for python >= 3.12
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Several .rst files are not bundled in distro tarballs. Add them to
EXTRA_DIST.
Fixes: dda57bd63f ("doc: move README contents to sphinx docs")
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Current sphinx/ contents are mostly WiP. Let's beat them into shape for
publishing on ReadTheDocs.
Integrate the API documentation generated with doxygen for the core C
API and C++ bindings into sphinx using breathe.
Update configure.ac to check for sphinx-build in addition to doxygen and
make the main Makefile trigger a sphinx build on `make doc` (although
the docs can also be generated without starting the build system by
running: `sphinx-build ./docs/ docs/sphinx-output`).
Move the introduction text from the main header into the relevant .rst
file.
Remove obsolete Doxyfile.in and create a static Doxygen under doc/ where
all the documentation now lives.
Update .gitignore where needed.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20250211-improve-docs-v4-12-dc56702c2ca8@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Groups make sense for the C API as they allow us to nicely order
interfaces manipulating a given structure thematically but for C++ they
make less sense as methods are already typically part of a class.
Additionally for global functions, they seem to make it difficult for
breathe to look up the correct symbols.
Remove the gpiod_cxx group from Doxygen comments.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20250211-improve-docs-v4-2-dc56702c2ca8@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Extend the test sequence to check that a device can be disabled and
re-enabled without problems.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Linux kernel commit 8bd76b3d3f3a ("gpio: sim: lock up configfs that an
instantiated device depends on") has uncovered an issue in libgpiosim:
we use reference counting for all objects (to make RAII easier for
bindings) but, with the above change, if the user doesn't explicitly
disable the device before dropping the last reference to a bank object,
the parent device will never get correctly cleaned up.
This is because we remove the hog and line directories in bank's
release() callback unconditionally. With the directories being locked
now, this fails if device is active and then when we eventually call the
device object's release(), we'll end up stuck with leftover bank
directories and never actually clean-up correctly.
Extend the gpiosim device with a list of deferred banks. When releasing
a bank on an active device, defer any actual cleanup until the time the
device gets deactivated which may be triggered by the user explictly or
will happen automatically when the last reference to the device object is
dropped. For inactive devices, there's no functional change.
Link: https://lore.kernel.org/r/20250214102648.71382-1-brgl@bgdev.pl
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
One GMainContext iteration may not be enough for the info event to be
emitted by the kernel after the triggering event. Let's wait a bit
longer. This fixes sporadic failures in the affected test cases
depending on the system load.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The org.freedesktop.DBus.Peer.Ping() method isn't correct for checking
if a given object is exposed by a service. It only lets us know if the
service is available no matter the object on which it's called (in fact:
it will not return an error even if it's called on a nonexistent object).
While this has worked for most part by accident, if the timing isn't
right, we may start calling methods in chips which are not yet fully
registered. We should try to read the chip's property instead and keep
on waiting for as long as org.freedesktop.DBus.Properties.Get() returns
an error.
While at it: fix the counter increment as its syntax is invalid.
Fixes: a5ab76da1e ("dbus: add the D-Bus daemon, command-line client and tests")
Link: https://lore.kernel.org/r/20250203-fix-dbus-wait-for-chip-v1-1-563f7132c04f@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Linux kernel commit 8bd76b3d3f3a ("gpio: sim: lock up configfs that an
instantiated device depends on") uncovered an issue in Rust bindings
tests where the GPIO simulator device is not disabled before removing its
configfs entries. Implenent Drop for the Sim struct in order to disable
the simulator first before dropping its bank and device objects.
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://lore.kernel.org/r/20250203-fix-gpiosim-in-bindings-v1-3-d2c9e0f3a29d@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Linux kernel commit 8bd76b3d3f3a ("gpio: sim: lock up configfs that an
instantiated device depends on") uncovered an issue in Python bindings
tests where the GPIO simulator device is not disabled before removing its
configfs entries. Reorder the operations in chip_finalize() in order to
disable the device first (if needed) before releasing any other
resources.
Link: https://lore.kernel.org/r/20250203-fix-gpiosim-in-bindings-v1-2-d2c9e0f3a29d@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
This was complained about by clippy:
warning: empty line after doc comment
--> libgpiod/src/lib.rs:461:1
|
461 | / /// Various libgpiod-related functions.
462 | |
| |_
...
467 | pub fn is_gpiochip_device<P: AsRef<Path>>(path: &P) -> bool {
| ----------------------------------------------------------- the comment documents this function
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments
= help: if the empty line is unintentional remove it
help: if the documentation should include the empty line include it in the comment
|
462 | ///
|
The comment more seems to be of structural matter and should not be tied
to the function immediately below it. So lets turn it into a normal
non-doc comment.
Signed-off-by: Erik Schilling <erik.schilling@linaro.org>
Link: https://lore.kernel.org/r/20250103-lifetime-fix-v2-2-63902dc8cae1@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Newer rustc versions warn on elided named lifetimes. In thise case, it
actually revealed a misleading function signature.
The function defined &self with 'a. But there is no dependency on the
Request reference that extends longer than this function call. Yet,
the code expresses such a dependency and abuses it to force the buffer
argument to match &self lifetime (and thus the return lifetime too!).
Instead we want to explicitly break up the tie to the &self and tie it
to the buffer instead.
The 'a on &self caused a 'a on the return. With that being removed we
would get an automatic '0. So we are now forced to add the 'a on the
return that also fixes the compiler warning.
Reported-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Co-authored-by: Kent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/CAMRc=Me-QNmJ2L1K-gGzFtVZacsDiLsNUfh3QaWPdbVzyxUduA@mail.gmail.com/
Signed-off-by: Erik Schilling <erik.schilling@linaro.org>
Link: https://lore.kernel.org/r/20250103-lifetime-fix-v2-1-63902dc8cae1@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Certain polling APIs in the standard library - most notably: the
select() function and the poll class - allow to poll any object that
implements the fileno() method returning the underlying file descriptor
number.
Implement fileno() for Chip and LineRequest which allows users to do:
rd, _, _ = select([chip/request], [], [], 1)
where rd will contain the actual object passed to select which makes for
easier reading of events afterwards.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241211-python-fileno-v2-1-84c642572485@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
When building tests using the build_tests.py script, we try to increase
the verbosity using setuptools.logging.configure() preferably but
falling back to distutils.log.set_verbosity() if the former is missing.
This however creates a hard dependency on distutils on older environments
missing the recently added setuptools method. The build however, can work
fine even with default (low) verbosity so instead of bailing out if the
second import fails, just keep going.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Closes: https://github.com/brgl/libgpiod/issues/109
Link: https://lore.kernel.org/r/20241127133139.120107-1-brgl@bgdev.pl
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
We claim that libgpiod python bindings have no dependencies other than
the python standard library but this is not true - the tests do depend
on deprecated distutils for kernel version parsing.
As distutils is deprecated, the recommended improvement is to use the
Version class from packaging.version but this would too entail pulling
in an external module.
Let's instead implement the kernel version check in C using uname() and
put it into the tests.system extension. This allows us to entirely drop
the distutils import.
Reviewed-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241120-drop-distutils-v1-3-7498e8b3babe@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The module is now called _internal.py so update the Makefile. Without
this, we're no longer able to generate the distro tarball.
Fixes: b306ce694a ("bindings: python: make internal a private submodule")
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Since their inclusion in Python 3.6, f-strings have become the preferred
way to format strings with variable values as they are generally more
readable as the value substitution is in place and doesn't have to be
parsed from the list or arguments to `.format()`.
Where it does not impact readability (when the line is <120 characters),
swap usage of `.format()` to an f-string.
For lines that are not converted, inform the linter to ignore attempts
to upgrade those instances to f-strings [0]
[0]: https://docs.astral.sh/ruff/rules/f-string/
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-23-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Some of the unit tests intentionally call methods or assign properties
with invalid values to ensure they fail in an expected way.
Type checkers complain for these instances so inform them via directive
that these lines should be ignore for specific errors.
Additionally, some lines that access properties without assigning the
value look like they perform no action to linters.
To appease the linter, read the value into a throw-away variable.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-22-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Add type hints for internal members of the test cases so type checkers
can ensure the code properly constrains to these types and accounts for
scenarios where the values are `None`.
In most cases, the type checker is allowed to assume the inferred type
upon assignment.
An example is any test case that creates a `Chip` as part of its `setUp`
method. Many of these tests subsequently set the reference to `None` in
`tearDown` to free up resources to be collected by the GC.
If the member was "properly" typed to be `Optional`, all references in
the unit tests would need to be guarded by an assert or a cast or
ignored by the type checker. This is noisy and doesn't add value since
for the life of the test it should always be a valid reference.
Instead, allow `tearDown` to violate the inferred type and inform the
type checker to ignore the assignment via directive.
If the tests are ever changed to set the member to something other than
the inferred type outside of `tearDown`, explicit type hints and proper
checks should be added.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-21-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Previously, both tests_edge_event and tests_info_event had a public
module level EventType member.
The __main__ module for unittests does a star import from both modules
which led to an import conflict between the two.
It is not necessary to import EventType to run unit tests.
Now, EventType is private to avoid being imported via star syntax.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-18-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Previously, the `test_rising_edge_event` test was defined twice.
The second instance of the test actually tested the falling edge event
and was shadowing the first test which tested the rising edge event.
Now, the second instance is renamed to `test_falling_edge_event` to
reflect what it is testing and to avoid the naming conflict.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-16-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Since their inclusion in Python 3.6, f-strings have become the preferred
way to format strings with variable values as they are generally more
readable as the value substitution is in place and doesn't have to be
parsed from the list or arguments to `.format()`.
Where it does not impact readability (when the line is <120 characters),
swap usage of `.format()` to an f-string.
For lines that are not converted, inform the linter to ignore attempts
to upgrade those instances to f-strings [0]
[0]: https://docs.astral.sh/ruff/rules/f-string/
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-15-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
The `values` argument of `_ext.Request.get_values` uses a preallocated
`list[None]` as a buffer that is populated with `Value`s by the external
module that are then returned from the function.
Use `cast` to inform the type checker it's a `list[Value]` despite how
it's allocated.
Also, as `lines` is typed as an `Iterable`, there is no guarantee it has
a `__len__` method. Instead, use the size of the `offsets` array to
allocate the buffer.
Signed-off-by: Vincent Fazio <vfazio@xes-inc.com>
Link: https://lore.kernel.org/r/20241114145116.2123714-14-vfazio@xes-inc.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>