Skip to content

Add Rust, PyO3, and Maturin chapter (fills the 03_rust stub)#32

Merged
thewtex merged 10 commits into
scikit-build:mainfrom
thewtex:rust
Jul 12, 2026
Merged

Add Rust, PyO3, and Maturin chapter (fills the 03_rust stub)#32
thewtex merged 10 commits into
scikit-build:mainfrom
thewtex:rust

Conversation

@thewtex

@thewtex thewtex commented Jul 11, 2026

Copy link
Copy Markdown
Member

Summary

Fills the Rust bindings chapter (content/compiled/03_rust.md), which currently
exists only as a stub heading, with a complete Rust, PyO3, and Maturin chapter —
plus a runnable PyO3 example project, a matching Marp slide deck, and a set of
instructor-facing research notes.

Rebased on current main, so the chapter drops straight into the existing Compiled
TOC slot (01_compiled → 02_binding → 03_rust → 04_cibuildwheel); the 03_rust.md
stub is replaced in place and no renumbering is needed.

Why

The Compiled section covers pybind11/nanobind (C++) but leaves Rust as an empty
03_rust.md stub. Rust + PyO3 + maturin is now a mainstream way to ship compiled
Python extensions, so the section needs a self-contained, teachable chapter that
mirrors the book's existing "install-and-lock with pixi" approach and requires no
rustup or system Rust.

What's included

Book chaptercontent/compiled/03_rust.md (fills the existing TOC slot). Walks
from motivation through a first extension to shipping wheels: Why Rust → the toolchain
stack → pixi setup → a first extension → build/iterate loop → benchmarking → classes →
native-feeling errors → the GIL and free-threading → shipping wheels → exercises →
where to go next.

Runnable exampleexamples/2_04_rust_pyo3/, a minimal pixi-managed PyO3
extension. src/lib.rs exposes a GIL-releasing count_primes, a Point #[pyclass],
a sum_as_string function, and a checked_div that raises a Python exception; with a
pytest suite (tests/) and a pure-Python-vs-Rust benchmark (bench.py). Every tool —
the Rust compiler, maturin, Python, pytest — installs from conda-forge via pixi, and
pixi run test / pixi run bench chain a build in front so they never run against a
stale extension.

Slide deckslides/2_03_rust.md, a Marp deck (theme: simplepy) tracking the
chapter for live presentation.

Instructor notesinstructor-notes/: four research notes (PyO3 current state,
maturin workflows, the pixi/conda-forge Rust toolchain, and the Rust-for-Pythonistas
landscape) plus a synthesis deep-dive with a 30-minute teaching runbook. These carry
Obsidian-style frontmatter and [[wiki-links]] and are deliberately kept out of the
myst.yml TOC
, so they are never published into the book. Happy to drop this
directory if it is out of scope for the repo.

Supporting changes

  • AGENTS.md — documents the new examples/ and instructor-notes/ directories and
    scopes the "content, not code" note to the book itself (the example is runnable).
  • .pre-commit-config.yaml — excludes the pixi-generated pixi.lock from prettier
    (consistent with its linguist-generated marking in .gitattributes).
  • .gitignore — ignores agent-local .serena/ tool state (kept alongside the existing
    .venv/ / build/ ignores).

Notes for reviewers

  • All prose uses ASCII punctuation (no em/en dashes).
  • The example directory keeps the name examples/2_04_rust_pyo3/ because the chapter's
    verbatim captured build transcripts print that path; happy to renumber it to
    2_03_rust_pyo3 if you'd prefer directory numbering to track the chapter, at the cost
    of editing the captured output.
  • Instructor-note technical claims were fact-checked against primary sources (PyO3 0.29
    docs, maturin 1.14.1 CLI output, the conda-forge rust feedstock, PEP 803); the
    benchmark timings were captured from a real pixi run bench.
  • bun run build-book / build-slides build cleanly and pre-commit/prek passes.

🤖 Generated with Claude Code

