Module 04 — Maturin

Goal

Package the Rust library so Python can import it as an ordinary module.

From the Python consumer’s point of view there should be no Cargo, no .so hunting, and no special knowledge of the build system.

What Maturin does

Concern Maturin responsibility
Compile the Rust crate Yes
Produce a Python extension module Yes
Build wheels Yes
Development installs maturin develop
Release artifacts maturin build

Create a virtual environment first

maturin develop installs into the active Python environment. Maturin expects a virtualenv (or conda env); it will refuse to install into the system Python.

From the kernel/ directory:

# 1. Create a venv (once)
python3 -m venv .venv

# 2. Activate it
#    Linux / macOS:
source .venv/bin/activate
#    Windows (cmd):
#    .venv\Scripts\activate.bat
#    Windows (PowerShell):
#    .venv\Scripts\Activate.ps1

# 3. Confirm you are inside the venv
which python    # should point at .../kernel/.venv/bin/python
python -c "import sys; print(sys.prefix)"

# 4. Install Maturin into this venv
pip install -U maturin

When the venv is active, your prompt often shows (.env).
To leave the venv later:

deactivate

Optional: named venv elsewhere

python3 -m venv ~/venvs/oe-kernel
source ~/venvs/oe-kernel/bin/activate
pip install -U maturin

Development workflow

# Inside kernel/
maturin develop          # builds + installs into the active environment
python -c "import open_engineering_kernel; print('ok')"

maturin develop is the iterative loop while writing the course exercises.

If you see:

Couldn't find a virtualenv or conda environment

the venv is not active - run source .venv/bin/activate (or Windows equivalent) and try againc.

Release workflow

maturin build --release
# → target/wheels/open_engineering_kernel-…‑….whl
ls target/wheels/
# Absolute path to the wheel
WHEEL=$(realpath target/wheels/open_engineering_kernel-*.whl)
echo "$WHEEL"

Then in a fresh environment (definition of done for packaging):

python3 -m venv /tmp/oe-clean
source /tmp/oe-clean/bin/activate
pip install "$WHEEL"    # path/to/open_engineering_kernel-*.whl
python -c "from open_engineering_kernel import Identifier; print(Identifier.parse('oe.course.pico'))"

The course must not stop at maturin develop. Shipping a wheel that installs cleanly is part of the definition of done.

Concepts to understand (without drowning)

  • Virtual environment — isolated Python prefix; keeps course packages off the system interpreter
  • Native extension — compiled code loaded by the Python interpreter
  • Wheel — the standard binary distribution format for Python packages
  • Platform tags — Linux / macOS / Windows × CPU architecture × Python ABI
  • Development vs release builds — speed of iteration vs optimised artifacts

Design rule

Downstream Python code should treat the kernel like any other package:

from open_engineering_kernel import Identifier, validate_manifest

No sys.path hacks, no ctypes loading, no knowledge of target/debug.

Exercise

  1. Create and activate a venv under kernel/.venv.
  2. Install Maturin with pip install maturin.
  3. Run maturin develop successfully.
  4. Import the module from a Python REPL while the venv is active.
  5. Build a release wheel with maturin build --release.
  6. Install that wheel into a second clean venv and import again.