Change the vals in gpiod_Line_set_value from a tuple of tuples to just a
tuple. This brings it into line with other vals in the module such as
gpiod_Line_set_config and gpiod_Line_set_direction_output.
The previous usage made the vals equivalent to an args (a tuple of
arguments equivalent to argc,argv in C), as per gpiod_Line_set_flags.
Renaming vals to args in gpiod_Line_set_value was not an option as there
is already an args parameter.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Extend test coverage over set_config, set_flags, set_direction_input, and
set_direction_output methods.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Restructured gpiod_LineBulk_set_values to move the conversion of values
from Python tuple to int array into a helper function as it is useful for
similar functions.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Extend test coverage to cover the bias flags in requests and the bias
setting returned by line.bias().
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Add support for bias flags in line requests and returning the line bias
setting via a bias accessor.
Based on initial work by Drew Fustini <drew@pdp7.com>.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Trivial grammar fix. "correspond with" can mean either being in agreement
with, happening at the same time, or communication between parties.
"correspond to" is used to mean equivalance, which is the intended use
throughout the documentation.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
PyErr_SetFromErrno() always returns NULL. We can return from functions
on failure directly instead of calling it and then returning NULL in
the next line.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Python bindings are missing the functionality provided by the core C
library's gpiod_line_update(). Extend the Line class with the update()
method that allows to re-read the line information from the kernel.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Don't put a tab between the asignment and the first string - just move
the whole list one line below.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The examples are programs meant to be executed directly and not
imported. Use the standard "if __name__ == '__main__':" before
any code.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Kernel release candidate version strings seem to not be working
correctly with python's version.parse() function. Split the string
retrieved with os.uname().release using '-' as delimiter and pass
only the first part - 'major.minor.release' - to version.parse().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Mainline commit 2c60e6b5c924 ("gpiolib: never report open-drain/source
lines as 'input' to user-space") in the linux kernel has now been
backported to v5.2 stable branch and released in linux v5.2.11. We can
now enable back the assertions that were previously failed in test
suites (core, C++ and python). The required kernel versions must be
updated as well.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
When a call is expected to raise the OSError exception, verify that its
errno field is set to the expected value.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
After setting the line values in gpioset.py: don't exit until the user
presses ENTER. This makes the example work the same as the 'wait' mode
in the original gpioset utility.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
In gpioset.py: when calling lines.set_values(), there's no point in
storing the return value as it's always None. It's also not used
anywhere.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Modify the gpiomon.py example to describe the detected events in
a format similar to the one used by the original gpiomon tool.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Currently the only tests we have for python bindings are in a simple
script that makes a lot of assumptions about the environment and
doesn't even work anymore with recent kernels.
Remove it and replace it with a proper test-suite implemented using
libgpiod and the standard python unittest package.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The argument in Line.request() is called default_val, not default_vals.
For backward compatibility with older versions default_vals would still
work if it was passed a tuple or list, but let's not confuse users:
default_val is the preferred way for single lines.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
GCC8 has added a new warning heuristic to detect invalid function
casts. This causes a lot of warnings when building libgpiod python
bindings.
Let's use Py_UNUSED where applicable to make function prototypes match
that of PyCFunction. For keyword functions, let's cast them to a
function pointer taking no arguments before casting them again to
PyCFunction. This may not be the best solution but it has to do for
the moment.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
The src directory containing lib and tools is not necessary and will
actually cause problems if we tried to add a new component to src/
which would depend on libraries from the bindings directory because it
(bindings) already depends on src/lib.
Simplify the directory structure. Move lib and tools to the root source
directory and update all relevant files. That way we can specify the
exact build order of components from the top source Makefile.am.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Until now Line.request() only took 'default_vals' argument which was
passed down directly to LineBulk.request() internally. This meant that
even when requesting a single line in output mode, the default value
had to be passed in a sequence.
Add support for the 'default_val' argument which makes it possible to
specify the default value as an integer. The previous 'default_vals'
argument is still supported, but the two cannot be passed at the same
time.
Documentation for default_vals is removed, as it's now deprecated for
Line.request().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
When breaking a line, the arguments should be aligned with the opening
bracket of the function call.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
For integers representing simple return values of various functions
use the name 'rv' everywhere.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Current documentation of python bindings is quite limited. Extend it
with more elaborate descriptions of types and methods.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Currently we're not checking if the object returned from
gpiod.fine_line() is None which results in an attribute error being
raised when we try to call line methods on a non-line object.
Add an if and bail-out with an error code if the line with given name
was not found.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Currently if we call gpiod_Chip_find_lines() with some names that
cannot be looked up, we end up getting an exception from the LineBulk
object's constructor (because None is not a Line and LineBulk can only
hold Line objects).
Fix the behavior of gpiod_Chip_find_lines() for nonexistent lines by
raising an explicit exception if the underlying gpiod_Chip_find_line()
call returns None. Also: add a relevant test case.
Fixes: 96c524c495 ("bindings: implement python bindings")
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Unlike the C++ bindings: we can't expect the python runtime to call
the Chip object's destructor when all references are dropped. We need
to close each chip explicitly. Either call the close() method directly
or use controlled execution in all examples.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
We have a significant memory leak in the current implementation as we
don't call PyObject_Del() as the last action in tp_dealloc callbacks.
From tp_dealloc's documentation:
---
The destructor function should free all references which the instance
owns, free all memory buffers owned by the instance (using the freeing
function corresponding to the allocation function used to allocate the
buffer), and finally (as its last action) call the type’s tp_free
function.
---
PyObject_Del() will internally call the tp_free callback of the type.
Add a call to it as the last action in every destructor.
Fixes: 96c524c495 ("bindings: implement python bindings")
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
When allocating raw memory let python decide which allocator to use.
Convert all calls to PyMem_Raw*() to PyMem_*().
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
We can instantiate an object of a type by "calling" it's type structure
using PyObject_CallObject(). It will internally call the constructor so
use it to shrink the code.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Add two new tests verifying the default_vals argument in line requests
for single and multiple lines.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
We're assigning the wrong local variable in PyArg_ParseTupleAndKeywords()
which results in not honoring the default_vals argument. Fix the
LineBulk.request() implementation.
Fixes: 96c524c495 ("bindings: implement python bindings")
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Unlike the other two helpers that are still declared at the top of the
source file - this routine doesn't need to know any gpiod-specific type
so move it up and remove the prototype.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Strings with slashes trigger a warning in the kernel in
fs/proc/generic.c. Use a hardcoded consumer string.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Using the .tp_init callback is more complicated and unnecessary. Call
gpiod_LineBulk_init() directly from gpiod_ListToLineBulk().
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Wrap the calls to PyObject_GetAttrString() and PyObject_Call() in
a single helper that allows to call a python method and pass it the
args and kwds tuples directly as received from the interpreter.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
PyList_GetItem() returns a borrowed reference so we need to increase
the reference count on the returned object before DECREF'ing the list
object itself
This fixes random 'free(): invalid pointer' errors.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
We need to decref the iter object in Line.set_values() if the
conversion from python to C unsigned integer fails.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
On some architectures we get a 'comparison between signed and unsigned
integer' warning when building python bindings. Fix it by changing the
type of the variable used for offset to unsigned int.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Where it's impossible to use PyObject_CallMethod() (e.g. when we want
to pass args and kwargs unchanged to the method being called), use
a combination of PyObject_GetAttrString() and PyObject_Call().
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Avoid directly calling method callbacks. Use the routine provided by
Python API instead where possible.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
Provide __enter__ and __exit__ callbacks for Chip so that it can be
used with the 'with' statement.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
So far we rely on cpython's reference counting for closing the GPIO
chips and freeing the underlying resources. This is however wrong.
Python doesn't guarantee anything regarding the lifetime of an object.
Provide a method for closing the underlying chip handle and add
relevant checks to all methods using the resources associated with
a GPIO chip, so that we raise an error should the user use a chip
after closing it.
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>