Migrate Vector component from ctypes to SWIG bindings with backward compatibility
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.pyfor SWIG extension building - Updated
.gitignorefor 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.