better_bindings
better_bindings copied to clipboard
Better bindings for Python
Better Bindings
This project will attempt to accomplish 2 things:
- Easy to implement bindings (using a standard C ABI) - ✅
- Fast bindings (using something like
compile) - 🚧
Easy to use
Simple functions are trivial:
import better_bindings as bb
module = bb.bind('mylib.dylib', {
'fn': ([bb.int32, bb.int32], bb.float),
'renamed': ('orig_name', [bb.int32], bb.void)
})
out = module.fn(4, 4)
print(out)
Objects are also straightforward:
import better_bindings as bb
MyObj = bb.object('mylib.dylib', {
'__init__': ('makeObj', [bb.int32, bb.int32], bb.ptr),
'__del__': ('destroyObj', [bb.ptr], bb.void),
'foo': ('foo', [bb.ptr, bb.int32], bb.int32)
})
obj = MyObj(8, 4)
out = obj.foo(3)
print(out)
Fast bindings (work in progress)
Currently, bindings are compiled on the fly with the system's C compiler
module = bb.bind('mylib.dylib', binding_map) # calls clang/gcc!
In the future, I hope to expose compile().
New code is generated and the bytecode is hotswapped (ala torchdynamo):
module = bb.bind('mylib.dylib', binding_map)
def bar(a, b):
c = module.foo(a, 3)
d = module.foo(c, b)
return d
bar = bb.compile(bar) # the two calls to `foo` are merged and compiled together
This is particularly useful for ref counting
MyObj = bb.object('mylib.dylib', binding_map)
def bar(a, b):
obja = MyObj(a, 4)
objb = MyObj(b, 4)
objc = obja + objb
return objc
bar = bb.compile(bar) # the intermediate obja and objb are not materialized in Python, no refcounts are bumped!