name: Python
on:
push:
branches: [main, master]
paths:
- "**.py"
- "**.rs"
- "**.ipynb"
- "docs/**"
- "README.md"
- "pyproject.toml"
- "Cargo.toml"
- ".github/workflows/pytest.yml"
- "pytest.ini"
pull_request:
paths:
- "**.py"
- "**.rs"
- "**.ipynb"
- "docs/**"
- "README.md"
- "pyproject.toml"
- "Cargo.toml"
- ".github/workflows/pytest.yml"
- "pytest.ini"
workflow_dispatch:
jobs:
python-tests:
name: Python ${{ matrix.python-version }} (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
key: test-${{ matrix.os }}-${{ matrix.python-version }}
- name: Setup dependencies
uses: ./.github/actions/setup-dependencies
with:
python-version: ${{ matrix.python-version }}
enable-gstreamer: "true"
os: ${{ matrix.os }}
- name: Set up Rust
uses: dtolnay/rust-toolchain@nightly
- name: Install maturin
run: uv pip install maturin>=1.7.4
- name: Build Rust extension
run: |
# Build with platform-appropriate features
# Cargo.toml has platform-specific dependencies for Unix (HDF5, tracing)
uv run maturin develop --release
shell: bash
- name: Install Python dependencies
run: |
# On macOS, build h5py from source to ensure compatibility with system HDF5
if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
export HDF5_DIR="${HDF5_DIR}"
uv pip install --no-binary h5py "h5py>=3.8.0"
fi
# Install extra dependencies (evlib already installed by maturin develop above)
# This will only install the dependencies from [all], not rebuild evlib
uv pip install .[all]
shell: bash
- name: Debug - Find .pyd file location (Windows only)
if: matrix.os == 'windows-latest'
run: |
echo "=== Searching entire workspace for evlib .pyd files ==="
find . -name "evlib*.pyd" 2>/dev/null || echo "No evlib .pyd files found with find"
echo ""
echo "=== Checking sys.prefix/Lib/site-packages ==="
python -c "import sys, os; sp = os.path.join(sys.prefix, 'Lib', 'site-packages'); print('Path:', sp); print('Exists:', os.path.isdir(sp))"
python -c "import sys, os, glob; sp = os.path.join(sys.prefix, 'Lib', 'site-packages'); print('PYD files there:', glob.glob(os.path.join(sp, '*.pyd')))"
shell: bash
- name: Run tests
run: |
# Run pytest directly from venv instead of 'uv run' which creates isolated env
pytest -v tests/ -m "not slow and not integration"
pytest --nbmake examples/*.ipynb -v --no-cov
shell: bash
- name: Generate coverage report
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
run: pytest --cov=evlib --cov-report=xml -v tests/ -m "not slow and not integration"
shell: bash
- name: Upload coverage to Codecov
if: matrix.python-version == '3.11' && matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
fail_ci_if_error: false