Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Jul 13, 2025

This PR implements the first step in gradually migrating graphserver's hand-made Python bindings from ctypes to SWIG, starting with the Vector component. The migration maintains 100% backward compatibility while establishing a pattern for future component migrations.

Problem

The current Python bindings use hand-crafted ctypes wrappers that are:

  • More complex to maintain and debug
  • Less performant than native SWIG bindings
  • Prone to memory management issues
  • Harder to extend with new functionality

Solution

Implemented a hybrid approach that uses SWIG internally while preserving the ctypes interface:

Key Changes

1. SWIG Interface Definition (core/vector.i)

  • Created comprehensive SWIG interface for Vector C structure
  • Embedded C implementation to avoid linking complexities
  • Added proper typemaps for Python integer to void pointer conversion

2. SWIG Vector Wrapper (pygs/graphserver/vector_swig.py)

  • Python wrapper providing same interface as ctypes version
  • Automatic memory management through SWIG
  • Proper out-of-bounds handling matching ctypes behavior

3. Hybrid Vector Class (pygs/graphserver/vector.py)

  • Modified main Vector class to use SWIG internally when available
  • Maintains ctypes Structure compatibility for dependent components
  • Seamless fallback to original ctypes implementation
  • Synchronized field access between backends

4. Build System Updates

  • Added SWIG requirement to pyproject.toml
  • Created setup.py for SWIG extension building
  • Updated .gitignore for SWIG-generated files

Example Usage

from graphserver.vector import Vector

# Same interface as before
vec = Vector(init_size=10, expand_delta=5)
vec.add(42)
vec.add(100)
print(vec.get(0))  # 42
print(vec.num_elements)  # 2

# Still works as ctypes Structure for other components
from ctypes import POINTER
ptr_type = POINTER(Vector)  # ✅ Works

Benefits

  • Zero Breaking Changes: All 188 existing tests pass without modification
  • Performance: SWIG provides more efficient C bindings than ctypes
  • Type Safety: Better type checking and automatic conversions
  • Memory Management: Automatic cleanup of C resources
  • Gradual Migration: Pattern established for migrating other components
  • Robustness: Graceful fallback when SWIG unavailable

Testing

  • ✅ All 188 unit tests continue to pass
  • ✅ Vector-specific functionality thoroughly validated
  • ✅ Both SWIG and ctypes backends tested for compatibility
  • ✅ Integration with dependent components verified

Future Work

This establishes the migration pattern for other components:

  • State management classes
  • Edge payload types
  • Graph structures
  • Service calendar components

The hybrid approach allows incremental migration while maintaining system stability throughout the process.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

- Create SWIG interface for Vector component (core/vector.i)
- Implement SWIG-based Vector wrapper with ctypes compatibility
- Modify main Vector class to use SWIG internally while maintaining ctypes interface
- Add hybrid approach supporting both SWIG and ctypes backends
- Update build system and gitignore for SWIG support
- All 188 tests continue to pass without modification
- Establish pattern for gradual migration of other components

Co-authored-by: bmander <[email protected]>
@Copilot Copilot AI changed the title [WIP] Let's gradually port the hand made pygs python bindings over to SWIG. Pick a single component to port over. Make sure all the tests keep passing Migrate Vector component from ctypes to SWIG bindings with backward compatibility Jul 13, 2025
Copilot finished work on behalf of bmander July 13, 2025 23:04
@Copilot Copilot AI requested a review from bmander July 13, 2025 23:04
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