Provides patterns and build helpers for Zig-Python interoperability and bindings.
Install
mkdir -p .claude/skills/pyzig && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4577" && unzip -o skill.zip -d .claude/skills/pyzig && rm skill.zipInstalls to .claude/skills/pyzig
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
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.Key capabilities
- →Manages C-API interaction surface between Zig and Python
- →Automates build-on-import wrapper generation
- →Handles global type-object registration for heap types
- →Provides utilities for stub (.pyi) generation
How it works
It hooks into the import lifecycle to trigger the Zig build system, which manages the CPython C-API translation and memory ownership of wrapper objects.
Inputs & outputs
When to use pyzig
- →Create new Zig-Python binding
- →Debug C-API interaction errors
- →Rebuild native extension stubs
About this skill
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 +.pyisyncing) - Zig build:
src/faebryk/core/zig/build.zig(buildspyzig.so+pyzig_sexp.so, generates stubs) - Zig binding utilities:
src/faebryk/core/zig/src/pyzig/*(wrapper generation + minimal C-API surface)
Quick Start
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.pyigenerator)
- 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.zigsrc/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
PyTypeObjects for the same Zig type (type_registry). - No direct
__init__(by default): many “reference” types are not meant to be user-constructed;pyzigoften installs an init that raises. - Debug handle: generated wrappers include
__zig_address__()to help debug pointer identity.
Development Workflow
- Edit Zig:
- binding helpers:
src/faebryk/core/zig/src/pyzig/* - module wrappers:
src/faebryk/core/zig/src/python/**
- binding helpers:
- Rebuild native modules:
ato dev compile(importsfaebryk.core.zig; editable installs compile-on-import)- set
ZIG_RELEASEMODE=ReleaseFast|ReleaseSafe|Debugas needed
- If you changed stubs/output:
- ensure
src/faebryk/core/zig/gen/**gets updated (this is driven bysrc/faebryk/core/zig/__init__.py)
- ensure
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()vstp_dealloccalling.deinit()). - if you duplicate input buffers (sexp does), expose a
free(...)path and document it.
- if a wrapper allocates Zig memory, define how it is freed (explicit
- Don’t rely on Python GC for Zig arenas unless you intentionally installed a
tp_deallocthat callsdeinit. - Stub hygiene matters: keep the
.pyisurface 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.soandpyzig_sexp.sofromsrc/faebryk/core/zig/zig-out/lib/ - copying + formatting generated
.pyifiles intosrc/faebryk/core/zig/gen/**(black + ruff)
When not to use it
- →Projects not requiring native performance bindings
- →When C-API complexity exceeds binding capabilities
Prerequisites
Limitations
- →Requires knowledge of CPython memory management
- →Build-time overhead during development
How it compares
It eliminates the need for manual CFFI/ctypes definitions by using direct C-API bindings generated at build time.
Compared to similar skills
pyzig side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| pyzig (this skill) | 1 | 6mo | Review | Advanced |
| python-pro | 23 | 4mo | No flags | Advanced |
| add-new-setting-field | 1 | 7mo | No flags | Intermediate |
| generating-rest-apis | 0 | 27d | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by atopile
View all by atopile →You might also like
python-pro
sickn33
Master Python 3.12+ with modern features, async programming, performance optimization, and production-ready practices. Expert in the latest Python ecosystem including uv, ruff, pydantic, and FastAPI. Use PROACTIVELY for Python development, optimization, or advanced Python patterns.
add-new-setting-field
tsukumijima
【設定追加時は必ず参照】KonomiTV に新しい設定 (v-switch/v-select など) を追加する際の必須手順。SettingsStore.ts / Settings.ts / config.py / Settings/*.vue への追加が必要
generating-rest-apis
jeremylongshore
Generate complete REST API implementations from OpenAPI specifications or database schemas. Use when generating RESTful API implementations. Trigger with phrases like "generate REST API", "create RESTful API", or "build REST endpoints".
r-code
dslc-io
Guide for writing R code. Use when writing new functions, designing APIs, or reviewing/modifying existing R code.
jx
jpsca
Use this skill for anything Jx — the Python/Jinja2 component library. Covers BOTH (a) library mechanics and integration AND (b) authoring production-ready UI components. Trigger this skill on any mention of Jx, `.jx` files, "Jinja components" in a Python web app context, or requests to build/create
vyper-compiler
vyperlang
Vyper smart contract compiler internals. Use when working on the Vyper compiler codebase — compilation pipeline, Venom IR, semantic analysis, code generation, testing, or contributing. Triggers on vyper compiler development, Venom passes, AST/semantics changes, codegen work, or test writing.