1
0
mirror of https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git synced 2026-10-28 13:55:08 +03:00

48 Commits

Author SHA1 Message Date
Kent Gibson
1631521e64 bindings: python: fix uninitialized default_vals being passed to gpiod_LineBulk_request()
If "default_vals" is not provided in the kwds then default_vals are
passed uninitialized to gpiod_line_request_bulk(), so rename the
existing default_vals to vals and introduce a new default_vals that
points to vals, or NULL if no defaults have been passed.

Fixes: 96c524c495 (bindings: implement python bindings)
Reported-by: Pedro Botella <pbotella@gmail.com>
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2021-02-15 15:18:50 +01:00
Jiri Benc
fb3f127c38 bindings: python: fix Line.request() crashing
On an attempt to call the 'request' method of a Line object, the program
crashes with this exception:

> SystemError: ../Objects/dictobject.c:2606: bad argument to internal function
>
> The above exception was the direct cause of the following exception:
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> SystemError: <class 'gpiod.LineBulk'> returned a result with an error set

The problem is that keyword args are NULL (rather than an empty dict) if
they are not present. However, PyDict_Size sets an exception if it gets
NULL.

Fixes: 02a3d0a2ab ("bindings: python: fix segfault when calling Line.request()")
Signed-off-by: Jiri Benc <jbenc@upir.cz>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2020-10-09 14:36:02 +02:00
Jiri Benc
52cf211505 bindings: python: fix incorrect object size
tp_basicsize is the size of the allocated object, not of the class.

Fixes: 96c524c495 ("bindings: implement python bindings")
Signed-off-by: Jiri Benc <jbenc@upir.cz>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2020-10-09 09:45:32 +02:00
Bartosz Golaszewski
7f30548da6 bindings: python: add the __version__ module attribute
The python module provides the version_string() function that returns
the API version but the standard way to do this according to PEP 396
is by providing the __version__ attribute at the module level.

Add __version__ constant to gpiod module and mark version_string() as
deprecated in the doc.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2020-04-02 11:02:20 +02:00
Bartosz Golaszewski
40504d6a32 bindings: python: add a method for reading multiple line events
Add a new method to the Line class allowing to read up to 16 line
events at once.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2020-01-02 18:30:53 +01:00
Joel Savitz
02a3d0a2ab bindings: python: fix segfault when calling Line.request()
When Line.request() is called without the required 'consumer=value'
argument, the module attempts access an empty dictionary object
resulting in a segfault. This patch avoids such access when the
dictionary is empty and maintains the current design where the
LineBulk object is responsible for validation of arguments.

Signed-off-by: Joel Savitz <jsavitz@redhat.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2019-12-11 16:10:06 +01:00
Kent Gibson
3e30364cc1 bindings: python: make vals in gpiod_Line_set_value consistent with other functions
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>
2019-12-10 16:43:09 +01:00
Kent Gibson
937ca5ae35 bindings: python: add support for SET_CONFIG
Add methods to support setting line configuration.

