About a year ago I wrote a wrapper/api for creating python bindings with zig 0.13 and 0.14.1. It is located here https://codeberg.org/frmdstryr/py.zig .
It splits each of pythons separate object protocols into mixins and then used usingnamespace to add them, for example:
pub fn ObjectProtocol(comptime T: type) type {
return struct {
pub inline fn incref(self: *T) void {
// Use the _ variant since it should be non-null
c._Py_IncRef(@ptrCast(self));
}
pub inline fn decref(self: *T) void {
// Use the _ variant since it should be non-null
c._Py_DecRef(@ptrCast(self));
}
// etc
};
}
pub const Object = extern struct {
// The underlying python structure
impl: c.PyObject,
// Use the object protocol
pub usingnamespace ObjectProtocol(@This());
};
pub const Tuple = extern struct {
// The underlying python structure
impl: c.PyTupleObject,
// Tuple uses the object protocol
pub usingnamespace ObjectProtocol(@This());
// Tuple uses the SequenceProtocol
pub usingnamespace SequenceProtocol(@This());
// Some more tuple specific fns here...
};
This created a very clean and easy to use API that was then used to port a fairly large python framework written in c++.
I am looking to update to zig 0.15.2 (to use branch hints) but with usingnamespace now gone this design completely falls apart.
From what I can tell none of the proposed solutions in Remove `usingnamespace` · Issue #20663 · ziglang/zig · GitHub work well. Either I would have to:
- use a single type that wraps all c types and adds all functions to all objects (so a list would have dict functions but if used would just show a compile error)
- dig through each c type (which may change with python versions) and re-implement the structure in zig using the proposed mixin approach.
- copy paste all the protocol functions every time
Can anyone suggest how this project can be updated?