Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Build, test and publish lance-csr wheels: Linux x86-64 (manylinux_2_28) and native
# Apple Silicon (macOS arm64), plus an sdist for every other platform.
#
# Pull requests that touch packaging build and test the wheels without publishing.
# Pull requests that change how wheels are built (this workflow, the wheel check, the
# release build profile) build and test them without publishing. Other changes rely on a
# manual mode=dry_run run before a release, to spare the ~30-minute macOS build.
# A published GitHub release (tag vX.Y.Z) publishes to PyPI after every build and test
# passes, through PyPI trusted publishing and the protected `pypi` environment; so does
# a manual run with mode=release. mode=dry_run builds and tests only.
Expand All @@ -15,10 +17,7 @@ on:
paths:
- .github/workflows/python-publish.yml
- ci/check_wheel.py
- python/pyproject.toml
- python/.cargo/**
- crates/lance-graph-python/Cargo.toml
- crates/lance-graph-python/Cargo.lock
workflow_dispatch:
inputs:
mode:
Expand Down Expand Up @@ -54,12 +53,17 @@ jobs:
with:
python-version: "3.12"

- uses: astral-sh/setup-uv@v4

- name: Install build dependencies
run: |
# protoc is needed by Lance's build scripts, not by wheel users.
sudo apt-get update
sudo apt-get install -y protobuf-compiler
pip install ziglang
# The ziglang package ships a zig binary: put its directory on PATH, where maturin
# looks first. (Not the tool's python3, which has no pip for maturin-action to use.)
uv tool install ziglang
"$(uv tool dir)/ziglang/bin/python" -c "import os, ziglang; print(os.path.dirname(ziglang.__file__))" >> "$GITHUB_PATH"

- name: Build manylinux_2_28 x86-64 wheel
uses: PyO3/maturin-action@04ac600d27cdf7a9a280dadf7147097c42b757ad # v1
Expand All @@ -81,8 +85,7 @@ jobs:
- name: Inspect distributions
working-directory: python
run: |
pip install twine
twine check dist/*
uvx twine check dist/*
sha256sum dist/*

- uses: actions/upload-artifact@v4
Expand All @@ -104,6 +107,8 @@ jobs:
with:
python-version: "3.12"

- uses: astral-sh/setup-uv@v4

- name: Install build dependencies
run: brew install protobuf

Expand All @@ -119,8 +124,7 @@ jobs:
- name: Inspect wheel
working-directory: python
run: |
pip install twine
twine check dist/*.whl
uvx twine check dist/*.whl
shasum -a 256 dist/*.whl

- uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -161,13 +165,18 @@ jobs:
run: |
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v -e cargo -e rustup | paste -sd: -)
! command -v cargo && ! command -v rustc
uv venv --python ${{ matrix.python }} "$RUNNER_TEMP/venv"
py="$RUNNER_TEMP/venv/bin/python"
uv pip install --python "$py" --only-binary=:all: --find-links dist lance-csr pytest pandas
"$py" -I ci/check_wheel.py
# This platform's wheel, by path, so PyPI's copy of the same version can't stand in.
case "$RUNNER_OS" in
Linux) wheel=$(ls "$PWD"/dist/*manylinux*.whl) ;;
macOS) wheel=$(ls "$PWD"/dist/*macosx*.whl) ;;
esac
# A fresh environment with the wheel and test tools; --no-build refuses any sdist.
run=(uv run --isolated --no-project --no-build --python ${{ matrix.python }}
--with "$wheel" --with pytest --with pandas)
"${run[@]}" python -I ci/check_wheel.py
cp -r python/python/tests "$RUNNER_TEMP/tests"
cd "$RUNNER_TEMP"
"$py" -I -m pytest "$RUNNER_TEMP/tests" -q -p no:cacheprovider
"${run[@]}" python -I -m pytest "$RUNNER_TEMP/tests" -q -p no:cacheprovider

publish:
needs: [build-linux, build-macos, test]
Expand Down
58 changes: 13 additions & 45 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ jobs:
python-version: ["3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Setup Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- uses: Swatinem/rust-cache@v2
Expand All @@ -45,63 +41,35 @@ jobs:
sudo apt update
sudo apt install -y protobuf-compiler
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Create virtual environment and install dependencies
uses: astral-sh/setup-uv@v4
- name: Install locked dependencies
working-directory: python
run: |
uv venv
source .venv/bin/activate
uv pip install maturin[patchelf]
# Install test dependencies only (skip editable install to avoid double-building Rust)
uv pip install pytest pyarrow pandas ruff
# The package itself is built by maturin develop below, in debug mode.
run: uv sync --locked --no-install-project --python ${{ matrix.python-version }}
- name: Build Python extension
working-directory: python
run: |
source .venv/bin/activate
maturin develop
run: uv run --no-sync maturin develop
- name: Run tests
working-directory: python
run: |
source .venv/bin/activate
pytest python/tests/ -v
- name: Run doctests
working-directory: python
run: |
source .venv/bin/activate
if [ -f python/lance_csr/__init__.py ]; then
python -m doctest python/lance_csr/__init__.py || echo "No doctests found"
fi
run: uv run --no-sync pytest python/tests/ -v

lint:
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install linting tools
uses: astral-sh/setup-uv@v4
- name: Install locked dependencies
working-directory: python
run: |
uv venv
source .venv/bin/activate
# Install only linting tools without building the Rust extension
uv pip install ruff pyright
# Linting needs no build of the Rust extension.
run: uv sync --locked --no-install-project --python 3.12
- name: Run ruff format check
working-directory: python
run: |
source .venv/bin/activate
ruff format --check python/
run: uv run --no-sync ruff format --check python/
- name: Run ruff lint
working-directory: python
run: |
source .venv/bin/activate
ruff check python/
run: uv run --no-sync ruff check python/
- name: Run pyright type check
working-directory: python
run: |
source .venv/bin/activate
pyright
run: uv run --no-sync pyright
9 changes: 4 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@
- `examples/` demonstrates Cypher usage; update or add examples when introducing new public APIs.

## Build, Test, and Development Commands
- `cargo check` / `cargo test --all` (run inside `crates/lance-graph`) validate Rust code paths.
- `cargo test --workspace` (from the repository root) runs the Rust tests; building needs `protoc`.
- `cargo bench --bench graph_execution -p lance-graph-benches` measures performance-critical changes; include shortened runs with `--warm-up-time 1`.
- `uv venv --python 3.12 .venv` and `uv pip install -e '.[tests]'` bootstrap the Python workspace.
- `maturin develop` rebuilds the extension after Rust edits; `pytest python/python/tests/ -v` exercises Python bindings.
- `make lint` (in `python/`) runs `ruff`, formatting checks, and `pyright`.
- Never use `pip`. In `python/`, `make install` runs `uv sync --locked --no-install-project` (locked dependencies and the `dev` group) and then a debug build with `uv run --no-sync maturin develop`; re-run it after Rust edits. Change dependencies with `uv add`/`uv remove` and commit `uv.lock`.
- `make test` runs the Python tests; `make lint` runs `ruff`, formatting checks, and `pyright`.

## Coding Style & Naming Conventions
- Format Rust with `cargo fmt --all`; keep modules and functions snake_case, types PascalCase, and reuse `snafu` error patterns.
- Run `cargo clippy --all-targets --all-features` to catch lint regressions.
- Run `cargo clippy --workspace --all-targets -- -D warnings` to catch lint regressions, as CI does.
- Use 4-space indentation in Python; maintain snake_case modules, CamelCase classes, and type-annotated public APIs.
- Apply `ruff format python/` before committing; `ruff check` and `pyright` enforce import hygiene and typing.

Expand Down
Loading
Loading