thewtex and others added 7 commits July 11, 2026 15:34
Adds content/compiled/04_rust_pyo3.md from motivation through a first
working build: Why Rust?, the Rust-to-Python stack translation table,
pixi-managed toolchain setup, the annotated pyo3_example project files,
and the maturin develop / REPL loop. All embedded code is verbatim from
examples/2_04_rust_pyo3/ (committed here as well); all transcripts were
captured from real runs. In the example, the PyZeroDivisionError import
moved into checked_div so page excerpts are self-contained (pytest: 8
passed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
From benchmark to shipping: 'How fast is it?' (bench.py + real 19x
measurement + debug-vs-release warning), 'Classes' (Point pyclass),
'Errors that feel native' (checked_div + genuine ZeroDivisionError
traceback), 'The GIL (and life without it)' (py.detach +
free-threading dropdown), 'Shipping wheels' (real maturin build
--release transcript, abi3 in plain text, generate-ci/cibuildwheel),
'Try it yourself' exercise, and 'Where to go next' links.

All code blocks verified verbatim against examples/2_04_rust_pyo3/;
all transcripts captured from real runs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Snippet-verification pass over content/compiled/04_rust_pyo3.md: all 8
:filename: code blocks diff clean against examples/2_04_rust_pyo3/ (full
files or explicitly elided verbatim excerpts), and every pycon/console
transcript was replayed. The one transcript without a recorded capture
(pixi run develop) was re-run and re-pasted; all others reproduce.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measured every rendered slide with a headless browser: seven slides ran
past the bottom of the 1280x720 Marp canvas even though every code block
respected the 15-line/80-char source guideline. Trimmed the pixi.toml
snippet to a 10-line elided subset, condensed bullets to fewer rendered
lines, elided two transcript lines, and unsplit the further-reading line
so it wraps naturally. All 16 slides now end at or above the density of
the existing 2_03 deck; no code block overflows horizontally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cross-checking the deck against the section found one rewritten (not
elided) console line: real maturin output is 'Built wheel for CPython
3.14 to <path>'. Use the deck's established '...' elision style instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- instructor-notes/: four research notes (PyO3 current state, maturin
  workflows, pixi Rust toolchain, Rust-for-Pythonistas landscape) plus
  a deep-dive synthesis for teaching the 30-minute segment
- AGENTS.md: document examples/ and instructor-notes/ in Structure and
  scope the 'no code to test' claim to the book itself
- .pre-commit-config.yaml: exclude generated pixi.lock from prettier
  (matches its linguist-generated marking in .gitattributes)
- .gitignore: ignore agent-local .serena/ state
- content/compiled/04_rust_pyo3.md: collapse the 'No rustup' tip into
  a dropdown
- examples/2_04_rust_pyo3/README.md: refresh benchmark timing from a
  fresh run

Code-review fixes (CodeRabbit findings verified against primary
sources before applying): recommend pixi install --locked over
--frozen; correct maturin generate-ci publishing default (API token
via uv publish; trusted publishing is opt-in); mark
pyo3/extension-module redundant with PyO3 0.26+ under maturin;
pyclass requires Send + Sync (unsendable waives Send); abi3t is
CPython 3.15+ while 3.14t needs cp314t wheels; precise rust-src/
rust-docs target list; per-language compiler-package rule of thumb.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@thewtex thewtex changed the title Add Rust, PyO3, and Maturin chapter (book, example, slides, instructor notes) Add Rust, PyO3, and Maturin chapter (fills the 03_rust stub) Jul 11, 2026
@thewtex thewtex requested review from Copilot and henryiii July 11, 2026 19:40

Copilot AI 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.

Pull request overview

This PR fills the previously-stubbed Rust bindings chapter with a complete Rust/PyO3/maturin walkthrough, adds a runnable pixi-managed PyO3 example project (with tests + benchmark), introduces a matching Marp slide deck, and adds instructor-facing research/deep-dive notes. It also updates contributor docs and housekeeping (pre-commit + gitignore) to accommodate the new content.

Changes:

  • Replace content/compiled/03_rust.md stub with a full Rust/PyO3/maturin chapter aligned to the compiled section flow.
  • Add examples/2_04_rust_pyo3/ (pixi toolchain + maturin backend + Rust extension + pytest suite + benchmark).
  • Add a slide deck and instructor notes/research to support teaching and deeper reference material.

Reviewed changes

Copilot reviewed 17 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
slides/2_03_rust.md New Marp deck covering the Rust/PyO3/maturin content for live instruction.
instructor-notes/rust-pyo3-maturin-deep-dive.md Instructor deep-dive reference + runbook and troubleshooting guidance.
instructor-notes/research/rust-python-landscape.md Research note motivating Rust in Python ecosystems + positioning of this session.
instructor-notes/research/pyo3-current-state.md Research note summarizing PyO3 status, APIs, versioning, and support matrix.
instructor-notes/research/pixi-rust-toolchain.md Research note on conda-forge Rust via pixi, platform/linker realities, and reproducibility.
instructor-notes/research/maturin-workflows.md Research note on maturin workflows, distribution, and CI scaffolding.
examples/2_04_rust_pyo3/tests/test_pyo3_example.py Pytest coverage for the example extension’s exposed API.
examples/2_04_rust_pyo3/src/lib.rs The Rust extension module implementation (functions + Point class + GIL detaching).
examples/2_04_rust_pyo3/README.md Example usage docs + benchmark output and guidance.
examples/2_04_rust_pyo3/pyproject.toml PEP 517/660 backend config for maturin + project metadata.
examples/2_04_rust_pyo3/pixi.toml pixi toolchain + tasks wiring (develop/test/bench) for a reproducible workflow.
examples/2_04_rust_pyo3/pixi.lock Locked conda-forge toolchain/environment for the runnable example.
examples/2_04_rust_pyo3/Cargo.toml Rust crate metadata and PyO3 dependency pin.
examples/2_04_rust_pyo3/Cargo.lock Locked Rust crate dependency graph for the example.
examples/2_04_rust_pyo3/bench.py Pure-Python benchmark paired against the Rust implementation.
examples/2_04_rust_pyo3/.gitignore Ignore build artifacts/caches local to the example directory.
content/compiled/03_rust.md Full Rust/PyO3/maturin chapter replacing the prior stub.
AGENTS.md Updated repo guidance to include examples/ and instructor-notes/.
.pre-commit-config.yaml Exclude pixi.lock from prettier (generated file).
.gitignore Ignore agent-local .serena/ state.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread content/compiled/03_rust.md Outdated
Comment thread instructor-notes/rust-pyo3-maturin-deep-dive.md Outdated
Comment thread examples/2_04_rust_pyo3/src/lib.rs
Comment thread examples/2_04_rust_pyo3/src/lib.rs
thewtex added a commit to thewtex/SIMPLE-Py that referenced this pull request Jul 12, 2026
Address two PR scikit-build#32 review comments:
- content/compiled/03_rust.md: the cibuildwheel cross-link pointed at
  ./03_cibuildwheel.md, but that chapter is 04_cibuildwheel.md (03 is this
  Rust chapter). Fixes a broken link in the rendered book.
- instructor-notes/rust-pyo3-maturin-deep-dive.md: the "teaching hook" bullet
  attributed the plain linux_x86_64 tag to the conda env's glibc failing the
  manylinux policy, which contradicts the chapter transcript showing
  `maturin build --release` producing manylinux_2_28_x86_64 in that same env.
  Reframed as the accurate develop-vs-build distinction: `maturin develop`
  skips the auditwheel relabel; `maturin build` runs it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
thewtex and others added 3 commits July 11, 2026 21:07
Address two PR scikit-build#32 review comments:
- content/compiled/03_rust.md: the cibuildwheel cross-link pointed at
  ./03_cibuildwheel.md, but that chapter is 04_cibuildwheel.md (03 is this
  Rust chapter). Fixes a broken link in the rendered book.
- instructor-notes/rust-pyo3-maturin-deep-dive.md: the "teaching hook" bullet
  attributed the plain linux_x86_64 tag to the conda env's glibc failing the
  manylinux policy, which contradicts the chapter transcript showing
  `maturin build --release` producing manylinux_2_28_x86_64 in that same env.
  Reframed as the accurate develop-vs-build distinction: `maturin develop`
  skips the auditwheel relabel; `maturin build` runs it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Rust chapter used &mdash;/&ndash; HTML entities (which rendered as
em/en-dashes and so slipped past the earlier literal-dash sweep). Replace all
48 &mdash; and 3 &ndash; in content/compiled/03_rust.md with context-appropriate
colons, semicolons, commas, or parentheses, matching the branch's dash-free
style. content/other-tools/03_conda_forge.md is left untouched: it is unchanged
from main and its entities predate this branch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thewtex thewtex merged commit 733e3e9 into scikit-build:main Jul 12, 2026
3 checks passed
@thewtex thewtex deleted the rust branch July 12, 2026 01:09
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.

2 participants