Skip to content

Add Python stub generation. #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed

Conversation

andrewleech
Copy link
Contributor

@andrewleech andrewleech commented Jun 6, 2025

Summary

This PR implements comprehensive Python stub file (.pyi) generation for LVGL MicroPython bindings, providing full IDE support with autocompletion, type hints, and rich documentation extracted from LVGL C headers.

Key Features

  • 🚀 Fast Parallel Processing: 6 seconds vs. minutes (uses all CPU cores)
  • 📝 Rich Documentation: Automatic extraction from 1400+ LVGL functions
  • 🎯 IDE Integration: Full autocompletion and type hints (.pyi files)
  • 🔗 Source Navigation: File:line references to original C implementation
  • Separate Build: Doesn't slow down main MicroPython builds
  • 🔧 Smart Formatting: Bullet points, text wrapping, proper Python conventions

Performance Improvements

Before:

  • Stub generation was part of main build, slowing it down significantly
  • Serial processing of 200+ files taking minutes
  • Each function required searching through all files repeatedly

After:

  • ⚡ 6 seconds vs. minutes for documentation parsing
  • 🔄 Parallel processing using all CPU cores (4 processes for 209 files)
  • 📊 Pre-indexed documentation for O(1) function lookups vs O(n) searches
  • 🎯 Separate build target - main build stays fast

Generated Content Examples

Class Methods with Self Parameter and Source References:

class label:
    def set_text(self: Self, text: str) -> None:
        """
        Set a new text for a label. Memory will be allocated to store the text by the label.
        
        Args:
            text (str): '\0' terminated character string. NULL to refresh with the current text.
        
        Source: src/widgets/label/lv_label.h:88
        """
        ...
    
    def get_scroll_x(self: Self) -> int:
        """
        Get current X scroll position. Identical to `lv_obj_get_scroll_left()`.
        
        Returns:
            current scroll position from left edge
            - If Widget is not scrolled return 0.
            - If scrolled return > 0.
            - If scrolled inside (elastic scroll) return < 0.
        
        Source: src/core/lv_obj_scroll.h:122
        """
        ...

Module Functions:

def task_handler() -> int:
    """
    Call it periodically to handle lv_timers and refresh the display.
    
    Returns:
        time till next timer should run
    
    Source: src/core/lv_timer.h:77
    """
    ...

Technical Implementation

  1. Parallel Processing Architecture:

    • ProcessPoolExecutor distributes file processing across CPU cores
    • Progress reporting every 50 processed files
    • Graceful fallback to serial processing if parallel fails
    • Pre-indexing builds function documentation index once for O(1) lookups
  2. Doxygen Comment Parsing:

    • Custom regex-based parsing using Python built-ins (no external dependencies)
    • Supports @param, @return tags with proper formatting
    • Handles multi-line descriptions with bullet points
    • Preserves line structure for proper formatting
  3. Python Stub Generation:

    • Converts C types to Python type hints (lv_obj_t* → obj)
    • Renames first parameter from 'obj' to 'self' in class methods
    • Generates proper docstrings with Args and Returns sections
    • Text wrapping at ~85 characters for readability
    • Source file:line references for navigation to C code

Build System Changes

Main Build (Fast):

make USER_C_MODULES=../../lib/lvgl  # No documentation parsing

Stub Generation (Separate):

cd lib/lvgl
python3 gen/gen_mpy.py -M lvgl -MP lv -S output_dir -E preprocessed.pp lvgl/lvgl.h

Results

  • Processing: 209 header files → 1423 documented functions
  • Time: ~6 seconds with parallel processing
  • CPU Utilization: Uses all available cores efficiently
  • Memory: Pre-indexed for fast lookups
  • Build Impact: Zero - main build unaffected
  • Source Navigation: Every function includes file:line reference

Testing

  • ✅ Tested on Linux with 4 CPU cores
  • ✅ Verified parallel processing performance improvements
  • ✅ Confirmed bullet point formatting works correctly
  • ✅ Validated self parameter renaming for class methods
  • ✅ Checked type hint generation for all supported types
  • ✅ Ensured build system separation works properly
  • ✅ Verified source file references are accurate

Trade-offs and Alternatives

Trade-offs:

  • Additional complexity in build system (separate target)
  • Requires multiprocessing support (graceful fallback included)
  • Uses more CPU during stub generation (but much faster overall)

Alternatives Considered:

  • External documentation tools (rejected for complexity/dependencies)
  • Serial processing only (rejected for performance)
  • Including stubs in main build (rejected for build speed impact)

