gpiod 2.2.4__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gpiod-2.2.4 → gpiod-2.3.0}/MANIFEST.in +1 -1
- {gpiod-2.2.4/gpiod.egg-info → gpiod-2.3.0}/PKG-INFO +34 -14
- {gpiod-2.2.4 → gpiod-2.3.0}/README.md +17 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/build_tests.py +11 -7
- gpiod-2.3.0/gpiod/__init__.py +124 -0
- gpiod-2.3.0/gpiod/_ext.pyi +93 -0
- gpiod-2.2.4/gpiod/internal.py → gpiod-2.3.0/gpiod/_internal.py +3 -2
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/chip.py +57 -35
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/chip_info.py +8 -5
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/edge_event.py +14 -4
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/exception.py +2 -2
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/info_event.py +14 -7
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/line.py +23 -2
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/line_info.py +17 -5
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/line_request.py +69 -48
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/line_settings.py +16 -7
- gpiod-2.3.0/gpiod/py.typed +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/version.py +1 -1
- {gpiod-2.2.4 → gpiod-2.3.0/gpiod.egg-info}/PKG-INFO +34 -14
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod.egg-info/SOURCES.txt +5 -3
- {gpiod-2.2.4 → gpiod-2.3.0}/include/gpiod.h +0 -36
- gpiod-2.3.0/libgpiod-version.txt +1 -0
- gpiod-2.3.0/pyproject.toml +82 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/setup.py +1 -18
- gpiod-2.3.0/tests/__init__.py +12 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/__main__.py +3 -4
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/gpiosim/__init__.py +3 -1
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/gpiosim/chip.py +2 -1
- gpiod-2.3.0/tests/helpers.py +27 -0
- gpiod-2.3.0/tests/system/__init__.py +6 -0
- gpiod-2.3.0/tests/system/ext.c +79 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_chip.py +50 -49
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_chip_info.py +16 -15
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_edge_event.py +69 -28
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_info_event.py +59 -40
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_line.py +4 -3
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_line_info.py +20 -20
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_line_request.py +199 -99
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_line_settings.py +10 -11
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/tests_module.py +18 -19
- gpiod-2.2.4/gpiod/__init__.py +0 -54
- gpiod-2.2.4/libgpiod-version.txt +0 -1
- gpiod-2.2.4/pyproject.toml +0 -5
- gpiod-2.2.4/tests/__init__.py +0 -17
- gpiod-2.2.4/tests/helpers.py +0 -16
- gpiod-2.2.4/tests/procname/__init__.py +0 -4
- gpiod-2.2.4/tests/procname/ext.c +0 -42
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/chip.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/common.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/internal.h +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/line-config.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/line-settings.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/module.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod/ext/request.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod.egg-info/dependency_links.txt +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/gpiod.egg-info/top_level.txt +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/chip-info.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/chip.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/edge-event.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/info-event.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/internal.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/internal.h +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/line-config.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/line-info.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/line-request.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/line-settings.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/misc.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/request-config.c +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/lib/uapi/gpio.h +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/setup.cfg +0 -0
- {gpiod-2.2.4 → gpiod-2.3.0}/tests/gpiosim/ext.c +0 -0
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: gpiod
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Python bindings for libgpiod
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Author-email: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
6
|
+
License: LGPL-2.1-or-later
|
|
7
|
+
Project-URL: Homepage, https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
|
|
8
|
+
Project-URL: Issues, https://github.com/brgl/libgpiod/issues/
|
|
9
9
|
Platform: linux
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
22
|
Requires-Python: >=3.9.0
|
|
11
23
|
Description-Content-Type: text/markdown
|
|
12
|
-
Dynamic: author
|
|
13
|
-
Dynamic: author-email
|
|
14
|
-
Dynamic: description
|
|
15
|
-
Dynamic: description-content-type
|
|
16
|
-
Dynamic: home-page
|
|
17
|
-
Dynamic: license
|
|
18
|
-
Dynamic: platform
|
|
19
|
-
Dynamic: requires-python
|
|
20
|
-
Dynamic: summary
|
|
21
24
|
|
|
22
25
|
<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
|
|
23
26
|
<!-- SPDX-FileCopyrightText: 2023 Phil Howard <phil@gadgetoid.com> -->
|
|
@@ -133,3 +136,20 @@ make python-tests-run
|
|
|
133
136
|
|
|
134
137
|
from the `libgpiod/bindings/python` directory as root (necessary to be able
|
|
135
138
|
to create the **gpio-sims** used for testing).
|
|
139
|
+
|
|
140
|
+
## Linting/Formatting
|
|
141
|
+
|
|
142
|
+
When making changes, ensure type checks and linting still pass:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
python3 -m venv venv
|
|
146
|
+
. venv/bin/activate
|
|
147
|
+
pip install mypy ruff
|
|
148
|
+
mypy; ruff format; ruff check
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Ideally the gpiod library will continue to pass strict checks:
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
mypy --strict
|
|
155
|
+
```
|
|
@@ -112,3 +112,20 @@ make python-tests-run
|
|
|
112
112
|
|
|
113
113
|
from the `libgpiod/bindings/python` directory as root (necessary to be able
|
|
114
114
|
to create the **gpio-sims** used for testing).
|
|
115
|
+
|
|
116
|
+
## Linting/Formatting
|
|
117
|
+
|
|
118
|
+
When making changes, ensure type checks and linting still pass:
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
python3 -m venv venv
|
|
122
|
+
. venv/bin/activate
|
|
123
|
+
pip install mypy ruff
|
|
124
|
+
mypy; ruff format; ruff check
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Ideally the gpiod library will continue to pass strict checks:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
mypy --strict
|
|
131
|
+
```
|
|
@@ -11,7 +11,7 @@ polluted with artefacts in build/
|
|
|
11
11
|
Builds:
|
|
12
12
|
|
|
13
13
|
tests/gpiosim/_ext.<target>.so
|
|
14
|
-
tests/
|
|
14
|
+
tests/system/_ext.<target>.so
|
|
15
15
|
|
|
16
16
|
"""
|
|
17
17
|
|
|
@@ -61,9 +61,9 @@ gpiosim_ext = Extension(
|
|
|
61
61
|
],
|
|
62
62
|
)
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
"tests.
|
|
66
|
-
sources=["tests/
|
|
64
|
+
system_ext = Extension(
|
|
65
|
+
"tests.system._ext",
|
|
66
|
+
sources=["tests/system/ext.c"],
|
|
67
67
|
define_macros=[("_GNU_SOURCE", "1")],
|
|
68
68
|
extra_compile_args=["-Wall", "-Wextra"],
|
|
69
69
|
)
|
|
@@ -71,7 +71,7 @@ procname_ext = Extension(
|
|
|
71
71
|
dist = Distribution(
|
|
72
72
|
{
|
|
73
73
|
"name": "gpiod",
|
|
74
|
-
"ext_modules": [gpiosim_ext,
|
|
74
|
+
"ext_modules": [gpiosim_ext, system_ext, gpiod_ext],
|
|
75
75
|
"version": __version__,
|
|
76
76
|
"platforms": ["linux"],
|
|
77
77
|
}
|
|
@@ -82,9 +82,13 @@ try:
|
|
|
82
82
|
|
|
83
83
|
configure()
|
|
84
84
|
except ImportError:
|
|
85
|
-
|
|
85
|
+
try:
|
|
86
|
+
from distutils.log import DEBUG, set_verbosity
|
|
86
87
|
|
|
87
|
-
|
|
88
|
+
set_verbosity(DEBUG)
|
|
89
|
+
except ImportError:
|
|
90
|
+
# We can still build the tests, it will just be very quiet.
|
|
91
|
+
pass
|
|
88
92
|
|
|
89
93
|
with tempfile.TemporaryDirectory(prefix="libgpiod-") as temp_dir:
|
|
90
94
|
command = build_ext(dist)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Python bindings for libgpiod.
|
|
6
|
+
|
|
7
|
+
This module wraps the native C API of libgpiod in a set of python classes.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from collections.abc import Iterable
|
|
11
|
+
from typing import Optional, Union
|
|
12
|
+
|
|
13
|
+
from . import (
|
|
14
|
+
_ext,
|
|
15
|
+
chip,
|
|
16
|
+
chip_info,
|
|
17
|
+
edge_event,
|
|
18
|
+
exception,
|
|
19
|
+
info_event,
|
|
20
|
+
line,
|
|
21
|
+
line_info,
|
|
22
|
+
line_request,
|
|
23
|
+
line_settings,
|
|
24
|
+
version,
|
|
25
|
+
)
|
|
26
|
+
from .chip import *
|
|
27
|
+
from .chip_info import *
|
|
28
|
+
from .edge_event import *
|
|
29
|
+
from .exception import *
|
|
30
|
+
from .info_event import *
|
|
31
|
+
from .line_info import *
|
|
32
|
+
from .line_request import *
|
|
33
|
+
from .line_settings import *
|
|
34
|
+
from .version import __version__
|
|
35
|
+
|
|
36
|
+
api_version = _ext.api_version
|
|
37
|
+
|
|
38
|
+
# public submodules
|
|
39
|
+
__all__ = [
|
|
40
|
+
"chip",
|
|
41
|
+
"chip_info",
|
|
42
|
+
"edge_event",
|
|
43
|
+
"exception",
|
|
44
|
+
"info_event",
|
|
45
|
+
"line",
|
|
46
|
+
"line_info",
|
|
47
|
+
"line_request",
|
|
48
|
+
"line_settings",
|
|
49
|
+
"version",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# re-export public submodule exports
|
|
53
|
+
# do not re-export line objects, this is not an oversight
|
|
54
|
+
__all__ += (
|
|
55
|
+
chip.__all__
|
|
56
|
+
+ chip_info.__all__
|
|
57
|
+
+ edge_event.__all__
|
|
58
|
+
+ exception.__all__
|
|
59
|
+
+ info_event.__all__
|
|
60
|
+
+ line_info.__all__
|
|
61
|
+
+ line_request.__all__
|
|
62
|
+
+ line_settings.__all__
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# module methods/attributes
|
|
66
|
+
__all__ += [
|
|
67
|
+
"__version__",
|
|
68
|
+
"api_version",
|
|
69
|
+
"is_gpiochip_device",
|
|
70
|
+
"request_lines",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def is_gpiochip_device(path: str) -> bool:
|
|
75
|
+
"""
|
|
76
|
+
Check if the file pointed to by path is a GPIO chip character device.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
path
|
|
80
|
+
Path to the file that should be checked.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Returns true if so, False otherwise.
|
|
84
|
+
"""
|
|
85
|
+
return _ext.is_gpiochip_device(path)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def request_lines(
|
|
89
|
+
path: str,
|
|
90
|
+
config: dict[Union[Iterable[Union[int, str]], int, str], Optional[LineSettings]],
|
|
91
|
+
consumer: Optional[str] = None,
|
|
92
|
+
event_buffer_size: Optional[int] = None,
|
|
93
|
+
output_values: Optional[dict[Union[int, str], line.Value]] = None,
|
|
94
|
+
) -> LineRequest:
|
|
95
|
+
"""
|
|
96
|
+
Open a GPIO chip pointed to by 'path', request lines according to the
|
|
97
|
+
configuration arguments, close the chip and return the request object.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
path
|
|
101
|
+
Path to the GPIO character device file.
|
|
102
|
+
config:
|
|
103
|
+
Dictionary mapping offsets or names (or tuples thereof) to
|
|
104
|
+
LineSettings. If None is passed as the value of the mapping,
|
|
105
|
+
default settings are used.
|
|
106
|
+
consumer:
|
|
107
|
+
Consumer string to use for this request.
|
|
108
|
+
event_buffer_size:
|
|
109
|
+
Size of the kernel edge event buffer to configure for this request.
|
|
110
|
+
output_values:
|
|
111
|
+
Dictionary mapping offsets or names to line.Value. This can be used
|
|
112
|
+
to set the desired output values globally while reusing LineSettings
|
|
113
|
+
for more lines.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Returns a new LineRequest object.
|
|
117
|
+
"""
|
|
118
|
+
with Chip(path) as chip:
|
|
119
|
+
return chip.request_lines(
|
|
120
|
+
config=config,
|
|
121
|
+
consumer=consumer,
|
|
122
|
+
event_buffer_size=event_buffer_size,
|
|
123
|
+
output_values=output_values,
|
|
124
|
+
)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
|
+
# SPDX-FileCopyrightText: 2024 Vincent Fazio <vfazio@gmail.com>
|
|
3
|
+
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from .chip_info import ChipInfo
|
|
7
|
+
from .edge_event import EdgeEvent
|
|
8
|
+
from .info_event import InfoEvent
|
|
9
|
+
from .line import Value
|
|
10
|
+
from .line_info import LineInfo
|
|
11
|
+
|
|
12
|
+
class LineSettings:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
direction: int,
|
|
16
|
+
edge_detection: int,
|
|
17
|
+
bias: int,
|
|
18
|
+
drive: int,
|
|
19
|
+
active_low: bool,
|
|
20
|
+
debounce_period: int,
|
|
21
|
+
event_clock: int,
|
|
22
|
+
output_value: int,
|
|
23
|
+
) -> None: ...
|
|
24
|
+
|
|
25
|
+
class LineConfig:
|
|
26
|
+
def __init__(self) -> None: ...
|
|
27
|
+
def add_line_settings(self, offsets: list[int], settings: LineSettings) -> None: ...
|
|
28
|
+
def set_output_values(self, global_output_values: list[Value]) -> None: ...
|
|
29
|
+
|
|
30
|
+
class Request:
|
|
31
|
+
def release(self) -> None: ...
|
|
32
|
+
def get_values(self, offsets: list[int], values: list[Value]) -> None: ...
|
|
33
|
+
def set_values(self, values: dict[int, Value]) -> None: ...
|
|
34
|
+
def reconfigure_lines(self, line_cfg: LineConfig) -> None: ...
|
|
35
|
+
def read_edge_events(self, max_events: Optional[int]) -> list[EdgeEvent]: ...
|
|
36
|
+
@property
|
|
37
|
+
def chip_name(self) -> str: ...
|
|
38
|
+
@property
|
|
39
|
+
def num_lines(self) -> int: ...
|
|
40
|
+
@property
|
|
41
|
+
def offsets(self) -> list[int]: ...
|
|
42
|
+
@property
|
|
43
|
+
def fd(self) -> int: ...
|
|
44
|
+
|
|
45
|
+
class Chip:
|
|
46
|
+
def __init__(self, path: str) -> None: ...
|
|
47
|
+
def get_info(self) -> ChipInfo: ...
|
|
48
|
+
def line_offset_from_id(self, id: str) -> int: ...
|
|
49
|
+
def get_line_info(self, offset: int, watch: bool) -> LineInfo: ...
|
|
50
|
+
def request_lines(
|
|
51
|
+
self,
|
|
52
|
+
line_cfg: LineConfig,
|
|
53
|
+
consumer: Optional[str],
|
|
54
|
+
event_buffer_size: Optional[int],
|
|
55
|
+
) -> Request: ...
|
|
56
|
+
def read_info_event(self) -> InfoEvent: ...
|
|
57
|
+
def close(self) -> None: ...
|
|
58
|
+
def unwatch_line_info(self, line: int) -> None: ...
|
|
59
|
+
@property
|
|
60
|
+
def path(self) -> str: ...
|
|
61
|
+
@property
|
|
62
|
+
def fd(self) -> int: ...
|
|
63
|
+
|
|
64
|
+
def is_gpiochip_device(path: str) -> bool: ...
|
|
65
|
+
|
|
66
|
+
api_version: str
|
|
67
|
+
|
|
68
|
+
# enum constants
|
|
69
|
+
BIAS_AS_IS: int
|
|
70
|
+
BIAS_DISABLED: int
|
|
71
|
+
BIAS_PULL_DOWN: int
|
|
72
|
+
BIAS_PULL_UP: int
|
|
73
|
+
BIAS_UNKNOWN: int
|
|
74
|
+
CLOCK_HTE: int
|
|
75
|
+
CLOCK_MONOTONIC: int
|
|
76
|
+
CLOCK_REALTIME: int
|
|
77
|
+
DIRECTION_AS_IS: int
|
|
78
|
+
DIRECTION_INPUT: int
|
|
79
|
+
DIRECTION_OUTPUT: int
|
|
80
|
+
DRIVE_OPEN_DRAIN: int
|
|
81
|
+
DRIVE_OPEN_SOURCE: int
|
|
82
|
+
DRIVE_PUSH_PULL: int
|
|
83
|
+
EDGE_BOTH: int
|
|
84
|
+
EDGE_EVENT_TYPE_FALLING: int
|
|
85
|
+
EDGE_EVENT_TYPE_RISING: int
|
|
86
|
+
EDGE_FALLING: int
|
|
87
|
+
EDGE_NONE: int
|
|
88
|
+
EDGE_RISING: int
|
|
89
|
+
INFO_EVENT_TYPE_LINE_CONFIG_CHANGED: int
|
|
90
|
+
INFO_EVENT_TYPE_LINE_RELEASED: int
|
|
91
|
+
INFO_EVENT_TYPE_LINE_REQUESTED: int
|
|
92
|
+
VALUE_ACTIVE: int
|
|
93
|
+
VALUE_INACTIVE: int
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
# SPDX-License-Identifier:
|
|
1
|
+
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
2
|
# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
|
|
3
3
|
|
|
4
4
|
from datetime import timedelta
|
|
5
5
|
from select import select
|
|
6
6
|
from typing import Optional, Union
|
|
7
7
|
|
|
8
|
-
__all__ = []
|
|
8
|
+
__all__ = ["poll_fd"]
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def poll_fd(fd: int, timeout: Optional[Union[timedelta, float]] = None) -> bool:
|
|
12
|
+
sec: Union[float, None]
|
|
12
13
|
if isinstance(timeout, timedelta):
|
|
13
14
|
sec = timeout.total_seconds()
|
|
14
15
|
else:
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
2
|
# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
|
|
3
3
|
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
from collections import Counter
|
|
7
|
+
from errno import ENOENT
|
|
8
|
+
from typing import TYPE_CHECKING, Optional, Union, cast
|
|
9
|
+
|
|
4
10
|
from . import _ext
|
|
5
|
-
from .
|
|
11
|
+
from ._internal import poll_fd
|
|
6
12
|
from .exception import ChipClosedError
|
|
7
|
-
from .info_event import InfoEvent
|
|
8
|
-
from .internal import poll_fd
|
|
9
13
|
from .line import Value
|
|
10
|
-
from .line_info import LineInfo
|
|
11
|
-
from .line_settings import LineSettings, _line_settings_to_ext
|
|
12
14
|
from .line_request import LineRequest
|
|
13
|
-
from
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
from
|
|
17
|
-
from
|
|
15
|
+
from .line_settings import LineSettings, _line_settings_to_ext
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Iterable
|
|
19
|
+
from datetime import timedelta
|
|
20
|
+
from types import TracebackType
|
|
21
|
+
|
|
22
|
+
from .chip_info import ChipInfo
|
|
23
|
+
from .info_event import InfoEvent
|
|
24
|
+
from .line_info import LineInfo
|
|
18
25
|
|
|
19
|
-
__all__ = "Chip"
|
|
26
|
+
__all__ = ["Chip"]
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
class Chip:
|
|
@@ -32,7 +39,7 @@ class Chip:
|
|
|
32
39
|
Callers must close the chip by calling the close() method when it's no longer
|
|
33
40
|
used.
|
|
34
41
|
|
|
35
|
-
Example
|
|
42
|
+
Example::
|
|
36
43
|
|
|
37
44
|
chip = gpiod.Chip(\"/dev/gpiochip0\")
|
|
38
45
|
do_something(chip)
|
|
@@ -40,7 +47,7 @@ class Chip:
|
|
|
40
47
|
|
|
41
48
|
The gpiod.Chip class also supports controlled execution ('with' statement).
|
|
42
49
|
|
|
43
|
-
Example
|
|
50
|
+
Example::
|
|
44
51
|
|
|
45
52
|
with gpiod.Chip(path="/dev/gpiochip0") as chip:
|
|
46
53
|
do_something(chip)
|
|
@@ -54,8 +61,8 @@ class Chip:
|
|
|
54
61
|
path:
|
|
55
62
|
Path to the GPIO character device file.
|
|
56
63
|
"""
|
|
57
|
-
self._chip = _ext.Chip(path)
|
|
58
|
-
self._info = None
|
|
64
|
+
self._chip: Union[_ext.Chip, None] = _ext.Chip(path)
|
|
65
|
+
self._info: Union[ChipInfo, None] = None
|
|
59
66
|
|
|
60
67
|
def __bool__(self) -> bool:
|
|
61
68
|
"""
|
|
@@ -66,14 +73,19 @@ class Chip:
|
|
|
66
73
|
"""
|
|
67
74
|
return True if self._chip else False
|
|
68
75
|
|
|
69
|
-
def __enter__(self):
|
|
76
|
+
def __enter__(self) -> Chip:
|
|
70
77
|
"""
|
|
71
78
|
Controlled execution enter callback.
|
|
72
79
|
"""
|
|
73
80
|
self._check_closed()
|
|
74
81
|
return self
|
|
75
82
|
|
|
76
|
-
def __exit__(
|
|
83
|
+
def __exit__(
|
|
84
|
+
self,
|
|
85
|
+
exc_type: Optional[type[BaseException]],
|
|
86
|
+
exc_value: Optional[BaseException],
|
|
87
|
+
traceback: Optional[TracebackType],
|
|
88
|
+
) -> None:
|
|
77
89
|
"""
|
|
78
90
|
Controlled execution exit callback.
|
|
79
91
|
"""
|
|
@@ -89,7 +101,7 @@ class Chip:
|
|
|
89
101
|
longer be used after this method is called.
|
|
90
102
|
"""
|
|
91
103
|
self._check_closed()
|
|
92
|
-
self._chip.close()
|
|
104
|
+
cast(_ext.Chip, self._chip).close()
|
|
93
105
|
self._chip = None
|
|
94
106
|
|
|
95
107
|
def get_info(self) -> ChipInfo:
|
|
@@ -102,7 +114,7 @@ class Chip:
|
|
|
102
114
|
self._check_closed()
|
|
103
115
|
|
|
104
116
|
if not self._info:
|
|
105
|
-
self._info = self._chip.get_info()
|
|
117
|
+
self._info = cast(_ext.Chip, self._chip).get_info()
|
|
106
118
|
|
|
107
119
|
return self._info
|
|
108
120
|
|
|
@@ -127,7 +139,7 @@ class Chip:
|
|
|
127
139
|
|
|
128
140
|
if not isinstance(id, int):
|
|
129
141
|
try:
|
|
130
|
-
return self._chip.line_offset_from_id(id)
|
|
142
|
+
return cast(_ext.Chip, self._chip).line_offset_from_id(id)
|
|
131
143
|
except OSError as ex:
|
|
132
144
|
if ex.errno == ENOENT:
|
|
133
145
|
try:
|
|
@@ -146,7 +158,9 @@ class Chip:
|
|
|
146
158
|
|
|
147
159
|
def _get_line_info(self, line: Union[int, str], watch: bool) -> LineInfo:
|
|
148
160
|
self._check_closed()
|
|
149
|
-
return self._chip.get_line_info(
|
|
161
|
+
return cast(_ext.Chip, self._chip).get_line_info(
|
|
162
|
+
self.line_offset_from_id(line), watch
|
|
163
|
+
)
|
|
150
164
|
|
|
151
165
|
def get_line_info(self, line: Union[int, str]) -> LineInfo:
|
|
152
166
|
"""
|
|
@@ -184,7 +198,9 @@ class Chip:
|
|
|
184
198
|
Offset or name of the line to stop watching.
|
|
185
199
|
"""
|
|
186
200
|
self._check_closed()
|
|
187
|
-
return self._chip.unwatch_line_info(
|
|
201
|
+
return cast(_ext.Chip, self._chip).unwatch_line_info(
|
|
202
|
+
self.line_offset_from_id(line)
|
|
203
|
+
)
|
|
188
204
|
|
|
189
205
|
def wait_info_event(
|
|
190
206
|
self, timeout: Optional[Union[timedelta, float]] = None
|
|
@@ -218,11 +234,13 @@ class Chip:
|
|
|
218
234
|
This function may block if there are no available events in the queue.
|
|
219
235
|
"""
|
|
220
236
|
self._check_closed()
|
|
221
|
-
return self._chip.read_info_event()
|
|
237
|
+
return cast(_ext.Chip, self._chip).read_info_event()
|
|
222
238
|
|
|
223
239
|
def request_lines(
|
|
224
240
|
self,
|
|
225
|
-
config: dict[
|
|
241
|
+
config: dict[
|
|
242
|
+
Union[Iterable[Union[int, str]], int, str], Optional[LineSettings]
|
|
243
|
+
],
|
|
226
244
|
consumer: Optional[str] = None,
|
|
227
245
|
event_buffer_size: Optional[int] = None,
|
|
228
246
|
output_values: Optional[dict[Union[int, str], Value]] = None,
|
|
@@ -251,7 +269,7 @@ class Chip:
|
|
|
251
269
|
|
|
252
270
|
line_cfg = _ext.LineConfig()
|
|
253
271
|
|
|
254
|
-
# Sanitize lines - don't allow offset
|
|
272
|
+
# Sanitize lines - don't allow offset repetitions or offset-name conflicts.
|
|
255
273
|
for offset, count in Counter(
|
|
256
274
|
[
|
|
257
275
|
self.line_offset_from_id(line)
|
|
@@ -264,9 +282,7 @@ class Chip:
|
|
|
264
282
|
).items():
|
|
265
283
|
if count != 1:
|
|
266
284
|
raise ValueError(
|
|
267
|
-
"line must be configured exactly once - offset {} repeats"
|
|
268
|
-
offset
|
|
269
|
-
)
|
|
285
|
+
f"line must be configured exactly once - offset {offset} repeats"
|
|
270
286
|
)
|
|
271
287
|
|
|
272
288
|
# If we have global output values - map line names to offsets
|
|
@@ -312,7 +328,9 @@ class Chip:
|
|
|
312
328
|
if len(global_output_values):
|
|
313
329
|
line_cfg.set_output_values(global_output_values)
|
|
314
330
|
|
|
315
|
-
req_internal = self._chip.request_lines(
|
|
331
|
+
req_internal = cast(_ext.Chip, self._chip).request_lines(
|
|
332
|
+
line_cfg, consumer, event_buffer_size
|
|
333
|
+
)
|
|
316
334
|
request = LineRequest(req_internal)
|
|
317
335
|
|
|
318
336
|
request._chip_name = req_internal.chip_name
|
|
@@ -326,6 +344,12 @@ class Chip:
|
|
|
326
344
|
|
|
327
345
|
return request
|
|
328
346
|
|
|
347
|
+
def fileno(self) -> int:
|
|
348
|
+
"""
|
|
349
|
+
Return the underlying file descriptor.
|
|
350
|
+
"""
|
|
351
|
+
return self.fd
|
|
352
|
+
|
|
329
353
|
def __repr__(self) -> str:
|
|
330
354
|
"""
|
|
331
355
|
Return a string that can be used to re-create this chip object.
|
|
@@ -333,7 +357,7 @@ class Chip:
|
|
|
333
357
|
if not self._chip:
|
|
334
358
|
return "<Chip CLOSED>"
|
|
335
359
|
|
|
336
|
-
return 'gpiod.Chip("{}")'
|
|
360
|
+
return f'gpiod.Chip("{self.path}")'
|
|
337
361
|
|
|
338
362
|
def __str__(self) -> str:
|
|
339
363
|
"""
|
|
@@ -342,9 +366,7 @@ class Chip:
|
|
|
342
366
|
if not self._chip:
|
|
343
367
|
return "<Chip CLOSED>"
|
|
344
368
|
|
|
345
|
-
return '<Chip path="{}" fd={} info={}>'
|
|
346
|
-
self.path, self.fd, self.get_info()
|
|
347
|
-
)
|
|
369
|
+
return f'<Chip path="{self.path}" fd={self.fd} info={self.get_info()}>'
|
|
348
370
|
|
|
349
371
|
@property
|
|
350
372
|
def path(self) -> str:
|
|
@@ -352,7 +374,7 @@ class Chip:
|
|
|
352
374
|
Filesystem path used to open this chip.
|
|
353
375
|
"""
|
|
354
376
|
self._check_closed()
|
|
355
|
-
return self._chip.path
|
|
377
|
+
return cast(_ext.Chip, self._chip).path
|
|
356
378
|
|
|
357
379
|
@property
|
|
358
380
|
def fd(self) -> int:
|
|
@@ -360,4 +382,4 @@ class Chip:
|
|
|
360
382
|
File descriptor associated with this chip.
|
|
361
383
|
"""
|
|
362
384
|
self._check_closed()
|
|
363
|
-
return self._chip.fd
|
|
385
|
+
return cast(_ext.Chip, self._chip).fd
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
|
|
7
|
-
__all__ = "ChipInfo"
|
|
7
|
+
__all__ = ["ChipInfo"]
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
@dataclass(frozen=True, repr=False)
|
|
@@ -14,10 +14,13 @@ class ChipInfo:
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
name: str
|
|
17
|
+
"""Name of the chip."""
|
|
18
|
+
|
|
17
19
|
label: str
|
|
20
|
+
"""Label of the chip."""
|
|
21
|
+
|
|
18
22
|
num_lines: int
|
|
23
|
+
"""Number of lines exposed by the chip."""
|
|
19
24
|
|
|
20
|
-
def __str__(self):
|
|
21
|
-
return '<ChipInfo name="{}" label="{}" num_lines={}>'
|
|
22
|
-
self.name, self.label, self.num_lines
|
|
23
|
-
)
|
|
25
|
+
def __str__(self) -> str:
|
|
26
|
+
return f'<ChipInfo name="{self.name}" label="{self.label}" num_lines={self.num_lines}>'
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
2
2
|
# SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>
|
|
3
3
|
|
|
4
|
-
from . import _ext
|
|
5
4
|
from dataclasses import dataclass
|
|
6
5
|
from enum import Enum
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
from . import _ext
|
|
8
|
+
|
|
9
|
+
__all__ = ["EdgeEvent"]
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
@dataclass(frozen=True, init=False, repr=False)
|
|
@@ -15,14 +16,23 @@ class EdgeEvent:
|
|
|
15
16
|
"""
|
|
16
17
|
|
|
17
18
|
class Type(Enum):
|
|
19
|
+
"""Possible edge event types."""
|
|
20
|
+
|
|
18
21
|
RISING_EDGE = _ext.EDGE_EVENT_TYPE_RISING
|
|
22
|
+
"""Rising edge event."""
|
|
19
23
|
FALLING_EDGE = _ext.EDGE_EVENT_TYPE_FALLING
|
|
24
|
+
"""Falling edge event."""
|
|
20
25
|
|
|
21
26
|
event_type: Type
|
|
27
|
+
"""Edge event type."""
|
|
22
28
|
timestamp_ns: int
|
|
29
|
+
"""Timestamp of the event in nanoseconds."""
|
|
23
30
|
line_offset: int
|
|
31
|
+
"""Offset of the line on which this event was registered."""
|
|
24
32
|
global_seqno: int
|
|
33
|
+
"""Global sequence number of this event."""
|
|
25
34
|
line_seqno: int
|
|
35
|
+
"""Event sequence number specific to the concerned line."""
|
|
26
36
|
|
|
27
37
|
def __init__(
|
|
28
38
|
self,
|
|
@@ -38,8 +48,8 @@ class EdgeEvent:
|
|
|
38
48
|
object.__setattr__(self, "global_seqno", global_seqno)
|
|
39
49
|
object.__setattr__(self, "line_seqno", line_seqno)
|
|
40
50
|
|
|
41
|
-
def __str__(self):
|
|
42
|
-
return "<EdgeEvent type={} timestamp_ns={} line_offset={} global_seqno={} line_seqno={}>".format(
|
|
51
|
+
def __str__(self) -> str:
|
|
52
|
+
return "<EdgeEvent type={} timestamp_ns={} line_offset={} global_seqno={} line_seqno={}>".format( # noqa: UP032
|
|
43
53
|
self.event_type,
|
|
44
54
|
self.timestamp_ns,
|
|
45
55
|
self.line_offset,
|