PyOZ v0.6.0
What's New in v0.6.0
Added
-
Initial attempt at ABI3 (Stable ABI) Support - Build Python extensions compatible with Python 3.8+
- Enable via
-Dabi3=truebuild option orabi3 = truein pyproject.toml - Uses Python's Limited API (
Py_LIMITED_API = 0x03080000) for forward compatibility - Single wheel works across Python 3.8, 3.9, 3.10, 3.11, 3.12, 3.13+
- Wheel tags correctly use
cp38-abi3-platformformat - Comprehensive example module demonstrating all ABI3-compatible features
- Enable via
-
ABI3-Compatible Features - Most PyOZ features work in ABI3 mode:
- All basic types: int, float, bool, strings, bytes, complex, datetime, decimal, path
- Collections: list, dict, set (via Views)
- Classes with all magic methods:
__add__,__sub__,__mul__,__eq__,__lt__, etc. - Context managers:
__enter__,__exit__ - Descriptors:
__get__,__set__,__delete__ - Dynamic attributes:
__getattr__,__setattr__,__delattr__ - Iterators:
__iter__,__next__,__reversed__ - Callable objects:
__call__with multiple arguments - Hashable/frozen classes:
__hash__,__frozen__ - Class attributes via
classattr_*prefix - Computed properties via
get_X/set_Xpattern pyoz.property()API for explicit property definitions- GIL management:
releaseGIL(),acquireGIL()(stable ABI functions) - Enums (IntEnum and StrEnum)
- Custom exceptions with inheritance
- Error mappings
- In-place operators:
__iadd__,__ior__,__iand__, etc. - Reflected operators:
__radd__,__rmul__, etc. - Matrix operators:
__matmul__,__rmatmul__,__imatmul__ - Type coercion:
__int__,__float__,__bool__,__complex__,__index__ Iterator(T)andLazyIterator(T, State)producersBufferView(T)for read-only numpy array access
-
ABI3 Configuration in pyproject.toml:
[tool.pyoz] abi3 = true # Enable ABI3/Limited API mode
-
ABI3 Limitations - Features NOT available in ABI3 mode:
BufferViewMut(T)- Mutable buffer access requires unstable API__base__inheritance - Extending Python built-in types (list, dict) not supported__dict__/__weakref__support - Requires type flag access__buffer__producer protocol - Buffer export requires unstable structures- Submodules - Module hierarchy requires
tp_dictaccess - GC protocol (
__traverse__,__clear__) - May work but needs verification
-
Iterator(T)producer type - Return Python lists from Zig slices- Eager evaluation: converts slice to Python list immediately
- Use for small, known data sets
fn get_fibonacci() pyoz.Iterator(i64) { const fibs = [_]i64{ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }; return .{ .items = &fibs }; }
-
LazyIterator(T, State)producer type - Return lazy Python iterators- Generates values on-demand, memory efficient for large/infinite sequences
- State struct must implement
pub fn next(self: *@This()) ?T
const RangeState = struct { current: i64, end: i64, step: i64, pub fn next(self: *@This()) ?i64 { if (self.current >= self.end) return null; const val = self.current; self.current += self.step; return val; } }; fn lazy_range(start: i64, end: i64, step: i64) pyoz.LazyIterator(i64, RangeState) { return .{ .state = .{ .current = start, .end = end, .step = step } }; }
-
ByteArrayproducer support - Return Pythonbytearrayfrom Zig- Previously
ByteArraywas consumer-only (could only receive from Python) - Now supports bidirectional conversion
- Previously
Changed
-
Type markers are now
pub const- All internal type markers (_is_pyoz_*) are now public- Fixes cross-module
@hasDecldetection which requires public declarations - Affected types:
Set,FrozenSet,Dict,Iterator,LazyIterator,ListView,DictView,SetView,IteratorView,BufferView,BufferViewMut,Complex,DateTime,Date,Time,TimeDelta,Bytes,ByteArray,Path,Decimal
- Fixes cross-module
-
View types now use distinct markers - Consumer (View) types have separate markers from producer types
_is_pyoz_set_viewvs_is_pyoz_set_is_pyoz_dict_viewvs_is_pyoz_dict_is_pyoz_list_view(no producer equivalent, use slices)_is_pyoz_iterator_viewvs_is_pyoz_iterator_is_pyoz_buffervs_is_pyoz_buffer_mut
-
conversion.zigrefactored to use markers consistently- All type detection now uses
@hasDecl(T, "_is_pyoz_*")instead of direct type comparison - Improves extensibility and consistency across the codebase
- All type detection now uses
-
stubs.zigupdated for new typesIterator(T)generateslist[T]type hint (eager, returns list)LazyIterator(T, State)generatesIterator[T]type hint (lazy iterator)Dict(K, V)producer now properly detected via_is_pyoz_dictmarkerBufferViewMut(T)now properly detected via_is_pyoz_buffer_mutmarker- Added
Iteratorto typing imports for lazy iterator support
Documentation
- Types guide updated - Added Iterator vs LazyIterator section with usage examples
- View type asymmetry explained - Documented why Views are consumer-only
Fixed
-
Incorrect wheel ABI tag - Wheels were incorrectly tagged as
abi3even though PyOZ doesn't usePy_LIMITED_API- Changed from
cp312-abi3-platformto correctcp312-cp312-platformformat - ABI3 support will be added in a future release with proper Limited API compliance
- Changed from
-
Misleading Linux platform tag - Changed default from
manylinux_2_17tolinux_x86_64/linux_aarch64manylinuxtags promise glibc compatibility that we can't guarantee without building in manylinux containers- Users can now override via
linux-platform-tagin pyproject.toml for proper manylinux builds
-
Hardcoded macOS platform tag - Now detects actual macOS version at runtime
- Previously hardcoded
macosx_10_9_x86_64andmacosx_11_0_arm64 - Now uses Python's
platform.mac_ver()to detect actual OS version (e.g.,macosx_14_5_arm64)
- Previously hardcoded
Added
linux-platform-tagconfiguration option in pyproject.toml[tool.pyoz] # Override Linux platform tag for manylinux builds linux-platform-tag = "manylinux_2_17_x86_64"
- Allows users building in manylinux Docker containers to use proper manylinux tags
- Default remains
linux_x86_64/linux_aarch64for honest compatibility
Installation
Download the binary for your platform and add it to your PATH:
| Platform | Binary |
|---|---|
| Linux x86_64 | pyoz-x86_64-linux |
| Linux ARM64 | pyoz-aarch64-linux |
| macOS x86_64 | pyoz-x86_64-macos |
| macOS ARM64 (Apple Silicon) | pyoz-aarch64-macos |
| Windows x86_64 | pyoz-x86_64-windows.exe |
| Windows ARM64 | pyoz-aarch64-windows.exe |
Source
Download PyOZ-0.6.0.tar.gz for the source code.
Quick Start
pyoz init mymodule
cd mymodule
pyoz build
pip install dist/*.whl