skillby atopile
pyzig
How the Zig↔Python binding layer works (pyzig), including build-on-import, wrapper generation patterns, ownership rules, and where to add new exported APIs. Use when adding Zig-Python bindings, modifying native extensions, or debugging C-API interactions.
Installs: 0
Used in: 1 repos
Updated: 5h ago
$
npx ai-builder add skill atopile/pyzigInstalls to .claude/skills/pyzig/
# Pyzig Module `pyzig` is the Zig↔Python interoperability layer used by Faebryk’s native modules (graph, sexp, faebryk typegraph, …). There are three distinct layers to keep straight: - **Python loader/glue**: `src/faebryk/core/zig/__init__.py` (build-on-import + `.pyi` syncing) - **Zig build**: `src/faebryk/core/zig/build.zig` (builds `pyzig.so` + `pyzig_sexp.so`, generates stubs) - **Zig binding utilities**: `src/faebryk/core/zig/src/pyzig/*` (wrapper generation + minimal C-API surface) ## Quick Start ```bash ato dev compile python -c "import faebryk.core.zig; import faebryk.core.graph" ``` ## Relevant Files - Python-side loader/build glue: - `src/faebryk/core/zig/__init__.py` (`ZIG_NORECOMPILE`, `ZIG_RELEASEMODE`, lock, stub syncing) - Zig build + stub generation: - `src/faebryk/core/zig/build.zig` (builds extensions + runs `.pyi` generator) - Core pyzig utilities: - `src/faebryk/core/zig/src/pyzig/pybindings.zig` (minimal CPython C-API declarations) - `src/faebryk/core/zig/src/pyzig/pyzig.zig` (wrapper generation helpers) - `src/faebryk/core/zig/src/pyzig/type_registry.zig` (global type-object registry) - `src/faebryk/core/zig/src/pyzig/pyi.zig` (stub generation helpers) - Example consumers: - `src/faebryk/core/zig/src/python/graph/graph_py.zig` - `src/faebryk/core/zig/src/python/sexp/sexp_py.zig` ## Dependants (Call Sites) - Graph bindings: `src/faebryk/core/zig/src/python/graph/*` - Sexp bindings: `src/faebryk/core/zig/src/python/sexp/*` - TypeGraph bindings: `src/faebryk/core/zig/src/python/faebryk/*` (and friends) ## How to Work With / Develop / Test ### Core Concepts - **Direct binding**: pyzig calls the CPython C-API directly (no cffi/ctypes). - **Wrapper types**: most exposed Zig structs become Python heap types via `wrap_in_python(...)` / `wrap_in_python_simple(...)`. - **Global type registry**: prevents re-creating Python `PyTypeObject`s for the same Zig type (`type_registry`). - **No direct `__init__` (by default)**: many “reference” types are not meant to be user-constructed; `pyzig` often installs an init that raises. - **Debug handle**: generated wrappers include `__zig_address__()` to help debug pointer identity. ### Development Workflow 1) Edit Zig: - binding helpers: `src/faebryk/core/zig/src/pyzig/*` - module wrappers: `src/faebryk/core/zig/src/python/**` 2) Rebuild native modules: - `ato dev compile` (imports `faebryk.core.zig`; editable installs compile-on-import) - set `ZIG_RELEASEMODE=ReleaseFast|ReleaseSafe|Debug` as needed 3) If you changed stubs/output: - ensure `src/faebryk/core/zig/gen/**` gets updated (this is driven by `src/faebryk/core/zig/__init__.py`) ### Testing - Smoke tests are usually through downstream modules: - `python -m faebryk.core.graph` (GraphView allocation/cleanup stress) - `ato dev test --llm test/core/solver` (heavy user of graph + bindings via many subsystems) ## Best Practices - **Assume mistakes segfault**: treat changes here like unsafe systems programming. - **Be explicit about ownership**: - if a wrapper allocates Zig memory, define how it is freed (explicit `.destroy()` vs `tp_dealloc` calling `.deinit()`). - if you duplicate input buffers (sexp does), expose a `free(...)` path and document it. - **Don’t rely on Python GC for Zig arenas** unless you intentionally installed a `tp_dealloc` that calls `deinit`. - **Stub hygiene matters**: keep the `.pyi` surface accurate; many callers rely on types for navigation. ## Build-on-import behavior (important) `src/faebryk/core/zig/__init__.py` is responsible for: - compiling extensions in editable installs (unless `ZIG_NORECOMPILE=1`) - loading `pyzig.so` and `pyzig_sexp.so` from `src/faebryk/core/zig/zig-out/lib/` - copying + formatting generated `.pyi` files into `src/faebryk/core/zig/gen/**` (black + ruff)
Quick Install
$
npx ai-builder add skill atopile/pyzigDetails
- Type
- skill
- Author
- atopile
- Slug
- atopile/pyzig
- Created
- 5h ago