This patch series employs mypy [0] and ruff [1] to ensure the gpiod library has correctly typed public interfaces, is performing proper type checking internally, is consistently formatted in a standard code style that targets Python 3.9 syntax, and passes a subset of linting checks. Patches 1 and 2 remove unused imports, sort and guard the remainder, and ensure the publicly usable classes are available from the gpiod module. Patches 3-5 fix and add type hints to callable interfaces. Patches 6-14 fix type and lint errors internal to the bindings. Patch 15 fixes a duplicate test name identified by the linter. Patch 16 and 17 remove unused imports, sort the remainder, and fix lint errors related to a shadowed export. Patches 18 and 19 fix and add type hints to callable interfaces within the tests. Patches 20-22 fix type and lint errors internal to the tests. Patch 23 adds mypy and ruff configuration to pyproject.toml and adds documentation to the readme so future patches can be evaluated against a standard set of rules. There should be no functional changes that impact existing code as part of this series. All unit tests continue to pass without changes and code coverage has not changed. After this series is applied, the public type annotations will reflect the argument expectations of the class methods so consumers can type check their code against the gpiod type annotations. v2 changes (mostly feedback from Bartosz): - Added/expanded commit messages - Commit to raise exception classes has been dropped - A few changes have been split to separate commits - Line objects are no longer directly exported from the gpiod module - A couple of public APIs now have loosened type requirements - casting has been reworked for Chip and LineRequest classes - additional strings are now f-strings - imports used only for type checking are behind a type check guard - tests: type hints have been reworked to be less noisy [0]: https://mypy.readthedocs.io/en/stable/ [1]: https://docs.astral.sh/ruff/ Vincent Fazio (23): bindings: python: clean up imports and exports bindings: python: make internal a private submodule bindings: python: loosen type requirements in public API bindings: python: explicitly type gpiod.request_lines bindings: python: add type stub for the _ext module bindings: python: add missing method type hints bindings: python: add type hint for the sec variable in poll_fd bindings: python: add type hints for Chip's internal members bindings: python: fix Chip union-attr type errors bindings: python: add type hints for LineRequest's internal members bindings: python: fix LineRequest union-attr type errors bindings: python: convert lines to offsets in LineRequest bindings: python: cast return value of LineRequest.get_values bindings: python: selectively use f-strings bindings: python: tests: fix duplicate test name bindings: python: tests: clean up imports and exports bindings: python: tests: make EventType private to prevent export bindings: python: tests: add type stubs for external modules bindings: python: tests: add missing method type hints bindings: python: tests: add type hints to internal members bindings: python: tests: ignore purposeful type errors bindings: python: tests: selectively use f-strings bindings: python: configure and document dev dependencies bindings/python/README.md | 17 ++ bindings/python/gpiod/__init__.py | 83 ++++++- bindings/python/gpiod/_ext.pyi | 93 ++++++++ .../gpiod/{internal.py => _internal.py} | 3 +- bindings/python/gpiod/chip.py | 80 ++++--- bindings/python/gpiod/chip_info.py | 8 +- bindings/python/gpiod/edge_event.py | 9 +- bindings/python/gpiod/exception.py | 4 +- bindings/python/gpiod/info_event.py | 13 +- bindings/python/gpiod/line.py | 5 +- bindings/python/gpiod/line_info.py | 10 +- bindings/python/gpiod/line_request.py | 90 ++++---- bindings/python/gpiod/line_settings.py | 15 +- bindings/python/pyproject.toml | 36 +++ bindings/python/setup.py | 2 +- bindings/python/tests/__init__.py | 6 +- bindings/python/tests/__main__.py | 5 +- bindings/python/tests/gpiosim/__init__.py | 2 + bindings/python/tests/gpiosim/_ext.pyi | 21 ++ bindings/python/tests/gpiosim/chip.py | 3 +- bindings/python/tests/helpers.py | 17 +- bindings/python/tests/procname/__init__.py | 2 + bindings/python/tests/procname/_ext.pyi | 1 + bindings/python/tests/tests_chip.py | 99 +++++---- bindings/python/tests/tests_chip_info.py | 31 +-- bindings/python/tests/tests_edge_event.py | 60 ++--- bindings/python/tests/tests_info_event.py | 81 +++---- bindings/python/tests/tests_line.py | 5 +- bindings/python/tests/tests_line_info.py | 40 ++-- bindings/python/tests/tests_line_request.py | 210 +++++++++--------- bindings/python/tests/tests_line_settings.py | 19 +- bindings/python/tests/tests_module.py | 37 ++- 32 files changed, 691 insertions(+), 416 deletions(-) create mode 100644 bindings/python/gpiod/_ext.pyi rename bindings/python/gpiod/{internal.py => _internal.py} (90%) create mode 100644 bindings/python/tests/gpiosim/_ext.pyi create mode 100644 bindings/python/tests/procname/_ext.pyi -- 2.34.1