Add Rust availability probe and native wheel parity checks - #25
Conversation
…ce extension Add a detailed ExecPlan document outlining the build system and documentation foundation for optional Rust-backed stream operations. This plan includes constraints, risk analysis, progress stages, and validation criteria to scaffold native wheel builds with maturin alongside pure-Python fallback wheels. It establishes the roadmap alignment and defines interfaces for the Rust extension, test strategy, CI integration, and documentation updates. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughIntroduce an optional Rust-backed extension with a Python availability probe; add a PyO3 native crate and Rust workspace; switch wheel builds from cibuildwheel to maturin; extend CI to build and verify pure‑Python and native wheels; add tests, docs and tooling for the new probe and build flow. Changes
Sequence Diagram(s)sequenceDiagram
participant CI as CI (GitHub Actions)
participant Builder as Builder (maturin)
participant Rust as Rust extension (cargo/pyo3)
participant Verifier as Verifier job
participant Python as Python runtime
CI->>Builder: Run maturin build across matrix (--manifest-path ...)
Builder->>Rust: Compile PyO3 binding and produce native wheel
Rust-->>Builder: Emit native wheel to wheelhouse
Builder-->>CI: Upload wheel artifacts
CI->>Verifier: Start verify-wheel-install job
Verifier->>Python: Install pure-Python wheel
Python->>Verifier: is_rust_available() -> False
Verifier->>Python: Snapshot package metadata
Verifier->>Python: Install native wheel
Python->>Verifier: is_rust_available() -> True
Verifier->>Verifier: Compare metadata snapshots and availability
Verifier-->>CI: Report verification result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
Reviewer's GuideIntegrates an optional Rust backend into Cuprum via a PyO3-based extension and maturin-built native wheels, adds a Python availability shim and tests, and retools CI and release workflows so pure-Python and native wheels are built, verified, and published together while keeping uv_build as the primary backend. Sequence diagram for Rust availability probe at runtimesequenceDiagram
actor User
participant CuprumRustBackend as CuprumRustBackend
participant Importlib as Importlib
participant RustBackendNative as RustBackendNative
User->>CuprumRustBackend: import cuprum._rust_backend
User->>CuprumRustBackend: is_available()
CuprumRustBackend->>Importlib: import_module("cuprum._rust_backend_native")
alt native_extension_present
Importlib-->>CuprumRustBackend: module RustBackendNative
CuprumRustBackend->>RustBackendNative: is_available()
RustBackendNative-->>CuprumRustBackend: True
CuprumRustBackend-->>User: True
else native_extension_missing
Importlib-->>CuprumRustBackend: ImportError
CuprumRustBackend-->>User: False
end
Class diagram for Python shim and Rust extension integrationclassDiagram
class CuprumRustBackend {
+is_available() bool
}
class CuprumRustBackendNativePyO3 {
+is_available(py Python) PyResult~bool~
}
class RustCrateCuprumRust {
<<cdylib>>
+lib_name : _rust_backend_native
}
class RustWorkspace {
+members : cuprum-rust
+clippy_lints : pedantic, hygiene, panic_prone, portability, idioms, numerics, ergonomics, error_handling
+rust_lints : missing_docs, missing_crate_level_docs
}
class PyprojectMaturinConfig {
+bindings : pyo3
+manifest_path : rust/cuprum-rust/Cargo.toml
+module_name : cuprum._rust_backend_native
+python_source : .
}
CuprumRustBackend ..> CuprumRustBackendNativePyO3 : imports
CuprumRustBackendNativePyO3 ..> RustCrateCuprumRust : defined_in
RustCrateCuprumRust ..> RustWorkspace : member_of
PyprojectMaturinConfig ..> RustCrateCuprumRust : builds
PyprojectMaturinConfig ..> CuprumRustBackendNativePyO3 : exposes_module
CuprumRustBackend ..> PyprojectMaturinConfig : runtime_module_name
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Updated 4-1-1-performance-extension-foundation.md to specify that `uv_build` remains the primary Python build backend over hatchling, reflecting current `pyproject.toml` configuration. Removed outdated hatchling references and adjusted documentation on coexistence with maturin for native builds. Emphasized maintaining pure-Python build pathway and updated risk assessment accordingly. This change ensures accurate and up-to-date documentation of the build backend strategy, avoiding disruption from unnecessary migration risks and aligning plans with the existing tooling configuration. Date/Author: 2026-01-18 / Codex Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
…egration - Introduce a minimal Rust extension exposing an `is_available()` PyO3 binding. - Add Python shim `cuprum._rust_backend` as safe fallback returning False if native module missing. - Configure maturin alongside uv_build in pyproject.toml for optional native wheel builds. - Create Rust workspace and cargo config with linting and build targets. - Update GitHub Actions workflows for building and verifying both pure Python and native wheels. - Add unit and behavioural tests to verify Rust extension availability probe. - Extend documentation covering Rust backend architecture, fallback strategy, and usage guidance. This foundational work sets up optional Rust extension support to enable future performance improvements while maintaining pure Python compatibility. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
Replace the cibuildwheel-based native wheel build pipeline with direct usage of maturin. Introduce separate jobs for pure Python and native wheels, build native wheels using `maturin build` inside manylinux containers on Linux and directly on macOS and Windows. Ensure Rust toolchain setup is pinned and stable. Add verification steps in CI to install pure Python wheel first, check Rust extension availability, then install native wheel and verify extension availability and metadata consistency. Update release workflows to collect all wheel artifacts and publish them via `uv publish`. Update documentation to reflect the new wheel build and release strategy, removing references to cibuildwheel and describing the two-route build and publish process. Adjust workflows and actions accordingly. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
… docs Adjusted the --compatibility argument in the Linux wheel build step from a fixed 'pypi' to a matrix-based manylinux value in the GitHub build workflow. Updated related documentation in the execplans and users-guide to reflect the new manylinux_2_28 compatibility tag used for Linux builds with maturin, ensuring the docs align with the revised build process. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
- Remove deprecated `--compatibility` flag from maturin build commands. - Add `--manylinux 2_28` flag and explicit `--interpreter` path for Linux manylinux wheel builds. - Reflect changes in GitHub Actions workflow and documentation to ensure compatibility and clarity. - Improve documentation for building and verifying native and manylinux wheels. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Hey - I've found 6 issues, and left some high level feedback:
- The
_rust_backend.is_available()helper swallows allImportErrors, which can mask genuine import-time failures in the native module; consider catchingModuleNotFoundErrorspecifically so real extension bugs still surface. - In
build-wheels.yml, theverify-wheel-installjob is hard-wired to thewheels-native-ubuntu-latest-x86_64artifact and a single interpreter tag; it would be more robust to derive the artifact and wheel to install from the current matrix/runner so the check stays valid if the matrix changes. - The maturin version is pinned both in
.github/actions/build-wheels/action.yml(via pip) and in themessense/maturin-actionstep inbuild-wheels.yml; consolidating this into a single source of truth will reduce the chance of version drift between Linux and macOS/Windows builds.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `_rust_backend.is_available()` helper swallows all `ImportError`s, which can mask genuine import-time failures in the native module; consider catching `ModuleNotFoundError` specifically so real extension bugs still surface.
- In `build-wheels.yml`, the `verify-wheel-install` job is hard-wired to the `wheels-native-ubuntu-latest-x86_64` artifact and a single interpreter tag; it would be more robust to derive the artifact and wheel to install from the current matrix/runner so the check stays valid if the matrix changes.
- The maturin version is pinned both in `.github/actions/build-wheels/action.yml` (via pip) and in the `messense/maturin-action` step in `build-wheels.yml`; consolidating this into a single source of truth will reduce the chance of version drift between Linux and macOS/Windows builds.
## Individual Comments
### Comment 1
<location> `.github/workflows/build-wheels.yml:26-35` </location>
<code_context>
include:
- os: ubuntu-latest
arch: x86_64
- cibw_arch: x86_64
+ target: ""
+ manylinux: 2_28
+ # aarch64 wheels are built via QEMU emulation under maturin-action.
- os: ubuntu-latest
arch: aarch64
- cibw_arch: aarch64
- - os: windows-latest
+ target: aarch64-unknown-linux-gnu
+ manylinux: 2_28
+ emulation: qemu
+ - os: macos-13
arch: x86_64
</code_context>
<issue_to_address>
**issue (bug_risk):** aarch64 manylinux job declares QEMU emulation but does not enable it in the maturin action inputs
`emulation: qemu` is defined in the aarch64 matrix and the comment states these wheels are built via QEMU, but the `messense/maturin-action` step does not receive any `emulation` (or equivalent) input. This likely builds aarch64 wheels without QEMU, risking failures or host-arch wheels. Please pass `matrix.emulation` (and any corresponding field the action expects, e.g. `emulation: ${{ matrix.emulation }}`) into the maturin action so the aarch64 build actually runs under emulation.
</issue_to_address>
### Comment 2
<location> `cuprum/_rust_backend.py:8` </location>
<code_context>
+import importlib
+
+
+def is_available() -> bool:
+ """Return True when the native Rust extension can be imported."""
+ try:
</code_context>
<issue_to_address>
**issue (review_instructions):** Add concrete unit and behavioural tests for the new `_rust_backend.is_available()` feature; the newly added test files are currently missing actual test logic.
Treat the Rust backend availability probe as a new feature and cover it with both unit and behavioural tests.
Implement Python unit tests (e.g. in `cuprum/unittests/test_rust_extension.py`) that exercise:
- `is_available()` returning `False` when `cuprum._rust_backend_native` is not importable (e.g. via mocking `importlib.import_module`), and
- `is_available()` returning `True` when the native module is present and its `is_available()` returns a truthy value.
Implement behavioural tests (e.g. in `tests/behaviour/test_rust_extension_behaviour.py` and the associated `tests/features/rust_extension.feature`) that validate the end-to-end behaviour described in the docs and CI workflow: pure-Python installs report `False`, native installs report `True`, and the probe does not raise when the native extension is absent.
Do not leave the new test files empty or as placeholders; add assertions that would fail if the probe or its fallback behaviour regressed.
<details>
<summary>Review instructions:</summary>
**Path patterns:** `**/*`
**Instructions:**
For any new feature or change to an existing feature, both behavioural and unit tests are required.
</details>
</issue_to_address>
### Comment 3
<location> `docs/users-guide.md:891` </location>
<code_context>
+
+### Checking Rust availability
+
+You can check whether the optional extension is available in the current
+environment using the internal probe:
+
</code_context>
<issue_to_address>
**suggestion (review_instructions):** This sentence uses the second-person pronoun "you", which the documentation style instructions prohibit.
Consider rephrasing to avoid directly addressing the reader. For example: "It is possible to check whether the optional extension is available in the current environment using the internal probe:"
<details>
<summary>Review instructions:</summary>
**Path patterns:** `**/*.md`
**Instructions:**
Avoid 2nd person or 1st person pronouns ("I", "you", "we").
</details>
</issue_to_address>
### Comment 4
<location> `docs/execplans/4-1-1-performance-extension-foundation.md:40` </location>
<code_context>
+- Rust lints in Appendix 1 must be enforced in the new Cargo workspace.
+- Cuprum does not use cibuildwheel; native wheels must be built with maturin
+ directly.
+- CI must continue to pass on existing workflows; new jobs must not break
+ existing ones.
+
</code_context>
<issue_to_address>
**suggestion (review_instructions):** The acronym "CI" is used here without being defined on first use in this document.
Please expand the acronym on first use, for example: "Continuous integration (CI) must continue to pass on existing workflows; new jobs must not break existing ones." Subsequent uses can then use "CI" alone.
<details>
<summary>Review instructions:</summary>
**Path patterns:** `**/*.md`
**Instructions:**
Define uncommon acronyms on first use.
</details>
</issue_to_address>
### Comment 5
<location> `docs/execplans/4-1-1-performance-extension-foundation.md:140` </location>
<code_context>
+
+- `pyproject.toml` currently uses `uv_build` as the build backend.
+- `docs/roadmap.md` defines Phase 4.1 tasks (4.1.1 to 4.1.4).
+- `docs/adr-001-rust-extension.md` records the Rust extension decision and
+ runtime selection model.
+- `docs/cuprum-design.md` contains Section 13 on performance-optimised stream
</code_context>
<issue_to_address>
**suggestion (review_instructions):** The acronym "ADR" (architecture decision record) is referenced via the filename but not defined anywhere in the document.
Since ADR is not a universally known acronym, consider briefly expanding it at first mention, for example: "architecture decision record (ADR)", either in the surrounding text or in a short parenthetical note.
<details>
<summary>Review instructions:</summary>
**Path patterns:** `**/*.md`
**Instructions:**
Define uncommon acronyms on first use.
</details>
</issue_to_address>
### Comment 6
<location> `docs/execplans/4-1-1-performance-extension-foundation.md:218` </location>
<code_context>
+
+- Update `docs/cuprum-design.md` Section 13 to explicitly cover:
+ - Rust extension architecture (crate layout, PyO3 boundary).
+ - API boundary between Python and Rust (what crosses the FFI boundary).
+ - Fallback strategy (auto/rust/python selection and behaviour).
+ - Performance characteristics and limitations.
</code_context>
<issue_to_address>
**suggestion (review_instructions):** The acronym "FFI" is used without expansion, which conflicts with the requirement to define uncommon acronyms on first use.
Please expand FFI on first use, for example: "foreign function interface (FFI) boundary".
<details>
<summary>Review instructions:</summary>
**Path patterns:** `**/*.md`
**Instructions:**
Define uncommon acronyms on first use.
</details>
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 95d97e2eb2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Simplify and centralize the Python interpreter path resolution for manylinux builds by adding a dedicated step in the GitHub Actions workflow. Replace hardcoded paths with a dynamically resolved interpreter path using a reusable bash script. This improves maintainability and clarity in the build process. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 15
🤖 Fix all issues with AI agents
In @.github/actions/build-wheels/action.yml:
- Around line 27-28: Replace the floating tag used for the "Install Rust
toolchain" step (currently referencing dtolnay/rust-toolchain@stable) with an
explicit commit SHA to match the pinning policy used for other actions; update
the step that uses "dtolnay/rust-toolchain@stable" to
"dtolnay/rust-toolchain@<commit-sha>" (use the repo's latest verified commit
SHA) so the action is pinned and reproducible.
- Around line 34-41: The line-continuation escape in the run block is using a
double backslash which is unnecessary; update the args assignment in the run
script (the args=(--release --out "${{ inputs.wheelhouse }}" \\ --manifest-path
rust/cuprum-rust/Cargo.toml) line) to use a single backslash for line
continuation so the bash run block interprets it correctly, keeping the rest of
the args array and later maturin build "${args[@]}" invocation unchanged.
In @.github/workflows/build-wheels.yml:
- Line 50: The workflow currently references the action with a floating tag
"uses: messense/maturin-action@v1"; replace this with a specific commit SHA
(e.g. "messense/maturin-action@<commit-sha>") to pin the action for reproducible
builds and supply-chain security—update the "uses" entry in the build-wheels.yml
workflow to match the repository's convention of pinning GitHub actions to exact
commit hashes.
- Line 74: Remove the redundant comment "# aarch64 wheels are built via QEMU
emulation under maturin-action." by deleting the duplicate occurrence (keep the
original instance elsewhere in the workflow); search for that exact comment
string in the build-wheels.yml workflow and remove any additional copies so only
a single annotation remains.
- Around line 56-59: The workflow uses a non-existent replace() expression
inside the maturin args (the --interpreter value), which will fail; remove the
inline replace(...) and instead compute the Python interpreter path in a prior
shell step (e.g., run a step that reads inputs['python-version'], strips dots in
shell and exports an env var like PY_INTERPRETER_PATH or sets an output) and
then reference that env var in the args for the maturin invocation (the args
block containing "--interpreter ..."). Alternatively, omit the --interpreter
flag so the maturin/maturin-action auto-detects interpreters or use the action’s
built-in interpreter finding options.
In `@cuprum/_rust_backend.py`:
- Around line 8-14: Update the docstring for the is_available function in
cuprum._rust_backend.py to NumPy style: add a one-line summary, a "Returns"
section specifying "bool: True when the native Rust extension can be imported
and reports available", and a "Notes" section explaining the implementation
details (it attempts to import cuprum._rust_backend_native and returns
native.is_available()). Keep wording concise and follow NumPy docstring
formatting.
In `@cuprum/unittests/test_rust_extension.py`:
- Around line 41-47: Change the exception caught in the test function
test_native_module_reports_availability_when_installed to catch ImportError (not
ModuleNotFoundError) so it matches the shim behavior in cuprum._rust_backend;
locate the importlib.import_module("cuprum._rust_backend_native") call in that
test and replace the except ModuleNotFoundError branch with except ImportError
and keep the pytest.skip("Rust extension is not installed.") behavior intact.
In `@docs/users-guide.md`:
- Around line 881-884: Change the British -isation spelling in the sentence
containing "stream optimisations" to the en-GB-oxendict Oxford form using the
-ize suffix (i.e., replace "stream optimisations" with "stream optimizations")
so the paragraph about the Rust extension ("Cuprum ships as a pure Python
wheel..." through "pure Python installations.") follows the project's
en-GB-oxendict spelling guideline.
In `@pyproject.toml`:
- Line 25: Update the dev dependency entry for "maturin" in pyproject.toml to
pin it to the same version used in CI (1.6.0); locate the "maturin" entry under
the dev-dependencies section (e.g., [tool.poetry.dev-dependencies] or similar)
and add the version specifier so it matches the workflow pin to prevent local/CI
version drift.
In `@rust/Cargo.toml`:
- Around line 67-69: Update the lint configuration so the crate-level rustdoc
lint uses the new tool-lint namespace: remove or stop setting
missing_crate_level_docs under the [workspace.lints.rust] table and instead add
it under a new [workspace.lints.rustdoc] table (or prefix the key with
rustdoc::) so that missing_crate_level_docs is declared as a rustdoc tool lint
compatible with Rust 1.70+; change the relevant entry that currently reads
missing_crate_level_docs = "deny" to be under [workspace.lints.rustdoc] (or as
rustdoc::missing_crate_level_docs = "deny") while keeping missing_docs = "deny"
in [workspace.lints.rust].
In `@rust/cuprum-rust/Cargo.toml`:
- Around line 13-14: Update the pyo3 dependency from version "0.23" to "0.27.2"
in Cargo.toml (the pyo3 entry) and add a [lints] section so this crate inherits
the workspace lints defined at the workspace root; modify the pyo3 declaration
to use version "0.27.2" while preserving features = ["extension-module"], and
add a [lints] block that enables inheriting the workspace rules so the crate
follows the repo-wide lint configuration.
In `@rust/cuprum-rust/src/lib.rs`:
- Around line 19-23: The module doc comment for the Python module (above the
#[pymodule] attribute) uses British -ise spelling "initialised"; update that
sentence to use -ize spelling ("initialized") so the comment reads "Returns a
Python error if the module cannot be initialized." Make this change only in the
doc comment associated with the Python module definition in lib.rs so the
#[pymodule] attribute and surrounding code remain unchanged.
In `@rust/Makefile`:
- Around line 1-14: The Makefile declares markdownlint and nixie in .PHONY but
doesn't define them, causing make markdownlint / make nixie to fail; add
delegation targets named markdownlint and nixie (similar to the existing
check-fmt target) that invoke the root Makefile via $(MAKE) -C .. markdownlint
and $(MAKE) -C .. nixie so calls from the rust directory forward to the root
implementations and succeed.
- Around line 26-32: The Makefile test and lint targets invoke tools without
verifying availability; update the test target (which currently uses RUSTFLAGS,
RUST_FLAGS, $(CARGO), and nextest) to first check whether cargo-nextest is
available and, if not, fall back to running $(CARGO) test (preserving RUSTFLAGS
and TEST_FLAGS/BUILD_JOBS), and update the lint target to check for the presence
of the whitaker binary (used as `whitaker --all -- $(CARGO_FLAGS)`) and fail
fast with a clear error message if it is missing; use simple shell availability
checks (e.g., command -v or similar) inside the test and lint recipe commands to
implement these behaviors and reference the existing variables/commands
(RUSTFLAGS, $(CARGO), nextest, whitaker, CARGO_FLAGS) so the change is localized
to those targets.
In `@tests/behaviour/test_rust_extension_behaviour.py`:
- Around line 42-49: The test function then_probe_matches_native currently
catches ModuleNotFoundError when importing "cuprum._rust_backend_native"; change
the exception to ImportError to match production/shim behavior. Update the
try/except in then_probe_matches_native so it catches ImportError, leaving the
importlib.import_module("cuprum._rust_backend_native") call and the subsequent
availability assertion unchanged.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/build-wheels.yml:
- Around line 100-160: The hardcoded native-wheel path
dist/wheels-native-ubuntu-latest-x86_64/ should be replaced with an environment
variable so changes to artifact naming won’t break this job; add a variable
(e.g., NATIVE_WHEEL_DIR_PATTERN) at the top of the step or workflow and use that
variable in the pip install invocation (the python -m pip install
--force-reinstall ... line that currently references
dist/wheels-native-ubuntu-latest-x86_64/*${PYTAG}*.whl), ensuring PYTAG is still
interpolated as before and that the env var is exported or passed into the shell
session before any uses.
♻️ Duplicate comments (3)
.github/workflows/build-wheels.yml (3)
26-35: Pass the emulation setting to maturin-action for aarch64 builds.
matrix.emulationis defined for aarch64 but never consumed by the maturin-action step. Without this, aarch64 wheels will fail to build or produce incorrect binaries. Add the appropriate input to the maturin-action invocation.Additionally,
target: ""on line 28 may pass an empty--targetflag to maturin. Either omit the key entirely or use a conditional in the args.Proposed fix for target handling
- os: ubuntu-latest arch: x86_64 - target: "" + # target omitted; maturin defaults to host architecture manylinux: 2_28Or conditionally include
--targetin the args block.
60-60: Pin maturin-action to a commit SHA.
messense/maturin-action@v1uses a floating major version tag. Pin to a specific commit hash for supply-chain security and reproducibility, consistent with the other actions in this workflow.
83-83: Remove duplicate comment.This comment duplicates line 30. Delete the redundant annotation.
- # aarch64 wheels are built via QEMU emulation under maturin-action.
…uild - Implement is_available() probe to detect Rust extension presence safely, distinguishing missing module from other import errors. - Update Rust dependencies and workspace linting for stricter checks. - Refactor GitHub Actions/workflows to use pinned maturin version 1.6.0, improve manylinux wheel build with proper interpreter and QEMU setup for aarch64. - Enhance Makefile targets for Rust, adding fallbacks and requirement checks. - Update documentation and user-guide to clarify Rust extension usage, build instructions, and terminology. - Add tests covering availability probe behavior with adjusted import error handling. This enhances optional Rust extension integration, build reliability, availability detection, and documentation for users and CI workflows. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
- Added explicit 'stable' toolchain setting to Rust toolchain action install step to ensure consistent Rust version. - Replaced hardcoded native wheel path with environment variable for better maintainability and readability in GitHub workflow. - These fixes improve reliability and clarity of the wheels build process in CI. Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@cuprum/unittests/test_rust_extension.py`:
- Around line 13-51: Add intent-revealing assertion messages to each test
assertion: update the asserts in
test_is_available_returns_false_when_module_missing (assert
_rust_backend.is_available() is False),
test_is_available_returns_true_when_module_present (assert
_rust_backend.is_available() is True), and
test_native_module_reports_availability_when_installed (assert
native.is_available() is True) to include short explanatory messages (e.g.,
"expected probe to report unavailable when module missing", "expected probe to
report available when native module present", "expected native extension to
report available when installed") so each assertion clarifies the test intent;
modify the assert statements in those functions only.
In `@docs/execplans/4-1-1-performance-extension-foundation.md`:
- Around line 7-8: Update the ExecPlan status to match the revision note by
changing the "Status: COMPLETE" marker to "Status: IN PROGRESS" (or vice versa
if you prefer the plan to be COMPLETE); locate the header "Status: COMPLETE" and
the revision note that says "updated to IN PROGRESS" and make them consistent,
and also apply the same change to the duplicate occurrence around lines 383-385
so both the header and the later note reflect the same status.
In `@docs/users-guide.md`:
- Around line 941-948: In the "Verification procedure" section replace the
informal numbered markers ("1)", "2)", "3)") with standard Markdown ordered list
syntax ("1. ", "2. ", "3. ") for the three verification steps (install pure
Python wheel / force-reinstall native wheel / compare metadata) so the linter
recognizes the list; locate the "Verification procedure" heading and update the
three list lines accordingly.
In `@rust/cuprum-rust/Cargo.toml`:
- Line 4: Change testing only: temporarily set edition = "2024" in Cargo.toml
and validate the entire dependency tree before committing the upgrade by running
cargo update and inspecting dependencies with cargo tree (and cargo outdated if
available) to find incompatible crates, then run cargo build and cargo test (and
cargo check) under the target Rust toolchain (e.g., rustup default or
+stable/+nightly as appropriate) to surface any incompatibilities; specifically
verify PyO3 usage in this crate and its transitive dependencies (search for pyo3
in the cargo tree) and revert the edition change if any downstream crate fails
to build or test, otherwise make the edition = "2024" change permanent.
|
@coderabbitai Please investigate the following build failure, then suggest a fix for the cause and supply a prompt for an AI coding agent to enable it to apply the fix. |
This comment was marked as resolved.
This comment was marked as resolved.
…repo The verify-wheel-install job was importing the local repo's cuprum package instead of the installed wheel because CWD shadowed site-packages. Now all Python import checks run in a subshell that cds into a temp dir, and wheel paths are resolved to absolute paths before installation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/build-wheels.yml:
- Around line 124-136: The current shell step assigns PURE_WHEEL via glob and
then installs it without verifying the match count; update the script around the
PURE_WHEEL assignment/usage to first expand the glob into an array (or use a
count check), verify there is exactly one match (error and exit if zero or more
than one) before calling realpath and python -m pip install "${PURE_WHEEL}";
reference the PURE_WHEEL variable and the pip install line so you add the guard
immediately prior to the install to fail fast on missing or multiple pure-wheel
matches.
The pure wheel glob was being expanded and passed to realpath without verifying exactly one match exists. Now the glob is expanded into an array and checked for exactly one match before proceeding, matching the existing pattern used for native wheel validation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/build-wheels.yml:
- Around line 123-168: In the CI step named "Install pure Python wheel, then
native wheel" update the shell invocation that currently uses the line "set -eu"
to include pipefail by changing it to "set -euo pipefail" so that pipeline
failures are propagated; locate the shell block that sets up the virtualenv and
runs the verification commands (the block containing "python -m venv .venv",
"PURE_WHEEL_GLOB=(dist/wheels-pure/*.whl)", and the VERIFY_DIR subshell) and
replace the existing set option accordingly.
Add pipefail to set -euo to ensure pipeline failures are properly detected in the wheel verification script. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/build-wheels.yml:
- Around line 176-186: Remove the redundant shell option enablement: delete the
duplicate "shopt -s nullglob" invocation found just before the NATIVE_WHEEL_GLOB
assignment so the script relies on the earlier enabling (line with the first
shopt) and avoid repeated calls; keep the subsequent logic that builds
NATIVE_WHEEL_GLOB, the conditional check on "${`#NATIVE_WHEEL_GLOB`[@]}", and the
error handling around "Expected exactly one native wheel for ${ARCH}." intact.
The shopt -s nullglob call before NATIVE_WHEEL_GLOB is redundant since it was already enabled earlier in the script for PURE_WHEEL_GLOB. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.github/workflows/build-wheels.yml:
- Around line 192-211: The script currently imports cuprum._rust_backend_native
and only asserts cuprum.is_rust_available(); update the check to fail fast if
the native module loads but reports unavailable by explicitly checking
native.is_available() after a successful import and exiting non‑zero (or raising
AssertionError) when native.is_available() is False; modify the inline Python
block to call import cuprum as c; import cuprum._rust_backend_native as native;
then assert native.is_available() is True (and keep/assert c.is_rust_available()
is True) so any parity regression is surfaced immediately.
…vailable Add explicit assertion on native.is_available() after successful import to catch parity regressions between the native module and public API. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @.github/workflows/build-wheels.yml:
- Line 87: Replace the mutable container tag value
"ghcr.io/rust-cross/manylinux_2_28-cross:aarch64" with its immutable digest;
obtain the digest by running the provided docker pull + docker inspect command
and then update the container field to use the returned repoDigest (e.g.
ghcr.io/...@sha256:...) so the workflow references the pinned image digest
instead of the tag.
- Around line 10-12: Update the MATURIN_VERSION environment variable in the
GitHub Actions workflow (env: MATURIN_VERSION) from "1.6.0" to the current
stable release "1.11.5"; locate the MATURIN_VERSION entry in
.github/workflows/build-wheels.yml and change the string value so the workflow
uses the newer maturin release.
Summary
Changes
Tests
Documentation & Roadmap
Why this update
Task