Skip to content

Add Rust availability probe and native wheel parity checks - #25

Merged
leynos merged 27 commits into
mainfrom
terragon/add-rust-build-integration-ey5nsm
Jan 27, 2026
Merged

Add Rust availability probe and native wheel parity checks#25
leynos merged 27 commits into
mainfrom
terragon/add-rust-build-integration-ey5nsm

Conversation

@leynos

@leynos leynos commented Jan 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Introduce a minimal Rust backend availability probe and wire up a public Python API surface so pure-Python installs don’t break when the native Rust extension is unavailable.
  • Expose a public is_rust_available() API and keep a safe, import-time friendly probing path.
  • Add native Rust extension scaffolding (cuprum._ rust_backend_native) and a small Python shim (cuprum._rust_backend) to probe availability without forcing the native module to load.
  • Extend tests to cover public API wiring, the rust availability probe, and behavioural parity with the native backend when installed.
  • Revise CI/wheel flows to build both pure Python and native wheels, and add a verify-wheel-install step that installs pure first, then the native wheel, validating metadata parity.
  • Update design/docs references to reflect the availability probe, runtime dispatch considerations, and a robust wheel verification path.
  • Fix verify-wheel-install to reliably detect and validate native wheels and ensure metadata parity.

Changes

  • Import surface and public API:
    • cuprum/init.py now exports is_rust_available via cuprum.rust.is_rust_available().
    • New cuprum/rust.py provides a public is_rust_available() wrapper around the internal probe.
    • New cuprum/_rust_backend.py implements is_available() to probe the native extension without breaking imports when the native module is missing.
    • Kept a Python shim approach to probe availability without forcing the native extension to load.
  • Native extension scaffolding:
    • Added Rust workspace and minimal PyO3 binding (cuprum._rust_backend_native) to enable the availability probe.
  • Tests:
    • Updated unit/public API tests to ensure is_rust_available is exported and wired correctly.
    • Added unit tests for the Rust availability probe to verify behavior when the native module is present or missing.
    • Behavioural tests cover present/missing native extension scenarios and verify parity with the native backend state where installed.
  • CI & wheels:
    • Build workflows updated to produce both pure Python and native wheels, plus a verify-wheel-install step that installs pure Python first, then the native wheel and performs checks (including metadata parity).
  • Documentation & Roadmap:
    • Documentation references updated to reflect the availability probing surface and runtime dispatch considerations.
  • Artifacts & tooling:
    • Rust workspace scaffolding and maturin-backed tooling added to produce native wheels alongside pure Python wheels.
  • Tests infrastructure:
    • Added Rust availability probe tests and behavioural tests for end-to-end wheel verification.

Tests

  • Unit tests for the Rust availability probe ensure false when the native module is missing and true when present.
  • Behavioural tests verify the availability probe across installations and that the public probe mirrors the native backend state when installed.
  • Public API tests assert is_rust_available is exported and wired correctly.

Documentation & Roadmap

  • Design/docs references updated to reflect the Rust availability probe, fallback behavior, and runtime dispatch implications.
  • Roadmap entries updated to reflect the new two-wheel verification path and metadata parity checks.

Why this update

  • Ensures reliable detection of the native Rust wheel in environments that install both wheel types, and guards against metadata drift between wheel families.

Task

…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>
@coderabbitai

coderabbitai Bot commented Jan 18, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features

    • Optional Rust-backed performance extension and new public is_rust_available() API.
  • Improvements

    • Native wheels built and verified alongside pure‑Python wheels on all platforms.
    • Install-time verification ensures parity between wheel variants and automatic fallback to Python when Rust is unavailable.
    • Release flow updated to collect and publish built wheels.
  • Documentation

    • User and design docs added describing the optional Rust extension and verification steps.
  • Tests

    • Unit, behavioural and install-verification tests added for the availability probe and wheel installation.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Introduce 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

Cohort / File(s) Summary
GitHub Action: build action
.github/actions/build-wheels/action.yml
Replace cibuildwheel steps with maturin-based build; remove cibw-arch; add inputs target, wheelhouse, maturin-version; install Rust toolchain and run maturin build; use wheelhouse input for uploads.
Workflows
.github/workflows/build-wheels.yml, .github/workflows/ci.yml, .github/workflows/release.yml
Add build-pure-wheel, build-native-wheels, verify-wheel-install jobs; introduce MATURIN_VERSION; replace cibuildwheel matrix with explicit targets and manylinux handling; reuse build-wheels in CI and release; add id-token: write; collect wheels and publish via uv.
Python probe & public API
cuprum/_rust_backend.py, cuprum/rust.py, cuprum/__init__.py
Add internal shim is_available() that safely imports cuprum._rust_backend_native; add public is_rust_available() delegating to shim and export it from package root.
Native extension (Rust)
rust/cuprum-rust/src/lib.rs, rust/cuprum-rust/Cargo.toml, rust/Cargo.toml
Add minimal PyO3 extension _rust_backend_native exposing is_available(); introduce workspace and strict lint policies; add pyo3 dependency.
Rust build tooling
rust/Makefile
Add Makefile with targets for build, release, test, lint, fmt, check-fmt, markdownlint and nixie and associated flags/variables.
Maturin config / pyproject
pyproject.toml
Add maturin==1.6.0 as dev dependency and [tool.maturin] config (bindings=pyo3, manifest-path, module-name, python-source).
Tests: unit and behaviour
cuprum/unittests/test_rust_extension.py, cuprum/unittests/test_public_api.py, tests/behaviour/test_rust_extension_behaviour.py, tests/features/rust_extension.feature
Add unit tests for the availability probe and public export; add behavioural and Gherkin tests verifying probe returns boolean and matches native module when present.
Documentation & planning
docs/cuprum-design.md, docs/execplans/4-1-1-performance-extension-foundation.md, docs/roadmap.md, docs/users-guide.md
Document availability probe, backend selection, maturin-based build and verification; add ExecPlan and update roadmap to reflect completed stages.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🦀 Wheels shift to Rust and Python hum along,
A tiny probe replies if it belongs,
CI builds both paths and checks they play nice,
Tests and docs align, the workflow rolls like dice,
Merge the duet; let artefacts sing strong.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarises the primary change: introducing a Rust availability probe and implementing native wheel parity validation checks.
Description check ✅ Passed The description comprehensively addresses the changeset, detailing the Rust availability probe, public API surface, native extension scaffolding, test coverage, CI/workflow updates, and documentation revisions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch terragon/add-rust-build-integration-ey5nsm

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai

sourcery-ai Bot commented Jan 18, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Integrates 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 runtime

sequenceDiagram
    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
Loading

Class diagram for Python shim and Rust extension integration

classDiagram
    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
Loading

File-Level Changes

Change Details Files
Introduce optional Rust backend and Python availability shim for runtime probing without breaking pure-Python installs.
  • Add cuprum._rust_backend shim exposing is_available() that imports cuprum._rust_backend_native and safely returns False when unavailable.
  • Implement minimal PyO3-based Rust crate cuprum-rust exposing is_available() -> True via cuprum._rust_backend_native.
  • Add unit and BDD-style behavioural tests to validate probe behaviour with and without the native extension and to ensure consistency with the native module when present.
cuprum/_rust_backend.py
rust/Cargo.toml
rust/cuprum-rust/Cargo.toml
rust/cuprum-rust/src/lib.rs
cuprum/unittests/test_rust_extension.py
tests/behaviour/test_rust_extension_behaviour.py
tests/features/rust_extension.feature
Refactor CI wheel-building pipeline to support both pure-Python and maturin-based native wheels, plus installation verification and unified publishing.
  • Split build-wheels workflow into a pure-Python job using the existing pure-python-wheel action and a build-native-wheels matrix job using maturin (including manylinux and cross targets).
  • Add verify-wheel-install job that installs the pure wheel then a native wheel, asserts probe behaviour toggles from False to True, and checks metadata parity between wheel types.
  • Replace cibuildwheel-based composite action with a maturin-based one that installs Rust, runs maturin build (optionally with a target triple), and uploads artifacts.
  • Update release workflow to call the reusable build-wheels workflow, gather all wheel artifacts, and publish them to PyPI in one uv publish invocation instead of attaching them to a GitHub release.
  • Wire the build-wheels workflow into the main CI workflow as an additional job.
