Build high-performance Python extensions in Zig with automatic memory management. Inspired by ziggy-pydust.
Project description
pyz3 - Python Extensions in Zig
A high-performance framework for writing Python extension modules in Zig with automatic memory management, hot-reload, and NumPy integration.
🌟 Inspired by ziggy-pydust
Documentation: https://github.com/amiyamandal-dev/pyz3
Source Code: https://github.com/amiyamandal-dev/pyz3
Overview
pyz3 is a complete framework for building high-performance Python extension modules in Zig. It provides:
- 🚀 Seamless Python-Zig Interop - Automatic argument marshalling and type conversion
- 📊 NumPy Integration - Zero-copy array access with type-safe dtype mapping
- 🔧 Complete CLI Toolkit - Maturin-style commands for project lifecycle management
- 📦 Cross-Platform Builds - Build wheels for Linux, macOS, and Windows
- 🔗 C/C++ Integration - Automatic binding generation for C/C++ libraries
- 🧪 Testing Integration - Pytest plugin to discover and run Zig tests
- ⚡ Hot Reload - Watch mode with automatic rebuilding
- 🛡️ Memory Safe - Leverages Zig's safety features with Python's GC
Quick Example
const py = @import("pyz3");
pub fn fibonacci(args: struct { n: u64 }) u64 {
if (args.n < 2) return args.n;
var sum: u64 = 0;
var last: u64 = 0;
var curr: u64 = 1;
for (1..args.n) |_| {
sum = last + curr;
last = curr;
curr = sum;
}
return sum;
}
comptime {
py.rootmodule(@This());
}
import mymodule
print(mymodule.fibonacci(10)) # Output: 55
NumPy Integration Example
const py = @import("pyz3");
pub fn double_array(args: struct { arr: py.PyArray(@This()) }) !py.PyArray(@This()) {
// Zero-copy access to NumPy array
const data = try args.arr.asSliceMut(f64);
for (data) |*val| {
val.* *= 2.0;
}
return args.arr;
}
comptime {
py.rootmodule(@This());
}
import numpy as np
import mymodule
arr = np.array([1.0, 2.0, 3.0])
result = mymodule.double_array(arr)
print(result) # Output: [2.0, 4.0, 6.0]
Compatibility
- Zig: 0.15.x (tested with 0.15.2)
- Python: 3.11+ (CPython)
- Platforms: Linux (x86_64, aarch64), macOS (x86_64, arm64), Windows (x64)
Installation
pip install pyz3
Or with distribution extras for building wheels:
pip install pyz3[dist]
Quick Start
1. Create a New Project
# Create project using cookiecutter template
pyz3 init -n myproject --description "My awesome extension" --email "you@example.com" --no-interactive
cd myproject
2. Build Your Extension
# Development build
zig build
# Release build
zig build -Doptimize=ReleaseFast
# Watch mode (hot reload)
pyz3 watch
3. Test Your Extension
# Run pytest
pytest
# Run specific test
pytest test/test_myproject.py -v
4. Package for Distribution
# Build wheel for current platform
python -m build --wheel
# Build for all platforms (uses cross-compilation)
pyz3 build-wheel --all-platforms
# Publish to PyPI
pyz3 deploy --repository testpypi # Test first!
pyz3 deploy --repository pypi # Production
CLI Commands
pyz3 provides a complete CLI for managing your extension projects:
pyz3 init [OPTIONS] # Initialize new project
pyz3 build [OPTIONS] # Build extension module
pyz3 watch # Watch mode with hot reload
pyz3 test [OPTIONS] # Run tests
pyz3 clean # Clean build artifacts
pyz3 build-wheel [OPTIONS] # Build distribution packages
pyz3 deploy [OPTIONS] # Publish to PyPI
Key Features
Type-Safe Python-Zig Bridge
Automatic conversion between Python and Zig types:
| Zig Type | Python Type |
|---|---|
void |
None |
bool |
bool |
i32, i64 |
int |
f32, f64 |
float |
[]const u8 |
str |
struct {...} |
dict |
py.PyArray(root) |
numpy.ndarray |
Classes and Methods
pub const Point = py.class(struct {
pub const __doc__ = "A 2D point";
const Self = @This();
x: f64,
y: f64,
pub fn __init__(self: *Self, args: struct { x: f64, y: f64 }) !void {
self.* = .{ .x = args.x, .y = args.y };
}
pub fn distance(self: *const Self) f64 {
return @sqrt(self.x * self.x + self.y * self.y);
}
});
Exception Handling
pub fn divide(args: struct { a: i64, b: i64 }) !i64 {
if (args.b == 0) {
return py.ZeroDivisionError(root).raise("division by zero");
}
return @divTrunc(args.a, args.b);
}
Cross-Platform Distribution
Build wheels for multiple platforms:
# Using environment variables
ZIG_TARGET=x86_64-linux-gnu PYZ3_OPTIMIZE=ReleaseFast python -m build --wheel
ZIG_TARGET=aarch64-linux-gnu PYZ3_OPTIMIZE=ReleaseFast python -m build --wheel
ZIG_TARGET=x86_64-macos PYZ3_OPTIMIZE=ReleaseFast python -m build --wheel
ZIG_TARGET=aarch64-macos PYZ3_OPTIMIZE=ReleaseFast python -m build --wheel
ZIG_TARGET=x86_64-windows-gnu PYZ3_OPTIMIZE=ReleaseFast python -m build --wheel
The build system automatically:
- Detects target platform
- Cross-compiles for different architectures
- Creates manylinux-compatible wheels
- Handles platform-specific optimizations
Performance
pyz3 leverages Zig's performance advantages:
- Zero-cost abstractions - No runtime overhead
- Compile-time optimizations - Zig's comptime for metaprogramming
- SIMD support - Automatic vectorization where possible
- Small binaries - Smaller than equivalent Rust extensions
- Fast compilation - Faster than Rust, comparable to C
Acknowledgments
This project is a hard fork of ziggy-pydust by Fulcrum.
Major differences in pyz3:
- ✅ Built-in NumPy integration with zero-copy array access
- ✅ Enhanced cross-compilation support
- ✅ Updated CLI commands and workflows
- ✅ Comprehensive NumPy examples and tests
- ✅ Improved documentation for data science use cases
Special thanks to the original ziggy-pydust contributors for creating an excellent foundation!
License
Apache License 2.0
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Links
- Original Project: ziggy-pydust
- Zig Language: ziglang.org
- NumPy: numpy.org
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyz3-0.8.0-py3-none-any.whl.
File metadata
- Download URL: pyz3-0.8.0-py3-none-any.whl
- Upload date:
- Size: 249.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
332fcf7a34b5a2965d7b950d1789a4206f35810d9d0463c47b108bc9cd87f5cf
|
|
| MD5 |
97cb53323474ebd9cbbc11260b51c376
|
|
| BLAKE2b-256 |
3223f46102bc8f3943c7662a62f6cc4b1623e048066994cc07869efdd311f642
|
Provenance
The following attestation bundles were made for pyz3-0.8.0-py3-none-any.whl:
Publisher:
build-wheels.yml on amiyamandal-dev/pyz3
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyz3-0.8.0-py3-none-any.whl -
Subject digest:
332fcf7a34b5a2965d7b950d1789a4206f35810d9d0463c47b108bc9cd87f5cf - Sigstore transparency entry: 748532412
- Sigstore integration time:
-
Permalink:
amiyamandal-dev/pyz3@afe32b43e4baf32030ce894f1e7bf81e5fd08a7a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/amiyamandal-dev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
build-wheels.yml@afe32b43e4baf32030ce894f1e7bf81e5fd08a7a -
Trigger Event:
push
-
Statement type: