cargo test fails when using a uv-managed virtual environment. The README documents workarounds for extension-module linking and pyenv shared libraries, but uv's thin venvs introduce a different chain of issues:
- pyo3 doesn't find the venv Python: Without VIRTUAL_ENV or PYO3_PYTHON set, pyo3 discovers the system Python (which may be a different version and lack numpy/pandas).
- Test binary can't find libpython: Even with PYO3_PYTHON pointing at the venv, the compiled test binary fails at runtime with libpython3.x.so: cannot open shared object file. uv installs Python to its own managed location, so LD_LIBRARY_PATH must point there.
- Embedded Python can't find stdlib: After solving the linking, Python fails with Could not find platform dependent libraries / No module named 'encodings', because uv venvs are thin (they symlink to a uv-managed Python install rather than containing stdlib). PYTHONHOME must be
set to sys.base_prefix of the uv-managed Python.
The full workaround requires setting three environment variables before cargo test:
VENV_PYTHON=".venv/bin/python"
PYTHON_PREFIX=$($VENV_PYTHON -c "import sys; print(sys.base_prefix)")
PYTHON_VERSION=$($VENV_PYTHON -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")
PYO3_PYTHON=$VENV_PYTHON \
LD_LIBRARY_PATH="$PYTHON_PREFIX/lib" \
PYTHONHOME="$PYTHON_PREFIX" \
PYTHONPATH=".venv/lib/python$PYTHON_VERSION/site-packages" \
cargo test
The integration tests in tests/ use pyo3's auto-initialize to embed a Python interpreter inside Rust test binaries. This works when the system Python is straightforward, but is inherently fragile with modern Python managers (uv, potentially others) that use thin/symlinked venvs.
The tests are round-tripping through Python to test what are fundamentally Python-level concerns - input type coercion (lists, dicts, iterators, numpy arrays, pandas DataFrames) and the pyo3 binding layer. The actual financial math in src/core/ is pure Rust and already has its own unit tests.
Suggested fix:
Port the integration tests from Rust (tests/.rs with auto-initialize) to Python (tests/.py with pytest). This gives two clean testing tiers:
- cargo test - pure Rust, tests the financial math in src/core/, no Python dependency, works everywhere
- maturin develop && pytest - tests the bindings from Python, running in a normal Python process where numpy/pandas are naturally available
This eliminates the need for auto-initialize, the PYO3_PYTHON/LD_LIBRARY_PATH/PYTHONHOME workarounds, and any platform-specific runner scripts. I have a working port if this direction is agreeable.
cargo test fails when using a uv-managed virtual environment. The README documents workarounds for extension-module linking and pyenv shared libraries, but uv's thin venvs introduce a different chain of issues:
set to sys.base_prefix of the uv-managed Python.
The full workaround requires setting three environment variables before cargo test:
The integration tests in tests/ use pyo3's auto-initialize to embed a Python interpreter inside Rust test binaries. This works when the system Python is straightforward, but is inherently fragile with modern Python managers (uv, potentially others) that use thin/symlinked venvs.
The tests are round-tripping through Python to test what are fundamentally Python-level concerns - input type coercion (lists, dicts, iterators, numpy arrays, pandas DataFrames) and the pyo3 binding layer. The actual financial math in src/core/ is pure Rust and already has its own unit tests.
Suggested fix:
Port the integration tests from Rust (tests/.rs with auto-initialize) to Python (tests/.py with pytest). This gives two clean testing tiers:
This eliminates the need for auto-initialize, the PYO3_PYTHON/LD_LIBRARY_PATH/PYTHONHOME workarounds, and any platform-specific runner scripts. I have a working port if this direction is agreeable.