Conversation
* docs: add minimal compiled package example (collatz) Fill in the pybind11/scikit-build-core snippets in the compiled intro chapter and add a runnable copy under examples/2_01_package/collatz. Assisted-by: ClaudeCode:claude-opus-4.8 * feat: add more to page Signed-off-by: Henry Schreiner <henryfs@princeton.edu> * docs: expand compiled package chapter and add slides Add interactive material to the minimal compiled package chapter: a benchmark comparing compiled vs pure Python, a binding-tool tab-set (pybind11/nanobind), a mermaid SDist-vs-wheel flow, a glossary, and exercises for the SDist, wheel, and extending the extension. Also add a name-mismatch caution, an editable/debug iteration section, and fix typos plus the invalid `callout` directive. Add a Marp deck (slides/2_01_package.md) mirroring the chapter and link it from the page. Assisted-by: ClaudeCode:claude-opus-4.8 --------- Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Assisted-by: ClaudeCode:claude-fable-5
Split the compiled "Binding tools" chapter into a pybind11/nanobind page and a separate Rust (maturin, PyO3) page. Renumber the cibuildwheel content and slide to 04 and update cross-references. Assisted-by: ClaudeCode:claude-opus-4.8
The compiled intro chapter shared the `package` filename stem with the basic-packaging chapter, so both produced a `/package` URL. Rename it (and its slide deck) to `compiled`. Assisted-by: ClaudeCode:claude-opus-4.8
Add pybind11 intro material to the binding chapter, covering the basic Simple and Vector2D binding patterns before the Minuit2 example, and a full walkthrough of binding Minuit2 with pybind11. Reorder so the pybind11 intro comes before the Minuit2 sections. Add buildable simpleclass and vectorclass example projects, plus the pybind11 Minuit2 binding and cpponly/nanobind examples. Assisted-by: ClaudeCode:claude-opus-4.8
…build#27) Add an "Intro to nanobind" section before the Minuit2 example and present the Minuit2 binding code, CMake, and pyproject in pybind11/nanobind tabs (synced across the page), matching the new nanobind example. Assisted-by: ClaudeCode:claude-opus-4.8
…les (scikit-build#28) * docs: add free-threading page with pure, pybind11, and nanobind examples Fills in the free-threading chapter with a Monte Carlo pi benchmark shown three ways: pure Python, and compiled inner loops via pybind11 and nanobind (shown side by side in tabs). Each example is a runnable scikit-build-core / hatchling project that scales across cores on a free-threaded (3.14t) build. Assisted-by: ClaudeCode:claude-opus-4.8 * docs: add free-threading slides Marp deck (slides/6_01_free_threading.md) mirroring the chapter: GIL / PEP 703 background, the Monte Carlo pi example, pure Python vs pybind11/nanobind opt-in side by side, and cp314t wheels. Links the deck from the page. Assisted-by: ClaudeCode:claude-opus-4.8
* docs: add slides for the binding-tools chapter The compiled/02_binding chapter (pybind11 and nanobind) was the only non-stub chapter without a Marp deck. Add slides covering pybind11 basics, nanobind's differences, and the Minuit2 wrapping walkthrough, using the two-column layout to show both tools side by side. Assisted-by: ClaudeCode:claude-opus-4.8 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Assisted-by: ClaudeCode:claude-opus-4.8
Fill out the lazy imports chapter from PEP 810 and the flake8-lazy blog post: the problem, the `lazy import` keyword, the back-compat `__lazy_modules__` list, when not to be lazy, the flake8-lazy tool, and results. Add a matching Marp deck and link it from the chapter. Assisted-by: ClaudeCode:claude-opus-4.8
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>
Owner
Author
|
Superseded by the upstream PR against scikit-build/SIMPLE-Py: scikit-build#32 (branch rebased onto current upstream main; chapter folded into the existing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a complete Rust, PyO3, and Maturin chapter to the SIMPLE-Py workshop — a
new book chapter, a runnable PyO3 example project, a Marp slide deck, and a set of
instructor-facing research notes. This fills the "Maturin, PyO3, and Rust" slot that
previously existed only as an empty heading in the Compiled section, giving the
workshop a first-class Rust track alongside its C++ material.
Why
The Compiled section covered pybind11/nanobind (C++) but left Rust as a stub. Rust +
PyO3 + maturin is now a mainstream way to ship compiled Python extensions, so the
workshop needed 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 chapter —
content/compiled/04_rust_pyo3.md(wired intomyst.ymlTOC andcross-linked from
content/compiled/02_binding.md). Walks from motivation through afirst 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 example —
examples/2_04_rust_pyo3/, a minimal pixi-managed PyO3extension.
src/lib.rsexposes a GIL-releasingcount_primes, aPoint#[pyclass],a
sum_as_stringfunction, and achecked_divthat raises a Python exception; witha pytest suite (
tests/) and a pure-Python-vs-Rust benchmark (bench.py). Everything— the Rust compiler, maturin, Python, pytest — installs from conda-forge via pixi, and
pixi run test/pixi run benchchain a build in front so they never run against astale extension.
Slide deck —
slides/2_04_rust_pyo3.md, a Marp deck (theme: simplepy) trackingthe chapter for live presentation.
Instructor notes —
instructor-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 themyst.ymlTOC, so they are never published into the book.Supporting changes
AGENTS.md— documents the newexamples/andinstructor-notes/directories andscopes the "content, not code" note to the book itself (the example is runnable).
.pre-commit-config.yaml— excludes the pixi-generatedpixi.lockfrom prettier(consistent with its
linguist-generatedmarking in.gitattributes)..gitignore— ignores agent-local.serena/tool state.Notes for reviewers
was rewritten so no commit diff introduces those characters.
docs, maturin 1.14.1 CLI output, the conda-forge rust feedstock, PEP 803) and passed a
CodeRabbit review; the benchmark timings were captured from a real
pixi run bench.prek(all hooks) passes andbun run build-book/build-slidesboth build cleanly.🤖 Generated with Claude Code