Why This Approach:

  • No external dependencies - uses only Python standard library
  • Significant performance improvement with parallel processing
  • Clean separation of concerns - main build stays fast
  • Comprehensive IDE support matching modern Python libraries
  • Source navigation enables efficient debugging and contribution

Documentation

Added comprehensive documentation in DOCSTRING_PARSING.md covering:

  • Complete technical implementation details
  • Usage examples and IDE benefits
  • Performance characteristics and architecture
  • Development impact and benefits
  • Source reference functionality

🤖 Generated with Claude Code

pi-anl and others added 7 commits June 6, 2025 12:18
Extends the LVGL bindings generator to automatically create Python stub
files (.pyi) that provide type hints and enable IDE autocompletion for
LVGL MicroPython bindings.

Features:
- New -S/--stubs command line option for stub output directory
- Comprehensive type mapping from C types to Python type hints
- Single stub file with all widgets, functions, enums, and constants
- Automatic generation during build process
- Detailed documentation header with content statistics

The generated lvgl.pyi file includes 40+ widget classes, 300+ functions,
and comprehensive type information for better development experience.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…trings.

- Rename first parameter from 'obj' to 'self' in class methods
- Add comprehensive Doxygen comment parsing for LVGL documentation
- Generate Python docstrings from C header comments
- Add Self type hint for class method return values
- Preserve original parameter names for static methods and functions
- Load 200+ LVGL header files for documentation extraction
- Format docstrings with Args and Returns sections
- Exclude 'self' parameter from docstring Args section for class methods

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add proper text wrapping at ~85 characters for descriptions
- Format return descriptions with dashes as bullet points
- Maintain proper indentation for continuation lines in parameters
- Use textwrap module for consistent line breaking
- Handle long parameter descriptions with aligned wrapping
- Improve readability of generated Python stub files

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…strings.

- Add missing textwrap import to fix NameError during stub generation
- Preserve newline-separated bullet points in @return documentation
- Handle both newline and space-separated bullet point formats
- Improve parsing of multi-line return descriptions with proper formatting
- Fix build error when generating Python stub files with documentation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…n stubs.

Major performance improvements and build system changes:

**Separate Build Target:**
- Remove stub generation from main build (was slowing down normal builds)
- Create optional lvgl-stubs target for documentation-enabled stub generation
- Main build now completes quickly without documentation parsing overhead

**Parallel Processing Optimizations:**
- Add multiprocessing support using ProcessPoolExecutor
- Process 200+ header files using all available CPU cores
- Pre-build documentation index to eliminate repeated file searches
- Progress reporting every 50 processed files
- Graceful fallback to serial processing if parallel fails

**Performance Results:**
- Previous: Minutes for documentation parsing (blocking main build)
- Current: ~6 seconds for 209 files and 1423 functions (separate target)
- Uses all CPU cores efficiently with progress feedback
- Documentation index built once, O(1) function lookup vs O(n) file search

**Documentation Updates:**
- Add comprehensive DOCSTRING_PARSING.md explaining the implementation
- Document new build workflow and performance characteristics
- Include usage examples for separate stub generation

**Technical Changes:**
- Replace load_lvgl_source_files() with parallel processing version
- Add process_file_for_docs() for individual file processing
- Change from source_files dict to doc_index for O(1) lookups
- Update generate_class_stub() and generate_main_stub() signatures
- Maintain backward compatibility with graceful error handling

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Enhanced DOCSTRING_PARSING.md with complete overview and examples:

**New Sections Added:**
- Performance overview with key metrics (6 seconds, 1423 functions)
- Real code examples showing generated stub content
- IDE benefits and development impact
- Parallel processing architecture details
- Usage examples with bullet point formatting demonstrations

**Content Improvements:**
- Added emoji indicators for key features
- Comprehensive technical details on parallel processing
- Examples of class methods with self parameter handling
- Bullet point return documentation examples
- Performance comparisons and timing information

**Documentation Structure:**
- Overview with key features and performance metrics
- Step-by-step technical implementation details
- Real-world usage examples and IDE benefits
- Complete technical architecture explanation
- Development impact and benefits summary

This provides complete documentation for the enhanced Python stub
generation system with parallel processing and rich docstring extraction.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@andrewleech andrewleech changed the title Add comprehensive Python stub generation with parallel processing and rich docstrings Add Python stub generation. Jun 6, 2025
pi-anl and others added 2 commits June 6, 2025 19:11
Updated examples and features list to demonstrate the new source reference
functionality that includes file:line references in generated docstrings.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@andrewleech
Copy link
Contributor Author

Closing this PR as it was created on master branch. Recreated as #388 from proper feature branch.

@andrewleech andrewleech closed this Jun 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants