Skip to content

Simplify tests/helpers/maturin.py: inline pin checks, consolidate wheel snapshot (#97, #99) - #240

Merged
leynos merged 13 commits into
mainfrom
simplify-maturin-helper
Aug 3, 2026
Merged

Simplify tests/helpers/maturin.py: inline pin checks, consolidate wheel snapshot (#97, #99)#240
leynos merged 13 commits into
mainfrom
simplify-maturin-helper

Conversation

@leynos

@leynos leynos commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Summary

tests/helpers/maturin.py had grown to 394 lines / 15 definitions while serving a single consumer, cuprum/unittests/test_maturin_build.py — the over-extraction flagged in #97 and #99. This PR inlines the pin-synchronisation logic into that sole consumer and consolidates the wheel-snapshot machinery.

Changes

  • Inline pin-reading into the consumer. read_expected_maturin_version, read_maturin_pins, read_manylinux_aarch64_container_ref, workflow_uses_manylinux_aarch64_container_ref, _require_pin_match, and all five pin regexes now live as private helpers in test_maturin_build.py. They have exactly one caller each.
  • Consolidate wheel-snapshot parsing 6 → 3 functions. _header_value, _locate_dist_info_wheel, and _parse_wheel_header are folded into wheel_build_snapshot/_parse_metadata, leaving three primary parsing functions (wheel_build_snapshot, _parse_metadata, _normalise_wheel_entry) as Simplify tests/helpers/maturin.py: consolidate 12 functions into 2–3 and defer abstraction until second consumer exists #99 asks.
  • Fold _maturin_module_available into toolchain_available.
  • Document the reuse policy (defer re-externalisation until a second concrete consumer exists) in the module docstring.

The retained wheel build/snapshot machinery wraps subprocess and zipfile introspection that does not inline cleanly, so per #97 it stays as a minimal helper.

Result: helper drops to 218 lines / 6 definitions.

Why the entry-normalisation is kept

Every _normalise_wheel_entry branch — the .dist-info suffixes, /sboms/, and the .cpython-<platform>.so extension module — is exercised by the test_maturin_wheel_build_snapshot syrupy snapshot, which runs across the wheel-build matrix. None is speculative, and removing any would change verified output.

Validation

  • test_maturin_wheel_build_snapshot passes with byte-identical snapshot output (behaviour preserved).
  • Full gates green: make check-fmt, make lint (ruff, interrogate 100%, pylint 10.00/10), make test (755 passed / 47 skipped; Rust nextest 57/57).

Closes #97
Closes #99

🤖 Generated with Claude Code

Summary by Sourcery

Inline maturin pin-synchronisation helpers into the maturin build tests and slim down the shared maturin helper to focus on wheel build/snapshot introspection.

Enhancements:

  • Fold maturin module detection into the Rust toolchain availability check to reduce indirection.
  • Simplify wheel metadata parsing by inlining header-extraction helpers and consolidating WHEEL/METADATA handling into the main snapshot function.

Documentation:

  • Document the reuse policy for the maturin test helper module, clarifying that new shared helpers should only be added when there is more than one consumer.

Tests:

  • Move maturin pin and manylinux container regexes and readers into private helpers within test_maturin_build, keeping the pin-synchronisation logic local to its only consumer.

@sourcery-ai

sourcery-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Simplifies the maturin test helper by inlining pin- and workflow-related logic into its sole test consumer and collapsing wheel snapshot parsing into fewer, more cohesive functions, while tightening the toolchain availability check and documenting reuse policy.

File-Level Changes

Change Details Files
Inline maturin pin and manylinux-container checks into the maturin build tests, turning the shared helper into a focused wheel/snapshot helper.
  • Move maturin pin regexes and manylinux container regexes from the helper module into test_maturin_build as private test-local constants.
  • Reimplement pin-reading and manylinux container helper functions directly in test_maturin_build.py with repo-relative file reads.
  • Update tests to call the new private helpers instead of the removed functions from tests.helpers.maturin.
cuprum/unittests/test_maturin_build.py
tests/helpers/maturin.py
Collapse wheel metadata parsing into fewer functions and simplify metadata extraction.
  • Remove the generic header_value helper and inline single-valued header extraction inside _parse_metadata.
  • Change _parse_metadata to pull first values directly from the headers dict while still sorting multi-valued headers.
  • Update the docstring for _parse_metadata to clarify it parses METADATA headers specifically.
tests/helpers/maturin.py
Consolidate WHEEL header parsing and archive inspection into wheel_build_snapshot.
  • Inline _locate_dist_info_wheel logic into wheel_build_snapshot when locating the .dist-info/WHEEL entry.
  • Inline _parse_wheel_header logic into wheel_build_snapshot to derive generator and Root-Is-Purelib values from the WHEEL payload.
  • Keep layout normalisation via _normalise_wheel_entry but reuse the inlined metadata to build the snapshot structure.
tests/helpers/maturin.py
Tighten the Rust toolchain availability check and clarify helper module intent.
  • Merge _maturin_module_available into toolchain_available, handling ImportError defensively and returning a single boolean.
  • Adjust the toolchain_available docstring to mention both Rust toolchain and maturin module availability.
  • Add a module-level docstring explaining that only wheel build/snapshot helpers remain here and that further extraction should wait for a second consumer.
tests/helpers/maturin.py

Assessment against linked issues

Issue Objective Addressed Explanation
#97 Inline the maturin pin-collection and version-expectation logic from tests/helpers/maturin.py into cuprum/unittests/test_maturin_build.py, leaving tests/helpers/maturin.py as a minimal helper module.
#97 Simplify tests/helpers/maturin.py by removing speculative platform-variability normalisation and over-general wheel parsing, retaining only the minimal wheel_build_snapshot machinery and its directly required helpers.
#97 Document the reuse strategy for test helpers in docs/developers-guide.md before any future re-externalisation of shared helpers. The PR documents the reuse policy in the tests/helpers/maturin.py module docstring, but does not add or modify any content in docs/developers-guide.md as explicitly requested in the issue.
#99 Inline maturin pin-reading and workflow pin-synchronisation logic from tests/helpers/maturin.py directly into its sole consumer cuprum/unittests/test_maturin_build.py.
#99 Consolidate wheel snapshot parsing helpers in tests/helpers/maturin.py into 2–3 primary functions, reducing over-extraction while preserving behaviour.
#99 Remove or avoid speculative, unexercised platform-variability normalisation from tests/helpers/maturin.py and document that further abstraction should be deferred until a second concrete consumer exists.

Possibly linked issues


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

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a57bcefa-a56e-4789-9490-ac50cc0a17ff

📥 Commits

Reviewing files that changed from the base of the PR and between 19a3d58 and 2f5cf70.

📒 Files selected for processing (7)
  • cuprum/unittests/_maturin_pin_support.py
  • cuprum/unittests/test_manylinux_container_ref_properties.py
  • cuprum/unittests/test_maturin_build.py
  • cuprum/unittests/test_maturin_pins.py
  • cuprum/unittests/test_maturin_toolchain.py
  • docs/developers-guide.md
  • tests/helpers/maturin.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/shared-actions (auto-detected)
  • leynos/pylint-pypy-shim (auto-detected)
  • leynos/whitaker (auto-detected)

Summary

  • Move Maturin pin synchronisation and Manylinux container validation into dedicated unit-test modules.
  • Reduce tests/helpers/maturin.py to toolchain detection, wheel building, and snapshot utilities.
  • Update toolchain_available() to import maturin directly while still requiring cargo and rustc.
  • Consolidate wheel archive inspection and preserve byte-identical snapshot output.
  • Add exact-message tests for missing wheel .dist-info/METADATA and .dist-info/WHEEL members.
  • Add coverage for Maturin pin checks, toolchain detection, script discovery, and Manylinux container references.
  • Share the Manylinux container regex after it gained a second consumer.
  • Update docs/developers-guide.md with helper responsibilities, version checks, and the policy for future extraction.
  • Confirm no production-code changes and passing formatting, linting, documentation, type-checking, and test gates.

Walkthrough

Separate Maturin pin, toolchain, wheel-build, and snapshot checks into focused modules. Add shared pin-reading support. Add coverage for missing wheel metadata. Update helper documentation and packaged test entries.

Changes

Maturin test separation

Layer / File(s) Summary
Centralise Maturin pin validation
cuprum/unittests/_maturin_pin_support.py, cuprum/unittests/test_maturin_pins.py, cuprum/unittests/test_manylinux_container_ref_properties.py, docs/developers-guide.md
Add shared readers and regular expressions. Verify synchronised Maturin pins, installed-version alignment, and immutable Manylinux container references.
Separate toolchain detection tests
tests/helpers/maturin.py, cuprum/unittests/test_maturin_toolchain.py, docs/developers-guide.md
Require importable maturin, cargo, and rustc. Test import failures, script discovery, and Windows .exe launchers. Document the updated boundaries.
Refocus wheel-build validation
cuprum/unittests/test_maturin_build.py, cuprum/unittests/__snapshots__/test_maturin_build.ambr
Reuse the shared pin reader. Remove relocated checks. Assert exact errors for missing WHEEL or METADATA entries. Update packaged test entries.

Possibly related PRs

  • leynos/cuprum#217: Refactors related Maturin pin, toolchain, script-location, and wheel-snapshot tests.

Suggested labels: Issue

Poem

Split each check into its place,
Pin every version with care.
Missing metadata raises clear,
Toolchain probes now persevere.
Wheels pass the test.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (4 inconclusive)

Check name Status Explanation Resolution
Testing (Overall) ❓ Inconclusive Investigation is still in progress; no verdict has been submitted yet. Inspect the wheel parser and related tests before deciding.
Developer Documentation ❓ Inconclusive Investigation is still in progress. Inspect the committed documentation and related test changes before deciding whether the developer guide documents the new boundaries.
Unit Architecture ❓ Inconclusive Investigation has not yet established whether the changed query and command paths expose and handle their fallible dependencies. Inspect the changed helpers and tests before deciding.
Performance And Resource Use ❓ Inconclusive Initial repository diff output was empty, so inspect the checked-out files and repository metadata before assessing resource behaviour. Provide the checked-out PR revision or make the PR changes visible to the repository tools.
✅ Passed checks (16 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the helper simplification and references both linked issues, #97 and #99.
Description check ✅ Passed The description explains the helper refactor, wheel snapshot consolidation, documentation updates, and validation results.
Linked Issues check ✅ Passed The changes inline single-consumer logic, consolidate wheel parsing, remove speculative abstractions, and document the reuse policy [#97] [#99].
Out of Scope Changes check ✅ Passed The changes remain within the linked objectives and support the test-helper refactor, validation, documentation, and justified symbol sharing.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
User-Facing Documentation ✅ Passed The PR changes only tests, test helpers, snapshots, and docs/developers-guide.md; it changes no production/API files or docs/users-guide.md, so no user-facing behaviour requires user-guide document...
Module-Level Documentation ✅ Passed Mark PASS: all six changed Python modules have module docstrings; the docs state each module’s purpose and, where relevant, its helper and test relationships.
Testing (Unit And Behavioural) ✅ Passed Retain PASS: tests cover real wheel builds, pin and workflow contracts, toolchain gates, platform launchers, property-based digest invariants, and exact missing-metadata errors.
Testing (Property / Proof) ✅ Passed Retain test_manylinux_container_ref_properties.py: Hypothesis generates valid 32-byte digests, mutable tags, and 0–63-character truncated digests against the shared regex.
Testing (Compile-Time / Ui) ✅ Passed No Rust or TypeScript compile-time change is present, so trybuild coverage is not applicable; the wheel output has a focused normalized snapshot and explicit semantic assertions.
Domain Architecture ✅ Passed The PR changes only test helpers, unit tests, snapshots, and documentation; no production/domain module imports maturin or test helpers, and filesystem, subprocess, and zipfile concerns remain in t...
Observability ✅ Passed Pass this check: the diff contains only unit-test helpers, snapshots, and developer documentation; it changes no runtime package or operational behaviour requiring telemetry.
Security And Privacy ✅ Passed Changed code contains no credentials or personal data; subprocess use is argument-list based with trusted paths, and the CI container remains SHA-256 pinned.
Concurrency And State ✅ Passed The PR adds only synchronous file, subprocess, and test-fixture operations; no async tasks, locks, shared mutable state, or ordering protocol is introduced, and pytest runs serially by default.
Architectural Complexity And Maintainability ✅ Passed Accept the change: the helper shrinks from 301 to 190 lines, shared symbols have two concrete consumers, and the guide documents the reuse boundary.
Rust Compiler Lint Integrity ✅ Passed Pass this check: the full PR range changes only Python, Markdown, and a snapshot; it changes no Rust files, lint suppressions, or Rust ownership code.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch simplify-maturin-helper

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

codescene-access[bot]

This comment was marked as outdated.

sourcery-ai[bot]

This comment was marked as resolved.

@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: 6494aa38bf

ℹ️ 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 tests/helpers/maturin.py Outdated
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot added the Issue label Jul 28, 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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/developers-guide.md`:
- Around line 1412-1415: Update the wheel builder scope description around
build_native_wheel_artifact, toolchain_available, and wheel_build_snapshot to
state that build_native_wheel_artifact uses the maturin module available to the
current Python interpreter rather than selecting a pinned version. Also describe
the pin check and snapshot generator assertion as the mechanisms enforcing
version alignment.

In `@tests/helpers/maturin.py`:
- Around line 164-178: In _read_wheel_members, validate that the derived
metadata_name appears in entry_names before calling archive.read(metadata_name).
Raise the documented AssertionError with the missing .dist-info/METADATA message
when absent, while preserving the existing read and decode flow when present.
- Around line 71-80: The public function toolchain_available in
tests/helpers/maturin.py (lines 71-80) needs a NumPy-style Returns section
documenting that it returns True only when cargo, rustc, and the maturin module
are available. Add the corresponding Returns section to the other changed public
function in tests/helpers/maturin.py (lines 204-208), documenting its stable
snapshot mapping for a wheel.
- Line 127: Update the changed docstrings in the relevant parsing helpers,
including the one describing RFC 2822 METADATA headers and the sections at the
referenced locations, to use Oxford -ize spellings: replace “normalised”,
“Normalise”, and “normalises” with “normalized”, “Normalize”, and “normalizes”
while preserving the existing documentation content.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c88aed4c-c59f-41bd-9c32-9cbed57e0797

📥 Commits

Reviewing files that changed from the base of the PR and between 302858c and 8b3df4a.

📒 Files selected for processing (3)
  • cuprum/unittests/test_maturin_build.py
  • docs/developers-guide.md
  • tests/helpers/maturin.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/shared-actions (auto-detected)
  • leynos/pylint-pypy-shim (auto-detected)
  • leynos/whitaker (auto-detected)

Comment thread docs/developers-guide.md Outdated
Comment thread tests/helpers/maturin.py
Comment thread tests/helpers/maturin.py Outdated
Comment thread tests/helpers/maturin.py Outdated
@pandalump

Copy link
Copy Markdown
Collaborator

The Testing (Unit And Behavioural) row came back Inconclusive ("placeholder | need evidence"), so I validated it myself, scoped to this PR. Recording the evidence rather than leaving the row to come back inconclusive next round.

What this PR changes. It is a pure refactor with no behaviour change: pin-reading logic moves from tests/helpers/maturin.py into its sole consumer cuprum/unittests/test_maturin_build.py as private helpers, and the wheel-snapshot parsing is consolidated. No production (cuprum/) code is touched — the diff is one test module, one test helper, and the developers guide.

Strongest evidence — the snapshot is byte-identical. test_maturin_wheel_build_snapshot builds a real release wheel and compares metadata, Root-Is-Purelib, generator, and the full normalised entry list against the stored .ambr. It passes unchanged, i.e. the refactor did not alter wheel_build_snapshot's observable output. That snapshot also exercises every branch of _normalise_wheel_entry (dist-info suffixes, /sboms/, and the .cpython-<platform>.so extension module), which is why none of them were removed as speculative.

Coverage of the changed surface. All 14 tests in the module pass, and every retained and inlined symbol is exercised:

Symbol Exercised by
build_native_wheel_artifact test_build_native_wheel_artifact_uses_locked_cargo_deps, ..._reports_maturin_stderr, snapshot test
MaturinBuildError test_build_native_wheel_artifact_reports_maturin_stderr
wheel_build_snapshot (+ _read_wheel_members, _parse_wheel_header, _parse_metadata, _normalise_wheel_entry) test_maturin_wheel_build_snapshot
toolchain_available snapshot test skip guard
_read_maturin_pins test_maturin_pins_are_synchronized
_read_expected_maturin_version test_installed_maturin_matches_expected_pin, snapshot test
_read_manylinux_aarch64_container_ref test_manylinux_aarch64_container_is_pinned_to_sha256
_workflow_uses_manylinux_aarch64_container_ref test_manylinux_aarch64_container_is_referenced_by_build_step
pin/container regexes 5 parametrised rejection cases + 2 regex-negative tests

Gates. make check-fmt, make lint (ruff, interrogate 100%, pylint 10.00/10), make test (full suite plus Rust nextest), make markdownlint, and make nixie are all green.

No new behaviour is introduced by this PR, so no new tests are warranted beyond the existing suite continuing to pass against the refactored code — which it does.

codescene-access[bot]

This comment was marked as outdated.

@leynos

leynos commented Jul 28, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following now been resolved?

  • In the pin-synchronisation helpers in test_maturin_build.py, pyproject.toml and the workflow/action YAML files are read multiple times within the same test run (e.g., _read_expected_maturin_version and _read_maturin_pins each re-open pyproject.toml), so consider caching these file contents per test module (e.g., via a small module-level cache or a fixture) to avoid redundant I/O and keep the helpers simpler.
  • In wheel_build_snapshot, the inline logic for locating the .dist-info/WHEEL entry and deriving the METADATA entry is now embedded directly in the function; if you intend to reuse this logic elsewhere, consider extracting a small internal helper (e.g., _dist_info_paths) to clarify the intent and make the error handling around missing WHEEL/METADATA entries easier to test and maintain.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Changed files =='
git diff --name-only origin/main...HEAD -- \
  cuprum/unittests/test_maturin_build.py \
  tests/helpers/maturin.py \
  docs/developers-guide.md

printf '%s\n' '== Test module outline =='
ast-grep outline cuprum/unittests/test_maturin_build.py --items all \
  --match 'maturin|pin|workflow|container' --view expanded || true

printf '%s\n' '== Helper module outline =='
ast-grep outline tests/helpers/maturin.py --items all \
  --match 'wheel|member|metadata|snapshot' --view expanded || true

printf '%s\n' '== Pin-reading helpers and calls =='
rg -n -A18 -B4 \
  'def _read_(expected_maturin_version|maturin_pins|manylinux_aarch64_container_ref)|def _workflow_uses_manylinux_aarch64_container_ref|read_text\(' \
  cuprum/unittests/test_maturin_build.py

printf '%s\n' '== Wheel member extraction and snapshot use =='
rg -n -A35 -B5 \
  'def _read_wheel_members|def wheel_build_snapshot|ZipFile|dist-info/WHEEL|METADATA' \
  tests/helpers/maturin.py

Length of output: 1413


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Test module: relevant declarations and uses =='
rg -n -A24 -B5 \
  '^(def _read_expected_maturin_version|def _read_maturin_pins|def _read_manylinux_aarch64_container_ref|def _workflow_uses_manylinux_aarch64_container_ref)|\b(_read_expected_maturin_version|_read_maturin_pins|_read_manylinux_aarch64_container_ref|_workflow_uses_manylinux_aarch64_container_ref)\(' \
  cuprum/unittests/test_maturin_build.py

printf '%s\n' '== Test module: every filesystem read =='
rg -n -C3 '\.read_text\(|open\(' cuprum/unittests/test_maturin_build.py || true

printf '%s\n' '== Helper module: wheel member extraction and caller =='
rg -n -A45 -B6 \
  '^(def _read_wheel_members|def wheel_build_snapshot)|ZipFile|dist-info/WHEEL|METADATA' \
  tests/helpers/maturin.py

Length of output: 13460


@leynos: Treat the two items separately:

  1. Pin-reading content cache — not resolved.
    _read_text() directly calls Path.read_text() (Line 59). The tests still reread pyproject.toml through _read_expected_maturin_version() (Line 65) and _read_maturin_pins() (Line 74), while build-wheels.yml is reread by both container helpers (Lines 96 and 105). Add a narrowly scoped cache or pass already-read content between the local helpers if eliminating that repeated I/O remains desired.

  2. Wheel member lookup extraction — resolved.
    tests/helpers/maturin.py now uses _read_wheel_members() (Lines 164–178) to locate .dist-info/WHEEL, derive/read METADATA, and report a missing WHEEL member. wheel_build_snapshot() delegates to it at Line 218, so this logic is no longer embedded inline.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/developers-guide.md`:
- Around line 1403-1410: Update the regex ownership wording in the documentation
around the “shared regex” reference so it identifies the private test-local
regexes in test_maturin_build.py, consistent with the documented helpers and
regexes being inlined there. Do not describe them as shared.
- Around line 1417-1420: Update the documentation around
test_installed_maturin_matches_expected_pin to describe its actual check: it
verifies the installed maturin package version from current-interpreter metadata
via importlib.metadata.version("maturin"), while only gating on the CLI being
available on PATH; alternatively, change the implementation to obtain the
version with maturin --version.

In `@tests/helpers/maturin.py`:
- Around line 178-185: Reduce the _read_wheel_members docstring to a single-line
summary of its return value, removing the Raises section and its assertion
details while preserving any non-obvious guarantee needed by callers.
- Around line 81-84: Update the maturin availability check in the helper to
import the maturin module directly instead of calling importlib.util.find_spec,
and keep the ImportError fallback setting maturin_available to False. The check
must only report availability when the import succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b00727e6-01fd-4901-8543-64e2040a5c87

📥 Commits

Reviewing files that changed from the base of the PR and between 302858c and cc49f1f.

📒 Files selected for processing (3)
  • cuprum/unittests/test_maturin_build.py
  • docs/developers-guide.md
  • tests/helpers/maturin.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/shared-actions (auto-detected)
  • leynos/pylint-pypy-shim (auto-detected)
  • leynos/whitaker (auto-detected)

Comment thread docs/developers-guide.md Outdated
Comment thread docs/developers-guide.md Outdated
Comment thread tests/helpers/maturin.py
Comment thread tests/helpers/maturin.py Outdated
@pandalump

Copy link
Copy Markdown
Collaborator

Thanks — took the simplification from the first comment and measured the caching half rather than guessing. The second comment looks to be against a superseded revision.

1. Pin-helper file reads

Applied the deduplication (abf8142). _read_maturin_pins genuinely duplicated _read_expected_maturin_version for its pyproject.toml entry — same read, same regex, same location string. It now delegates, so "how to read the pyproject pin" lives in one place:

"pyproject.toml": _read_expected_maturin_version(root),

Declined the caching, with numbers. A full run of the module performs seven reads totalling ~69 KiB:

File Reads per run
pyproject.toml (13.6 KiB) 3
.github/workflows/build-wheels.yml (9.4 KiB) 3
.github/actions/build-wheels/action.yml (1.8 KiB) 1

Measured wall-clock for all seven reads together: 0.124 ms, against a 1.32 s module runtime — 0.009%, and that 1.32 s is with an already-built wheel; a cold run spends seconds in maturin build. So the redundant I/O is unmeasurable in practice.

On the "keep the helpers simpler" half: a module-level cache or fixture would make them less simple, not more — it adds shared mutable state, an invalidation question (these files are read to detect drift, so a stale cache is a correctness hazard rather than a perf trade), and a test-isolation concern. That is exactly the speculative-abstraction pattern #97 and #99 asked this PR to remove, so adding one here would work against its purpose. The delegation above captures the real simplification without any of that.

2. _dist_info_paths in wheel_build_snapshot

This appears to be against an earlier revision. The WHEEL/METADATA logic is not embedded in wheel_build_snapshot — it was extracted in 724c455, and the function is now a three-line orchestrator:

entry_names, wheel_payload, metadata_payload = _read_wheel_members(whl_path)
generator, root_is_purelib = _parse_wheel_header(wheel_payload, whl_path)
return {...}

_read_wheel_members already owns locating the .dist-info/WHEEL entry, deriving the METADATA name, and guarding both. On the error handling being "easier to test": that is already covered, and through the public entry point rather than a private helper — test_wheel_build_snapshot_reports_missing_dist_info is parametrised over both missing-member cases. I checked it is non-vacuous rather than assuming: removing the METADATA guard makes it fail with the KeyError from ZipFile.read that the guard exists to prevent.

Splitting a further _dist_info_paths out of _read_wheel_members would separate path resolution from I/O, which has some appeal — but your suggestion is conditioned on intending to reuse the logic elsewhere, and there is no second consumer. Deferring extraction until one exists is the explicit resolution in #99, so I have left it. Happy to revisit if a second caller turns up.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

Three of the four applied in 8dc5353; one was already satisfied. Details below.

1. toolchain_available — direct import ✅

Valid, and the distinction is real rather than stylistic. find_spec reports success for a module that is findable but fails to import — a broken native dependency, say — whereas the build runs python -m maturin, which needs it to actually import. Now:

try:
    importlib.import_module("maturin")
except ImportError:
    maturin_available = False
else:
    maturin_available = True

I confirmed the two genuinely differ rather than assuming it. Installing a meta-path finder that returns a spec whose loader raises on exec:

find_spec reports available: True
import reports available: False  ( broken native dependency )

2. _read_wheel_members docstring ✅

Valid. Its neighbours in the module — _parse_metadata, _normalise_wheel_entry, _parse_wheel_header — are all one-line, so the Raises block on this private helper was the outlier.

Reduced to a single line that still carries the non-obvious guarantee, since that is precisely the part a caller cannot infer:

"""Return entry names and decoded ``WHEEL``/``METADATA``, asserting both exist."""

The reason it asserts rather than letting ZipFile.read raise KeyError stays as the comment beside the check, where it belongs.

3. test_installed_maturin_matches_expected_pin wording ✅

Valid — the guide said it "compares the installed CLI against the pyproject.toml pin", which is wrong on both halves of the mechanism. The test reads the installed distribution's version from the current interpreter's package metadata via importlib.metadata.version("maturin"), and only gates on a maturin CLI being present on PATH.

I took the documentation option rather than switching to maturin --version, because the metadata is the right thing to read: build_native_wheel_artifact runs sys.executable -m maturin, so the interpreter's package is exactly the maturin that builds wheels. A CLI on PATH could be a different installation entirely. The wording now states both the metadata source and the CLI gate.

Worth flagging, since it is adjacent but out of scope for a wording fix: the gate and the check use different signals, so on a machine with the package installed but no CLI on PATH the test skips despite being able to run, and in the inverse case importlib.metadata.version would raise PackageNotFoundError rather than skipping. Happy to align the gate with the check (skip on module import failure) if you would like that as a follow-up — I have left the behaviour alone here to keep the change minimal.

4. "Shared regex" wording — skipped ⏭️

No correction was needed: nothing described the regexes as shared. The passage already read "inlined there as private helpers (… and their regexes)", and the only occurrence of "shared" in the section is the shared interface can be designed against real requirements, which is about the reuse policy for tests/helpers/maturin.py, not about the regexes.

That said, the wording evidently read ambiguously, so I tightened it at negligible cost — the sentence now names them explicitly as module-private constants local to the test file rather than folding them into "and their regexes".

Validation

Command Outcome
uv run pytest cuprum/unittests/test_maturin_build.py 16 passed (incl. the wheel-build snapshot)
make check-fmt pass
make lint pass (ruff, interrogate 100%, pylint 10.00/10, clippy)
make typecheck pass
make test pass — full Python suite, Rust nextest 57/57
make markdownlint / make nixie pass

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@buzzybee-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai review

Rebasing onto main combined two independent decompositions of the same
surface. Main extracted wheel inspection into
`tests/helpers/maturin_wheel.py` and added `maturin_script_locatable`
with three tests; this branch inlined the pin readers into their sole
consumer. Both landed, which left `test_maturin_build.py` at 446 lines —
past the 400-line limit, and mixing three concerns.

Split it the way the helpers already are: pin synchronization in
`test_maturin_pins.py`, the availability detectors in
`test_maturin_toolchain.py` beside the `toolchain_available` tests they
sit next to, and the wheel build and snapshot in `test_maturin_build.py`.

One reader resists inlining. `read_expected_maturin_version` now has two
consumers — the pin comparison and the wheel snapshot's `Generator`
assertion — which is exactly the second concrete consumer this branch's
own re-use policy names as the condition for sharing. It moves to
`_maturin_pin_support.py`; the readers with one consumer stay put.

Repoint `test_manylinux_container_ref_properties.py`, which imported the
container regex from the module that was split, and refresh the wheel
manifest for the new files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lodyai
lodyai Bot force-pushed the simplify-maturin-helper branch from a799f4a to 19a3d58 Compare July 31, 2026 19:48
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/developers-guide.md (1)

1660-1662: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the toolchain_available() implementation description.

State that toolchain_available() imports maturin with
importlib.import_module. It does not use importlib.util.find_spec.
Retain the cargo and rustc availability checks. The current text describes
the wrong broken-import boundary.

Triage: [type:docstyle]

Based on supplied helper context, toolchain_available uses
importlib.import_module.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/developers-guide.md` around lines 1660 - 1662, Update the
toolchain_available() documentation to state that it imports maturin via
importlib.import_module, removing the incorrect importlib.util.find_spec
description while retaining the cargo and rustc PATH availability checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cuprum/unittests/_maturin_pin_support.py`:
- Around line 21-56: Expand the docstrings for require_pin_match, read_text, and
read_expected_maturin_version to follow NumPy style, adding Parameters, Returns,
and Raises sections that describe each argument, return value, and
AssertionError or file-reading exception raised. Preserve the existing behavior
and implementation of these helpers.

In `@cuprum/unittests/test_manylinux_container_ref_properties.py`:
- Line 8: Move the shared _MANYLINUX_CONTAINER_SHA256_RE definition from
test_maturin_pins.py into _maturin_pin_support.py, then update both
test_maturin_pins.py and test_manylinux_container_ref_properties.py to import it
from the support module. Remove the test-to-test import and preserve the
existing regex behavior.

In `@cuprum/unittests/test_maturin_build.py`:
- Around line 167-205: Remove the redundant standalone
test_wheel_build_snapshot_rejects_wheel_without_metadata test, while preserving
the missing_metadata case in test_wheel_build_snapshot_reports_missing_dist_info
as the sole coverage for absent METADATA and its exact diagnostic.

In `@cuprum/unittests/test_maturin_pins.py`:
- Around line 88-96: Update test_installed_maturin_matches_expected_pin to
verify maturin through importlib.import_module("maturin") rather than
shutil.which("maturin"), skipping only when the import raises ImportError.
Remove the unused shutil import and adjust the docstring to describe the current
interpreter’s maturin module.

In `@cuprum/unittests/test_maturin_toolchain.py`:
- Around line 152-153: Update the test around toolchain_available() to capture
the raised RuntimeError with pytest.raises as exc_info, then assert
str(exc_info.value) exactly equals the complete expected diagnostic, preserving
the existing explanatory assertion message.

In `@tests/helpers/maturin.py`:
- Around line 1-11: Update the module docstring to identify
cuprum/unittests/test_maturin_pins.py as the owner of pin-synchronization
checks, and separately state that test_maturin_build.py consumes the shared
expected-version reader for wheel validation. Remove the current wording that
identifies test_maturin_build.py as the sole consumer.

---

Outside diff comments:
In `@docs/developers-guide.md`:
- Around line 1660-1662: Update the toolchain_available() documentation to state
that it imports maturin via importlib.import_module, removing the incorrect
importlib.util.find_spec description while retaining the cargo and rustc PATH
availability checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1d68aaa7-0b23-467a-a895-f66c3ef08b89

📥 Commits

Reviewing files that changed from the base of the PR and between 8dc5353 and 19a3d58.

📒 Files selected for processing (8)
  • cuprum/unittests/__snapshots__/test_maturin_build.ambr
  • cuprum/unittests/_maturin_pin_support.py
  • cuprum/unittests/test_manylinux_container_ref_properties.py
  • cuprum/unittests/test_maturin_build.py
  • cuprum/unittests/test_maturin_pins.py
  • cuprum/unittests/test_maturin_toolchain.py
  • docs/developers-guide.md
  • tests/helpers/maturin.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/shared-actions (auto-detected)
  • leynos/pylint-pypy-shim (auto-detected)
  • leynos/whitaker (auto-detected)

Comment thread cuprum/unittests/_maturin_pin_support.py
Comment thread cuprum/unittests/test_manylinux_container_ref_properties.py Outdated
Comment thread cuprum/unittests/test_maturin_build.py
Comment thread cuprum/unittests/test_maturin_pins.py
Comment thread cuprum/unittests/test_maturin_toolchain.py Outdated
Comment thread tests/helpers/maturin.py
Six review findings on the maturin test split.

`_MANYLINUX_CONTAINER_SHA256_RE` had two consumers, one of which reached
into the other test module for a private name. Move it beside
`read_expected_maturin_version` in `_maturin_pin_support.py`, which is
what the two-consumer threshold already asks for, and make it public
since it is now a shared symbol rather than a module-local one.

Document the read failures the helpers can raise. `read_text` and
`read_expected_maturin_version` touch the filesystem while returning
plain `str`, so `OSError` and `UnicodeDecodeError` were reachable but
unadvertised. They stay uncaught deliberately — a renamed CI file is a
genuine failure, and its own traceback names the path better than a
wrapper would — but that is now stated rather than implied.

Skip the installed-version check on the maturin *module* rather than on
a `PATH` launcher. The build runs `python -m maturin` in the current
interpreter, so a launcher from another environment would have let the
test compare a version the build never uses.

Drop `test_wheel_build_snapshot_rejects_wheel_without_metadata`: the
`missing_metadata` parametrized case covers the same failure and
compares the message exactly. Its rationale about `metadata_name` being
derived by substitution moves into the case that survives.

Assert the toolchain import diagnostic exactly, for the reason already
applied to the wheel cases — `match=` searches, so a prefix or suffix
would slip through.

Correct three stale claims in the guide: `toolchain_available` uses
`import_module`, not `find_spec`; the manylinux command targets
`test_maturin_pins.py` after the split; and the skip boundary is the
module, not `PATH`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cuprum/unittests/test_maturin_pins.py (1)

133-137: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add diagnostics to the changed assertions.

The same test-guideline gap appears at all four sites. Add a short contract-specific message to each assertion.

  • cuprum/unittests/test_maturin_pins.py#L133-L137: describe why the invalid container reference must be rejected.
  • cuprum/unittests/test_manylinux_container_ref_properties.py#L21-L21: describe why a valid digest reference must match.
  • cuprum/unittests/test_manylinux_container_ref_properties.py#L35-L35: describe why mutable tags must be rejected.
  • cuprum/unittests/test_manylinux_container_ref_properties.py#L43-L43: describe why truncated digests must be rejected.

As per path instructions, “Use assert …, "message" over bare asserts.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cuprum/unittests/test_maturin_pins.py` around lines 133 - 137, Add
contract-specific assertion messages at all four sites: in
cuprum/unittests/test_maturin_pins.py lines 133-137, explain that invalid or
mutable manylinux AArch64 container references must be rejected; in
cuprum/unittests/test_manylinux_container_ref_properties.py lines 21, 35, and
43, explain respectively why valid digest references must match, mutable tags
must be rejected, and truncated digests must be rejected. Use assert condition,
"message" for each assertion.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@cuprum/unittests/test_maturin_pins.py`:
- Around line 133-137: Add contract-specific assertion messages at all four
sites: in cuprum/unittests/test_maturin_pins.py lines 133-137, explain that
invalid or mutable manylinux AArch64 container references must be rejected; in
cuprum/unittests/test_manylinux_container_ref_properties.py lines 21, 35, and
43, explain respectively why valid digest references must match, mutable tags
must be rejected, and truncated digests must be rejected. Use assert condition,
"message" for each assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 798198ac-538d-4410-ae0a-8fbae3d3e29c

📥 Commits

Reviewing files that changed from the base of the PR and between 19a3d58 and 3775d96.

📒 Files selected for processing (7)
  • cuprum/unittests/_maturin_pin_support.py
  • cuprum/unittests/test_manylinux_container_ref_properties.py
  • cuprum/unittests/test_maturin_build.py
  • cuprum/unittests/test_maturin_pins.py
  • cuprum/unittests/test_maturin_toolchain.py
  • docs/developers-guide.md
  • tests/helpers/maturin.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/shared-actions (auto-detected)
  • leynos/pylint-pypy-shim (auto-detected)
  • leynos/whitaker (auto-detected)

The guide had two passages describing what
`test_installed_maturin_matches_expected_pin` gates on. The previous
round fixed one; this paragraph still said it gates "on a `maturin` CLI
being present on `PATH`", contradicting both the code and the corrected
text further down.

State the actual boundary — the running interpreter being able to import
the module — and the reason it matters: the build runs `python -m
maturin`, so a launcher earlier on `PATH` can belong to an entirely
different environment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

Four assertions on the manylinux pin pattern carried no message, so a
failure reported only `assert None` or `assert <re.Match>` — true but
useless to whoever hits it.

Give each one the contract it is defending rather than a restatement of
the expression: a mutable tag can be republished under the same name, a
truncated digest identifies no single image, and rejecting a valid
64-character digest would block a legitimate bump. Each message
interpolates the reference that failed, so the case is visible without
re-running under a debugger.

Verified by breaking the pattern and confirming all four messages
surface.

The Developer Documentation warning in the same round needed no change:
it cites the paragraph corrected in 5e7efed, and the review was
submitted against 3775d96.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@pandalump

Copy link
Copy Markdown
Collaborator

Both warnings from this round, addressed.

Developer Documentation — already fixed. The cited paragraph was corrected in 5e7efed; this review was submitted against 3775d96, so it evaluated the version before that commit. The guide now says the test gates on the running interpreter being able to import maturin, and gives the reason: the build runs python -m maturin, so a launcher earlier on PATH can belong to a different environment. There were two such paragraphs and the earlier round only fixed one, which is what this check caught the remainder of.

Linked Issues — taking the second branch of the suggested resolution, "document and justify the second concrete consumer".

Both issues state the governing rule as "defer any re-extraction into a shared helper module until a second concrete consumer exists" (#99), and #97 asks to inline logic that at the time had "a single consumer". That threshold is met, and only for the symbols that meet it:

Symbol Consumer 1 Consumer 2
read_expected_maturin_version pin comparison in test_maturin_pins.py wheel Generator assertion in test_maturin_build.py
MANYLINUX_CONTAINER_SHA256_RE container-pin assertion in test_maturin_pins.py generated references in test_manylinux_container_ref_properties.py

Everything else stayed inlined: _WORKFLOW_PIN_RE, _ACTION_PIN_RE, _AARCH64_CONTAINER_PIN_RE, _AARCH64_CONTAINER_USAGE_RE, _read_maturin_pins, _read_manylinux_aarch64_container_ref, and _workflow_uses_manylinux_aarch64_container_ref all have exactly one consumer and remain module-local in test_maturin_pins.py.

On the literal wording: the issues name test_maturin_build.py because that was the only maturin test module when they were written — #99 refers to "the three tests in test_maturin_build.py". A previous review round in this PR asked for that module to be split by concern, which produced test_maturin_pins.py, test_maturin_toolchain.py, and test_maturin_build.py. Inlining the pin readers into test_maturin_build.py today would put them in the module that no longer owns the pin checks.

Worth noting the two findings in this same round point opposite ways: this check asks for _maturin_pin_support.py to be dissolved, while the inline review comment on test_manylinux_container_ref_properties.py asked for MANYLINUX_CONTAINER_SHA256_RE to be moved into it — which I did, because it stopped one test module importing a private name from another.

Rationale is recorded in the module docstring of cuprum/unittests/_maturin_pin_support.py and under "Maturin pin synchronization and native wheel tests" in docs/developers-guide.md.

codescene-access[bot]

This comment was marked as outdated.

codescene-access[bot]

This comment was marked as outdated.

The finding cited four sites and called them "all four". There were six:
`test_manylinux_aarch64_container_pin_regex_rejects_missing_comment` and
`test_manylinux_aarch64_container_usage_regex_rejects_literal_image`
carry the same guideline gap and went uncited.

Both defend something a bare `assert None` cannot convey. The pin
pattern must reject a digest with no trailing comment, because that
comment records which tag the digest came from — without it a reviewer
cannot tell what a bump is bumping to. The usage pattern must reject a
literal image reference, because the build step has to read
`env.MANYLINUX_AARCH64_CONTAINER`; otherwise the pin every other test in
this module checks is not what the job actually pulls.

Verified by inverting both conditions and confirming each message
surfaces. No bare assertions remain in any file this PR touches.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
codescene-access[bot]

This comment was marked as outdated.

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

No quality gates enabled for this code.

@pandalump

Copy link
Copy Markdown
Collaborator

Both remaining ⚠️ pre-merge warnings were checked against head 2f5cf700. Neither needs a code change; evidence below. (The other seven entries are ❓ Inconclusive — investigation budget, not defects.)


1. Developer Documentation — already resolved at head

The finding says lines 1581–1585 "still say the installed-version test gates on a CLI in PATH". That wording was removed by 5e7efed ("Correct the second stale PATH claim about the maturin skip"), which is an ancestor of the reviewed commit 2f5cf700, so the pre-merge table appears to have evaluated a tree earlier than the one it names.

At head, docs/developers-guide.md states the import boundary in both places:

  • 1581–1589 — "…and gates on that interpreter being able to import maturin, not on a CLI being present on PATH. A launcher found on PATH can belong to a different environment from the one the build uses."
  • 1637–1643 — "Skipped automatically when the maturin module cannot be imported by the running interpreter. That is the right boundary rather than PATH, because the build runs python -m maturin…"

That matches the code, cuprum/unittests/test_maturin_pins.py:97-100:

try:
    importlib.import_module("maturin")
except ImportError:
    pytest.skip("maturin is not installed in this interpreter.")

A sweep of docs/, README.md, AGENTS.md, and CHANGELOG.md for the PATH claim turns up no other occurrence. The two surviving PATH mentions nearby (1665, 1671) describe maturin_script_locatable() and toolchain_available(), and are correct: toolchain_available() genuinely does check for cargo and rustc on PATH.

No edit made.


2. Linked Issues check — the second concrete consumer exists, and pre-dates this PR

The recommendation offers a choice: inline the pin logic, or "document and justify the second concrete consumer that requires the new shared module". #97 and #99 both phrase the bar the same way — defer extraction "until a second concrete consumer exists". That bar is met, so the second branch applies. Naming the consumers:

MANYLINUX_CONTAINER_SHA256_RE — two consumers, and the second is not an artefact of this PR:

  • cuprum/unittests/test_maturin_pins.py:111,137 — asserts the live workflow pin is digest-pinned and rejects the mutable-tag comment.
  • cuprum/unittests/test_manylinux_container_ref_properties.py:21,39,50 — Hypothesis-generated references probing the same pattern.

On origin/main that property module already had this dependency, and satisfied it by reaching across test modules for a private name: from cuprum.unittests.test_maturin_build import _MANYLINUX_CONTAINER_SHA256_RE. The second consumer therefore existed before this PR; what the PR changed is that it is no longer served by importing a private symbol out of another test module.

read_expected_maturin_version (with the read_text / require_pin_match it is built from) — two consumers in distinct tests asserting distinct things:

  • cuprum/unittests/test_maturin_pins.py:50,101 — the three-way pin synchronization across pyproject.toml, build-wheels.yml, and action.yml, plus the installed-version comparison.
  • cuprum/unittests/test_maturin_build.py:117 — the built wheel's Generator metadata must match the same pin.

Inlining it would mean either duplicating the reader in both modules or reinstating a private cross-module import. The first is exactly what CodeScene flagged: cs delta origin/main HEAD records cuprum/unittests/test_maturin_build.py code health 9.38 → 10.00 with "Fixed issue: Code Duplication — the module no longer contains too many functions with similar structure". Inlining would trade that back.

There is also a hard constraint. Pylint's max-module-lines = 400 (pyproject.toml:193) is enforced in the gate. test_maturin_pins.py (171) + test_maturin_build.py (187) + _maturin_pin_support.py (153) is ~490 lines; a single module holding the inlined logic and both sets of tests cannot fit under the cap.

Worth being explicit that the issues' substantive complaints were actioned: the speculative platform-variability normalization is gone, the pin readers with only one consumer stayed inlined in test_maturin_pins.py, and only the two symbols with a genuine second consumer were externalized. _maturin_pin_support.py is 153 lines carrying two functions, one helper, and two patterns — not a restatement of the 12-function module the issues objected to.

The justification is already documented where a reader will meet it:

  • cuprum/unittests/_maturin_pin_support.py:1-17 — module docstring, opening "Nothing lives here on the strength of a single caller", then naming both consumers of each symbol.
  • docs/developers-guide.md:1553-1565 — the same, framed as the policy threshold, plus 1597-1600 restating that the policy is to stay this way and not re-externalize further until a second concrete consumer exists.

No edit made.


Verification run: uv run pytest over test_maturin_pins.py, test_maturin_build.py, test_maturin_toolchain.py, and test_manylinux_container_ref_properties.py — 28 passed, 1 snapshot passed. cs delta origin/main HEAD — one entry, the improvement above, no issues introduced.

@pandalump

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
leynos merged commit d5f4c88 into main Aug 3, 2026
20 checks passed
@leynos
leynos deleted the simplify-maturin-helper branch August 3, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

3 participants