1
4
Fork
You've already forked py.zig
0
Lightweight python bindings for zig
  • Zig 99.4%
  • Python 0.6%
Find a file
2026年05月29日 06:55:41 -04:00
.github/workflows Update ci 2025年02月18日 10:48:55 -05:00
example Update example 2026年05月12日 11:19:22 -04:00
tests Initial 2025年02月12日 14:40:12 -05:00
.gitignore Initial 2025年02月12日 14:40:12 -05:00
LICENSE.txt Add license, update readme, add sequenc protocol 2025年02月17日 06:56:05 -05:00
py.zig Add Complex 2026年05月29日 06:55:41 -04:00
README.md Add Function, Method, Code and drop unnecessary BaseType 2025年02月17日 19:53:16 -05:00

Lightweight Python bindings for zig

py.zig provides a lightweight interface for creating python extensions in zig.

It is intended to be used with setuptools-zig by simply cloning or copying py.zig into your python project, adding an Extension entry in your setup.py, and then using const py = @import("py.zig"); in your extensions source to define the python module.

from setuptools import Extension, setup
setup(
 name='pyzigtest',
 version='0.1.0',
 python_requires='>=3.10',
 build_zig=True,
 ext_modules=[
 Extension(
 'pyzigtest',
 sources=[
 'src/pyzigtest.zig'
 ],
 extra_compile_args=["-ODebug"] # or -OReleaseFast, etc..
 )
 ],
 setup_requires=['setuptools-zig'],
)

See the example for a complete example.

Why

py.zig is designed to be a much lighter alternative to something like ziggy-pydust.

Design

For each builtin python type py.zig defines an equivalent extern struct that embeds a single field impl with the underlying python type. For examle a tuple is defined as:

// c-import Python.hpubconstc=@cImport({@cDefine("PY_SSIZE_T_CLEAN","1");@cInclude("Python.h");});// ... pubconstTuple=externstruct{// The underlying python structureimpl:c.PyTupleObject,// Import the object protocolpubusingnamespaceObjectProtocol(@This());// Import the SequenceProtocolpubusingnamespaceSequenceProtocol(@This());// Some more tuple methods here...};

Since these types have the same memory representation as the c-equivalent you can safetly use @ptrCast and pass them to any functions (C/C++, or whatever) that take a tuple object.

You can also access any members of the python type using impl, directly. For example the Type can get the name like this:

pubconstType=externstruct{// The underlying python structureimpl:c.PyTypeObject,// ... // Return the name of this typepubinlinefnclassName(self:*Type)[:0]constu8{returnstd.mem.span(self.impl.tp_name);}};

However it is generally recommended to use public C-API functions as is done with the wrappers in py.zig.

Status

This is currently very alpha status and is undergoing breaking changes to functions but the basic design concept is unlikely to change.

Plans

Auto generate bindings...