You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For ANY changes to C++ interface files (native/src/*, native/include/*, pyhelios_build/*), ctypes wrappers, or core functionality, you MUST complete this verification sequence:
439
439
440
440
1.**Full Native Rebuild**: Run `build_scripts/build_helios --clean` to rebuild from scratch
441
-
2.**Complete Test Suite**: Run `pytest` (not individual tests) to verify ALL tests pass
441
+
2.**Complete Test Suite**: Run `pytest` (uses subprocess isolation for robust testing) to verify ALL tests pass
442
442
3.**Zero Tolerance**: Any failing tests must be fixed before declaring success
443
443
4.**No Shortcuts**: Never skip the full test suite even if "individual tests pass"
444
444
445
445
This protocol is NON-NEGOTIABLE and must be completed regardless of time constraints or apparent simplicity of changes.
446
446
447
+
**Note**: PyHelios uses pytest-forked for subprocess isolation, preventing ctypes contamination and ensuring reliable test results across all test execution patterns.
448
+
447
449
**GitHub CI/CD Integration:**
448
450
- Comprehensive CI/CD workflows test PyHelios across all platforms
449
451
- Quick tests (`test-quick.yml`) for fast development feedback
@@ -460,17 +462,20 @@ This protocol is NON-NEGOTIABLE and must be completed regardless of time constra
460
462
-**Platform detection**: Use `from pyhelios.plugins import get_plugin_info` to check current status and library availability
461
463
462
464
**Testing and Development Workflow:**
463
-
-**Comprehensive test suite**: 86 passing tests, 60 properly skipped, zero failures/errors/warnings
465
+
-**Comprehensive test suite**: 477 passing tests, 70 properly skipped, zero failures/errors/warnings
466
+
-**Subprocess isolation**: pytest-forked prevents ctypes contamination and state interference between tests
464
467
-**Cross-platform testing**: Run `pytest` on any platform - tests automatically adapt to available libraries
465
468
-**Mock mode development**: Develop and test PyHelios functionality without requiring native library compilation
466
469
-**Test categories**: Use `pytest -m cross_platform` for platform-independent tests, `pytest -m native_only` for native library tests
470
+
-**Robust test execution**: Tests pass consistently whether run individually or as part of full suite
467
471
468
472
**MANDATORY: Final Verification Checklist**
469
473
Before declaring ANY task complete involving C++/Python interface changes:
470
474
□ Built native libraries from scratch using `build_scripts/build_helios --clean`
471
-
□ Ran complete `pytest` suite (not selective tests)
475
+
□ Ran complete `pytest` suite (automatically uses subprocess isolation)
472
476
□ All tests pass with zero failures
473
-
□ No regressions introduced in any module
477
+
□ No regressions introduced in any module
478
+
□ Test session shows "plugins: forked-X.X.X" confirming subprocess isolation is active
474
479
□ Changes committed to git if task involves file modifications
475
480
476
481
Failure to complete this checklist constitutes incomplete task execution.
- Tests pass when run with `pytest tests/test_yourplugin.py -v`
1790
1790
- Same tests fail when run with `pytest` (full suite)
1791
1791
- Import-related failures with class identity mismatches
1792
-
- Error messages like `AssertionError: False = issubclass(...)`
1792
+
- Error messages like `AssertionError: False = issubclass(...)` or ctypes pointer type mismatches
1793
+
- Error messages like `expected LP_UContext instance instead of LP_UContext`
1793
1794
1794
-
**Root Causes Identified**:
1795
-
1.**Global Plugin Registry State**: Plugin registry singleton persists contaminated state across test modules
1796
-
2.**Import Path Inconsistencies**: Different import paths for error classes cause class identity issues
1797
-
3.**Context Validation Issues**: `isinstance()` checks fail due to class identity problems during module reloading
1795
+
**Root Cause Identified**:
1796
+
**ctypes Structure Type Identity Problem** - This is a well-documented limitation of ctypes where identical Structure classes are treated as different types when redefined during pytest module reloading. When pytest reloads modules, ctypes sees "new" pointer types (like `LP_UContext`) as incompatible with "old" ones, even when they have identical memory layout and field definitions.
1798
1797
1799
-
**PERMANENT SOLUTION IMPLEMENTED** (v0.0.7+):
1798
+
**PERMANENT SOLUTION IMPLEMENTED** (v0.1.0+):
1800
1799
1801
-
**1. Enhanced Test Fixture Architecture** (`conftest.py` - already fixed):
1800
+
**pytest-forked for Complete Test Isolation** - The definitive solution to prevent ctypes contamination by running each test in a separate subprocess:
1801
+
1802
+
```bash
1803
+
# Installation (automatically included in development dependencies)
1804
+
pip install pytest-forked>=1.6.0
1805
+
1806
+
# Automatic usage via pytest.ini configuration
1807
+
pytest # Now uses --forked by default
1808
+
```
1809
+
1810
+
This solution:
1811
+
- ✅ Completely eliminates ctypes type contamination between tests
1812
+
- ✅ Provides clean module state for each test execution
1813
+
- ✅ Works across all platforms (Windows, macOS, Linux)
1814
+
- ✅ Maintains test performance (minimal subprocess overhead)
1815
+
- ✅ Requires no code changes to PyHelios plugins
1816
+
- ✅ Prevents ALL forms of test state contamination, not just ctypes
1817
+
1818
+
**Alternative Solutions** (Legacy - for reference):
1819
+
1820
+
**1. Enhanced Test Fixture Architecture** (`conftest.py` - legacy approach):
0 commit comments