Signed-off-by: Kent Gibson <warthog618@gmail.com>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
2019-12-10 14:46:27 +01:00
Kent Gibson
587fd12961 bindings: python: move tuple to int array conversion into helper function
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>
2019-12-10 14:45:32 +01:00
Kent Gibson
811a694411 bindings: python: add support for bias flags
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>
2019-12-10 08:58:55 +01:00
Kent Gibson
bb3dc9eb2e treewide: change "correspond with" to "correspond to"
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>
2019-11-18 15:46:12 +01:00
Bartosz Golaszewski
1395cf9edf bindings: python: directly return the value from PyErr_SetFromErrno()
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>
2019-09-19 18:51:27 +02:00
Bartosz Golaszewski
4029c34f5c bindings: python: provide Line.update()
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>
2019-09-14 15:29:48 +02:00
Bartosz Golaszewski
b33cb2aa56 bindings: python: fix the default_val argument name in the doc string
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>
2019-08-09 11:49:09 +02:00
Bartosz Golaszewski
583cf823d3 bindings: python: fix GCC8 warnings due to function pointer casting
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>
2019-07-11 11:57:13 +02:00
Bartosz Golaszewski
0e2ff67853 bindings: python: add support for 'default_val' in Line.request()
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>
2019-02-15 13:46:10 +01:00
Bartosz Golaszewski
aa1eb7e6eb bindings: python: fix argument alignment in a function call
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>
2019-02-15 13:16:57 +01:00
Bartosz Golaszewski
acdd77c639 treewide: unify naming of local variables representing return values
For integers representing simple return values of various functions
use the name 'rv' everywhere.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-11-14 17:43:35 +01:00
Bartosz Golaszewski
3feb6d4fd5 bindings: python: pydoc improvements
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>
2018-07-31 16:24:01 +02:00
Bartosz Golaszewski
cdf5ef94c4 bindings: python: fix gpiod_Chip_find_lines() for nonexistent lines
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>
2018-07-31 14:30:46 +02:00
Bartosz Golaszewski
e9e56da405 bindings: python: remove a redundant if
We don't need to check if bulk is NULL in gpiod_Chip_find_lines()
before returning it.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-07-31 14:30:46 +02:00
Bartosz Golaszewski
29adcc24da bindings: python: fix tp_dealloc callbacks in all objects
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>
2018-07-24 14:12:18 +02:00
Bartosz Golaszewski
9d97f989ef bindings: python: don't force python to use the system allocator
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>
2018-07-22 21:26:47 +02:00
Bartosz Golaszewski
f8221bc88b bindings: python: don't call gpiod_LineBulk_init() directly
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>
2018-07-22 15:23:59 +02:00
Bartosz Golaszewski
58331f66e7 bindings: python: fix the default_vals argument in line requests
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>
2018-07-20 10:35:35 +02:00
Bartosz Golaszewski
150d2ca90b bindings: python: move gpiod_ChipIsClosed() to the top of gpiodmodule.c
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>
2018-07-13 18:34:50 +02:00
Bartosz Golaszewski
048f0dc26e bindings: python: call gpiod_LineBulk_init() directly
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>
2018-07-13 15:58:27 +02:00
Bartosz Golaszewski
f7e284ee6e bindings: python: provide a helper for calling methods with python args
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>
2018-07-13 15:08:45 +02:00
Bartosz Golaszewski
df5d7b4f42 bindings: python: fix a memory corruption
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>
2018-07-13 11:25:25 +02:00
Bartosz Golaszewski
ead4d6b46a bindings: python: fix a memory leak in error path
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>
2018-07-13 10:11:12 +02:00
Bartosz Golaszewski
3c660a3ec5 bindings: python: fix a warning
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>
2018-06-07 09:27:54 +02:00
Bartosz Golaszewski
6b3450372e bindings: python: avoid calling object method callbacks directly
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>
2018-06-07 09:25:04 +02:00
Bartosz Golaszewski
18d286843b bindings: python: use PyObject_CallMethod() where possible
Avoid directly calling method callbacks. Use the routine provided by
Python API instead where possible.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-06-07 08:56:05 +02:00
Bartosz Golaszewski
2dfb43260a bindings: python: add support for controlled execution
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>
2018-05-16 12:29:17 +02:00
Bartosz Golaszewski
e04d4d45c2 bindings: python: provide better resource control
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>
2018-05-16 12:01:45 +02:00
Bartosz Golaszewski
7cc5304f33 bindings: python: provide gpiod.version_string()
Implement a python wrapper around gpiod_version_string().

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-16 10:39:11 +02:00
Bartosz Golaszewski
16e5a3ce56 bindings: python: provide Line.is_requested()
Add a python wrapper around gpiod_line_is_requested().

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-15 18:34:52 +02:00
Bartosz Golaszewski
d463052184 bindings: python: provide Chip.get_all_lines()
Add a method for retrieving all GPIO lines exposed by a chip.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-15 12:05:28 +02:00
Bartosz Golaszewski
2c8127eba1 bindings: python: improve readability
Order the arguments in a reverse christmas tree shape in
gpiod_Chip_find_lines();

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-15 11:50:16 +02:00
Bartosz Golaszewski
7a64b84885 bindings: python: code shrink
Provide a helper for converting a list of lines into a LineBulk object
in a single call.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-15 11:49:16 +02:00
Bartosz Golaszewski
e6d1647a8f bindings: python: implement Chip.find_lines()
Provide a method for looking up multiple lines by name at once.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-15 11:41:52 +02:00
Bartosz Golaszewski
1e47c4d6ea bindings: python: change the return value of gpiod_LineBulk_event_wait()
gpiod_Line_event_wait() works differently than its LineBulk
counterpart. While the latter returns either a list of lines or False,
the former returns True if an event occurred on this line or False
otherwise.

False is not a good counterpart for an actual object, so instead return
None if no events occurred on any of the monitored lines.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-14 12:01:13 +02:00
Bartosz Golaszewski
15a623a7d2 bindings: python: fix a memory leak in gpiod_Line_event_wait()
We don't return the object returned from gpiod_LineBulk_event_wait()
back to the interpreter. We need to collect it before returning True.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-14 12:01:13 +02:00
Bartosz Golaszewski
27fec345ca bindings: python: fix a memory leak in Line.set_value()
We're not collecting the bulk object we're creating in this method. Add
Py_DECREF() where needed.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-14 12:01:13 +02:00
Bartosz Golaszewski
d331321f01 bindings: python: return None if line can't be found by name
For both find_line() variants (Chip's method and global function)
return None if the internal call to the C find_line function fails
with ENOENT. This is not an error so don't raise an exception.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-14 11:49:13 +02:00
Bartosz Golaszewski
f36a27f1cc bindings: python: decref the chip object in gpiod_Module_find_line()
When returning back to the interpreter from gpiod_Module_find_line(),
there's only one chip object reference holder, but we set the refcount
to 2 (as if the chip object existed separately in the interpreter).

Fix it by decreasing the chip's refcount by one before returning the
line object.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-05-12 14:51:28 +02:00
Bartosz Golaszewski
039b301b17 bindings: python: release the GIL during blocking I/O operations
We should release the python global interpreter lock when performing
blocking operations and reacquire it again when we're done. Use the
relevant APIs provided by libpython.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-04-22 23:16:40 +02:00
Bartosz Golaszewski
96c524c495 bindings: implement python bindings
Create a C extension module wrapping the functionality of libgpiod
in a set of Python classes.

Add code examples including simplified reimplementations of gpio-tools
in Python.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
2018-04-17 10:19:34 +02:00