Skip to content

Commit 0e8f6ea

Browse files
committed
gen: Implement separate stub generation system.
Refactor Python stub generation into dedicated module system: - Create gen_stubs.py: Standalone script for generating Python type stubs - Create gen_utils.py: Shared utilities between gen_mpy.py and gen_stubs.py - Update gen_mpy.py: Remove stub generation code, import shared utilities - Update pyproject.toml: Remove setuptools-scm, use __version__.py approach The new system generates complete Python type stubs with: - All LVGL widget classes with proper typing - Function signatures with parameter names and types - Enum definitions and constants - Documentation extracted from C headers - Validation to ensure stub-API consistency Signed-off-by: Andrew Leech <[email protected]>
1 parent f8918f4 commit 0e8f6ea

File tree

9 files changed

+4928
-719
lines changed

9 files changed

+4928
-719
lines changed

README.md

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,9 @@ Here is a procedure for adding lvgl to an existing MicroPython project. (The exa
220220
### gen_mpy.py syntax
221221
```
222222
usage: gen_mpy.py [-h] [-I <Include Path>] [-D <Macro Name>]
223-
[-E <Preprocessed File>] [-M <Module name string>]
224-
[-MP <Prefix string>] [-MD <MetaData File Name>]
223+
[-E <Preprocessed File>] [-J <JSON file>]
224+
[-M <Module name string>] [-MP <Prefix string>]
225+
[-MD <MetaData File Name>]
225226
input [input ...]
226227
227228
positional arguments:
@@ -236,6 +237,9 @@ optional arguments:
236237
-E <Preprocessed File>, --external-preprocessing <Preprocessed File>
237238
Prevent preprocessing. Assume input file is already
238239
preprocessed
240+
-J <JSON file>, --lvgl-json <JSON file>
241+
Provde a JSON from the LVGL JSON generator for missing
242+
information
239243
-M <Module name string>, --module_name <Module name string>
240244
Module name
241245
-MP <Prefix string>, --module_prefix <Prefix string>
@@ -244,12 +248,38 @@ optional arguments:
244248
Optional file to emit metadata (introspection)
245249
```
246250

247-
Example:
251+
Example for gen_mpy.py:
248252

249253
```
250254
python gen_mpy.py -MD lv_mpy_example.json -M lvgl -MP lv -I../../berkeley-db-1.xx/PORT/include -I../../lv_binding_micropython -I. -I../.. -Ibuild -I../../mp-readline -I ../../lv_binding_micropython/pycparser/utils/fake_libc_include ../../lv_binding_micropython/lvgl/lvgl.h
251255
```
252256

257+
258+
### gen_stubs.py syntax
259+
```
260+
usage: gen_stubs.py [-h] --metadata METADATA --stubs-dir STUBS_DIR
261+
[--lvgl-dir LVGL_DIR] [--module-name MODULE_NAME]
262+
[--validate]
263+
264+
Generate LVGL Python stub files
265+
266+
options:
267+
-h, --help show this help message and exit
268+
--metadata METADATA JSON metadata file from gen_mpy.py
269+
--stubs-dir STUBS_DIR
270+
Output directory for stub files
271+
--lvgl-dir LVGL_DIR LVGL source directory for documentation
272+
--module-name MODULE_NAME
273+
Module name
274+
--validate Enable validation checks
275+
```
276+
277+
Example for gen_stubs.py:
278+
279+
```
280+
python gen_stubs.py --metadata lv_mpy_example.json --stubs-dir ./stubs-output --lvgl-dir ../lvgl --module-name lvgl --validate
281+
```
282+
253283
### Binding other C libraries
254284

255285
The lvgl binding script can be used to bind other C libraries to MicroPython.
@@ -528,7 +558,7 @@ pip install -e /path/to/lv_binding_micropython/stubs
528558
After building and packaging:
529559

530560
```bash
531-
pip install lvgl-stubs
561+
pip install lvgl_stubs
532562
```
533563

534564
### Features
@@ -543,30 +573,60 @@ Once installed, your IDE will automatically provide:
543573

544574
### Building Stubs
545575

546-
The stubs are automatically generated when running the binding generation:
576+
The stubs are generated using a separate `gen_stubs.py` module that creates both stub files and distributable wheel packages. Two make targets are available:
547577

548578
```bash
549-
# Build with automatic stub generation
550-
make USER_C_MODULES=/path/to/lv_binding_micropython/micropython.cmake
579+
# Generate stub files only
580+
make USER_C_MODULES=/path/to/lv_binding_micropython LVGL_STUBS
581+
582+
# Generate stub files and build distributable wheel package
583+
make USER_C_MODULES=/path/to/lv_binding_micropython LVGL_STUBS_WHEEL
584+
```
551585

552-
# Or generate stubs manually
586+
You can also generate stubs manually:
587+
588+
```bash
553589
cd gen
554-
python gen_mpy.py --stubs /path/to/output/dir [other options...]
590+
python gen_stubs.py --metadata /path/to/metadata.json --stubs-dir /path/to/output/dir --lvgl-dir /path/to/lvgl --module-name lvgl --validate
555591
```
556592

593+
### Build Process
594+
595+
The stub package generation uses a template-based approach:
596+
597+
1. **Template Folder**: The `./stubs/` directory contains a complete Python package template with:
598+
- `pyproject.toml` - Package configuration
599+
- `lvgl_stubs/` - Python package directory
600+
- `lvgl_stubs/__init__.py` - Package initialization
601+
- `lvgl_stubs/py.typed` - Marks package as typed
602+
603+
2. **Build Process**: During build, the template is copied to the build directory, then:
604+
- LVGL version is extracted from headers (`lv_version.h`)
605+
- `__version__.py` file is created with the extracted version
606+
- `lvgl.pyi` stub file is generated with all type definitions
607+
- Documentation is extracted from 200+ LVGL header files in parallel
608+
- Validation ensures stubs match the generated MicroPython API
609+
610+
3. **Package Creation**: The build process creates a distributable wheel package (`lvgl_stubs-X.Y.Z-py3-none-any.whl`) that can be installed with pip.
611+
612+
### Generated Content
613+
557614
The generated `lvgl.pyi` stub file contains type definitions for:
558615
- All LVGL widget classes (buttons, labels, sliders, etc.)
559616
- Module-level functions and constants
560617
- Enum definitions with proper typing
561618
- Struct types with documented fields
562619
- Callback function signatures
563620

621+
Documentation is automatically extracted from LVGL C headers using Doxygen-style comment parsing, providing rich IDE tooltips and help text.
622+
564623
### Package Structure
565624

566-
The stubs are packaged in `stubs/` directory with:
567-
- `pyproject.toml` - Package configuration with setuptools-scm versioning
568-
- `lvgl-stubs/` - Python package containing type stubs
569-
- `lvgl-stubs/__init__.py` - Package initialization
570-
- `lvgl-stubs/py.typed` - Marks package as typed
571-
- `lvgl-stubs/lvgl.pyi` - Generated type stubs (git-ignored)
625+
The stubs are packaged in `stubs/` template directory with:
626+
- `pyproject.toml` - Package configuration with dynamic versioning
627+
- `lvgl_stubs/` - Python package containing type stubs
628+
- `lvgl_stubs/__init__.py` - Package initialization with version import
629+
- `lvgl_stubs/py.typed` - Marks package as typed
630+
- `lvgl_stubs/__version__.py` - Version file (generated during build)
631+
- `lvgl_stubs/lvgl.pyi` - Generated type stubs (created during build)
572632

0 commit comments

Comments
 (0)