.github/workflows/build-wheels.yml
.github/workflows/release.yml
.github/actions/build-wheels/action.yml
.github/workflows/ci.yml
Document the Rust extension architecture, build and verification flows, and mark roadmap ExecPlan items as complete.
  • Extend users guide with a new section on optional Rust performance extensions, availability probing, source builds, CI commands, and the verification sequence for pure vs native wheels.
  • Update cuprum-design to describe the availability probe modules, Python shim behaviour, and the two-path build/publish strategy using uv_build and maturin.
  • Add an ExecPlan document detailing constraints, risks, plan of work, CI/build specifics, and acceptance criteria for the performance extension foundation.
  • Update roadmap items in section 4.1 and 4.5 to mark build-system integration and design-doc tasks as complete and to reflect use of uv_build plus maturin instead of hatchling/cibuildwheel.
docs/users-guide.md
docs/cuprum-design.md
docs/roadmap.md
docs/execplans/4-1-1-performance-extension-foundation.md
Configure tooling for Rust workspace and maturin integration with the existing Python project.
  • Add Rust workspace with strict clippy and rustc lints, and a rust/Makefile defining build, test (via cargo nextest), lint, and formatting targets.
  • Update pyproject.toml to include maturin as a dev dependency and configure tool.maturin (bindings, manifest path, module name, and python source) while keeping uv_build as the build backend.
  • Refresh uv.lock to capture the new tooling dependencies.
rust/Cargo.toml
rust/Makefile
pyproject.toml
uv.lock

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

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>
@leynos leynos changed the title Integrate Rust extensions with build system (foundation) Add ExecPlan for Rust extension foundation (4.1 + 4.5) Jan 18, 2026
…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>
@leynos leynos changed the title Add ExecPlan for Rust extension foundation (4.1 + 4.5) Integrate optional Rust extension into Cuprum build system (uv_build + maturin) Jan 19, 2026
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>
@leynos leynos changed the title Integrate optional Rust extension into Cuprum build system (uv_build + maturin) Integrate Rust extension with Cuprum build system (availability probe) Jan 19, 2026
- 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>
@leynos leynos changed the title Integrate Rust extension with Cuprum build system (availability probe) Integrate Rust Extensions With Cuprum Build System Jan 19, 2026
@leynos
leynos marked this pull request as ready for review January 19, 2026 23:49

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 6 issues, and left some high level feedback:

  • The _rust_backend.is_available() helper swallows all ImportErrors, 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.
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>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread .github/workflows/build-wheels.yml Outdated
Comment thread docs/users-guide.md Outdated
Comment thread docs/execplans/4-1-1-performance-extension-foundation.md Outdated
Comment thread docs/execplans/4-1-1-performance-extension-foundation.md Outdated
Comment thread docs/execplans/4-1-1-performance-extension-foundation.md Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread .github/actions/build-wheels/action.yml Outdated
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>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/actions/build-wheels/action.yml Outdated
Comment thread .github/actions/build-wheels/action.yml
Comment thread .github/workflows/build-wheels.yml Outdated
Comment thread .github/workflows/build-wheels.yml Outdated
Comment thread .github/workflows/build-wheels.yml Outdated
Comment thread rust/cuprum-rust/Cargo.toml Outdated
Comment thread rust/cuprum-rust/src/lib.rs
Comment thread rust/Makefile
Comment thread rust/Makefile
Comment thread tests/behaviour/test_rust_extension_behaviour.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.emulation is 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 --target flag 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_28

Or conditionally include --target in the args block.


60-60: Pin maturin-action to a commit SHA.

messense/maturin-action@v1 uses 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.

Comment thread .github/workflows/build-wheels.yml
…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>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread cuprum/unittests/test_rust_extension.py Outdated
Comment thread docs/execplans/4-1-1-performance-extension-foundation.md Outdated
Comment thread docs/users-guide.md
Comment thread rust/cuprum-rust/Cargo.toml Outdated
@leynos

leynos commented Jan 26, 2026

Copy link
Copy Markdown
Owner Author

@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.

Run set -eu
Requirement already satisfied: pip in ./.venv/lib/python3.13/site-packages (25.3)
Processing ./dist/wheels-pure/cuprum-0.1.0-py3-none-any.whl
Installing collected packages: cuprum
Successfully installed cuprum-0.1.0
=== Inspecting native wheel contents ===
      884  2026-01-26 09:10   cuprum/_rust_backend.py
   517544  2026-01-26 09:10   cuprum/_rust_backend_native.cpython-313-x86_64-linux-gnu.so
Processing ./dist/wheels-native-ubuntu-latest-x86_64/cuprum-0.1.0-cp313-cp313-manylinux_2_28_x86_64.whl
Installing collected packages: cuprum
  Attempting uninstall: cuprum
    Found existing installation: cuprum 0.1.0
    Uninstalling cuprum-0.1.0:
      Successfully uninstalled cuprum-0.1.0
Successfully installed cuprum-0.1.0
=== Listing installed cuprum package ===
total 184
drwxr-xr-x  6 runner runner  4096 Jan 26 09:11 .
drwxr-xr-x 12 runner runner  4096 Jan 26 09:10 ..
-rw-r--r--  1 runner runner  2396 Jan 26 09:10 __init__.py
drwxr-xr-x  2 runner runner  4096 Jan 26 09:11 __pycache__
-rw-r--r--  1 runner runner   110 Jan 26 09:10 _constants.py
-rw-r--r--  1 runner runner  2161 Jan 26 09:10 _observability.py
-rw-r--r--  1 runner runner 11682 Jan 26 09:10 _pipeline_internals.py
-rw-r--r--  1 runner runner   546 Jan 26 09:10 _pipeline_spawn.py
-rw-r--r--  1 runner runner  7014 Jan 26 09:10 _pipeline_streams.py
-rw-r--r--  1 runner runner  4242 Jan 26 09:10 _pipeline_wait.py
-rw-r--r--  1 runner runner  8713 Jan 26 09:10 _process_lifecycle.py
-rw-r--r--  1 runner runner   884 Jan 26 09:10 _rust_backend.py
-rw-r--r--  1 runner runner  6235 Jan 26 09:10 _streams.py
-rw-r--r--  1 runner runner 12051 Jan 26 09:10 _subprocess_execution.py
-rw-r--r--  1 runner runner  1757 Jan 26 09:10 _testing.py
drwxr-xr-x  2 runner runner  4096 Jan 26 09:10 adapters
drwxr-xr-x  3 runner runner  4096 Jan 26 09:11 builders
-rw-r--r--  1 runner runner  5280 Jan 26 09:10 catalogue.py
-rw-r--r--  1 runner runner 10110 Jan 26 09:10 concurrent.py
-rw-r--r--  1 runner runner 17891 Jan 26 09:10 context.py
-rw-r--r--  1 runner runner  2087 Jan 26 09:10 events.py
-rw-r--r--  1 runner runner  4438 Jan 26 09:10 logging_hooks.py
-rw-r--r--  1 runner runner   300 Jan 26 09:10 program.py
-rw-r--r--  1 runner runner   589 Jan 26 09:10 rust.py
-rw-r--r--  1 runner runner 15011 Jan 26 09:10 sh.py
drwxr-xr-x  2 runner runner  4096 Jan 26 09:10 unittests
Package at: /home/runner/work/cuprum/cuprum/cuprum
=== Testing Rust extension import ===
Failed to import native module: No module named 'cuprum._rust_backend_native'
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
ModuleNotFoundError: No module named 'cuprum._rust_backend_native'
Traceback (most recent call last):
  File "<stdin>", line 12, in <module>
AssertionError: Expected True but got False
is_rust_available() = False
Error: Process completed with exit code 1.

@coderabbitai

This comment was marked as resolved.

@leynos leynos changed the title Add Rust backend with availability probe, parity checks, and tests Fix Rust module import failure and add availability probe Jan 26, 2026
…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>
@leynos leynos changed the title Fix Rust module import failure and add availability probe Add optional Rust backend and wheel verification Jan 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/build-wheels.yml
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>
@leynos leynos changed the title Add optional Rust backend and wheel verification Fix verify-wheel-install native wheel detection Jan 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/build-wheels.yml
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>
@leynos leynos changed the title Fix verify-wheel-install native wheel detection Add Rust availability probe and robust wheel verification Jan 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/build-wheels.yml Outdated
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>
@leynos leynos changed the title Add Rust availability probe and robust wheel verification Fix verify-wheel-install native wheel detection Jan 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/build-wheels.yml
…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>
@leynos leynos changed the title Fix verify-wheel-install native wheel detection Add Rust availability probe and native wheel parity checks Jan 27, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread .github/workflows/build-wheels.yml
Comment thread .github/workflows/build-wheels.yml
@leynos
leynos merged commit d8606d6 into main Jan 27, 2026
11 checks passed
@leynos
leynos deleted the terragon/add-rust-build-integration-ey5nsm branch January 27, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant