Skip to content

Installation

Kathryn is a mixed Rust/Python project: the compiler core is a Rust crate, and the Python DSL is a thin package that loads the compiled core as a native extension (kathryn._kathryn). The published wheels carry that core already built, so the normal install is one pip command and needs no Rust toolchain:

Terminal window
pip install kathryn

The package is kathryn on PyPI; the current release is 0.1.0 (first release, September 2026). Python 3.9 or newer is the only requirement — the package declares requires-python = ">=3.9".

Terminal window
python -m venv .venv
source .venv/bin/activate
pip install kathryn

To also pull in the simulation stack used by the end-to-end tests (cocotb and a Verilator wheel), install the sim extra:

Terminal window
pip install "kathryn[sim]"

The dev extra (pip install "kathryn[dev]") adds pytest. Neither extra is needed to write a design and emit Verilog.

At a glance, the install path from a Python interpreter to a working import:

flowchart TB
    U["Python 3.9+"] --> P["pip install kathryn<br/>(wheel: Rust core already built)"]
    P --> V["Verify: import kathryn"]
    U --> N["No wheel for your platform,<br/>or you are working on Kathryn itself"]
    N --> T["Rust toolchain plus maturin"]
    T --> A["maturin develop --release<br/>(into active venv)"]
    T --> B["maturin build --release"]
    B --> W["pip install target/wheels/kathryn-*.whl"]
    A --> V
    W --> V
    V --> Q["Optional: pytest py/tests"]

Release 0.1.0 ships wheels for:

PlatformInterpreters
Linux x86-64CPython 3.9–3.15, PyPy 3.11 (manylinux 2.17+)
Linux aarch64CPython 3.9–3.14, PyPy 3.11 (manylinux 2.17+)
macOS x86-64 (10.12+)CPython 3.9, 3.11–3.14
macOS arm64 (11.0+)CPython 3.9, 3.11–3.14
Windows x86-64CPython 3.9–3.14

A few combinations have no wheel — CPython 3.10 on macOS, and CPython 3.15 outside Linux x86-64. There pip falls back to the source distribution and compiles the Rust core, which needs the toolchain described below.

Build from source when you are working on Kathryn itself, when you want a change that is not released yet, or when your platform has no wheel. You need two more things on your machine:

  • A Rust toolchain. The crate uses the Rust 2024 edition, so install a recent stable Rust via rustup:

    Terminal window
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    rustup update stable
  • maturin 1.7 or newer (maturin>=1.7,<2.0), the build backend that compiles the Rust extension and packages it together with the pure-Python layer:

    Terminal window
    pip install "maturin>=1.7,<2.0"

Clone (or otherwise obtain) the Kathryn repository and work from its root — the directory containing Cargo.toml and pyproject.toml. Note that the Rust crate is named Kathryn2, but the Python package you import is plain kathryn.

maturin develop compiles the extension and installs the kathryn package directly into the currently active virtual environment, so create and activate one first:

Terminal window
python -m venv .venv
source .venv/bin/activate
maturin develop --release

This builds the Rust core with the python Cargo feature (configured in pyproject.toml, so you don’t pass it yourself), drops the compiled extension inside the pure-Python package, and installs it. --release is optional; it builds the Rust core with optimizations turned on.

Re-run maturin develop after changing the Rust source; pure-Python changes under py/kathryn/ are picked up without a rebuild in a develop install.

To produce an installable wheel (for example to install into another environment or machine):

Terminal window
maturin build --release
pip install target/wheels/kathryn-*.whl

The wheel lands under target/wheels/ and contains both the compiled extension and the Python DSL.

A successful install means import kathryn loads the native core and the DSL surface. Quick check:

Terminal window
python -c "import kathryn; print('kathryn OK:', kathryn.LogicOp)"

Then a slightly more end-to-end check that actually touches the model arena:

from kathryn import Module, init, reg, reset
reset() # fresh model arena
class hello(Module):
@init
def declare(self):
self.r = reg(8, "r")
m = hello()
print(m.r.hw_type) # -> REG

If this prints REG, the Rust core and the Python frontend are talking to each other correctly.

The test suites live in the repository, so they need a source checkout even if you installed the package from PyPI. The smoke-test suite covers the Python DSL:

Terminal window
pip install pytest
pytest py/tests

The end-to-end model tests under test/model/ additionally simulate the emitted Verilog with cocotb and a Verilog simulator. They are driven by one entry point, with no Makefile:

Terminal window
PYTHONPATH=py python test/run_cocotb.py # all cases, icarus
PYTHONPATH=py python test/run_cocotb.py verilator # all cases, verilator
PYTHONPATH=py python test/run_cocotb.py icarus tc2_par # one case

The simulator argument defaults to icarus (iverilog); verilator is also supported and needs verilator ≥ 5.036. Each case writes its Verilog and one VCD per testbench coroutine to test/.model_output/<case>/.

  • pip starts compiling Rust — there is no wheel for your interpreter and platform, so pip fell back to the source distribution. Install a Rust toolchain (above), or use an interpreter version that has a wheel.
  • maturin develop complains about a missing virtualenv — it refuses to install into a system Python. Activate a venv (or conda env) first.
  • import kathryn fails with an extension import error — the native module kathryn._kathryn was not built for your current interpreter. Re-run maturin develop inside the environment you are importing from.
  • Stale behavior after a Rust change — rebuild with maturin develop; the compiled extension is only refreshed by a build.

With the package installed, continue to the Quickstart and compile your first module to Verilog.