# (c) 2022 Exaloop Inc. All rights reserved. import os from internal.dlopen import * # general Py_DecRef = Function[[cobj], NoneType](cobj()) Py_IncRef = Function[[cobj], NoneType](cobj()) Py_Initialize = Function[[], NoneType](cobj()) PyImport_AddModule = Function[[cobj], cobj](cobj()) PyImport_AddModuleObject = Function[[cobj], cobj](cobj()) PyImport_ImportModule = Function[[cobj], cobj](cobj()) PyErr_Fetch = Function[[Ptr[cobj], Ptr[cobj], Ptr[cobj]], NoneType](cobj()) PyRun_SimpleString = Function[[cobj], NoneType](cobj()) PyEval_GetGlobals = Function[[], cobj](cobj()) # conversions PyLong_AsLong = Function[[cobj], int](cobj()) PyLong_FromLong = Function[[int], cobj](cobj()) PyFloat_AsDouble = Function[[cobj], float](cobj()) PyFloat_FromDouble = Function[[float], cobj](cobj()) PyBool_FromLong = Function[[int], cobj](cobj()) PyBytes_AsString = Function[[cobj], cobj](cobj()) PyList_New = Function[[int], cobj](cobj()) PyList_GetItem = Function[[cobj, int], cobj](cobj()) PyList_SetItem = Function[[cobj, int, cobj], cobj](cobj()) PyDict_New = Function[[], cobj](cobj()) PyDict_Next = Function[[cobj, Ptr[int], Ptr[cobj], Ptr[cobj]], int](cobj()) PyDict_GetItem = Function[[cobj, cobj], cobj](cobj()) PyDict_SetItem = Function[[cobj, cobj, cobj], cobj](cobj()) PySet_Add = Function[[cobj, cobj], cobj](cobj()) PySet_New = Function[[cobj], cobj](cobj()) PyTuple_GetItem = Function[[cobj, int], cobj](cobj()) PyTuple_New = Function[[int], cobj](cobj()) PyTuple_SetItem = Function[[cobj, int, cobj], NoneType](cobj()) PyUnicode_AsEncodedString = Function[[cobj, cobj, cobj], cobj](cobj()) PyUnicode_DecodeFSDefaultAndSize = Function[[cobj, int], cobj](cobj()) PyUnicode_FromString = Function[[cobj], cobj](cobj()) PyComplex_FromDoubles = Function[[float, float], cobj](cobj()) PyComplex_RealAsDouble = Function[[cobj], float](cobj()) PyComplex_ImagAsDouble = Function[[cobj], float](cobj()) PyIter_Next = Function[[cobj], cobj](cobj()) PySlice_New = Function[[cobj, cobj, cobj], cobj](cobj()) PySlice_Unpack = Function[[cobj, Ptr[int], Ptr[int], Ptr[int]], int](cobj()) # number PyNumber_Add = Function[[cobj, cobj], cobj](cobj()) PyNumber_Subtract = Function[[cobj, cobj], cobj](cobj()) PyNumber_Multiply = Function[[cobj, cobj], cobj](cobj()) PyNumber_MatrixMultiply = Function[[cobj, cobj], cobj](cobj()) PyNumber_FloorDivide = Function[[cobj, cobj], cobj](cobj()) PyNumber_TrueDivide = Function[[cobj, cobj], cobj](cobj()) PyNumber_Remainder = Function[[cobj, cobj], cobj](cobj()) PyNumber_Divmod = Function[[cobj, cobj], cobj](cobj()) PyNumber_Power = Function[[cobj, cobj, cobj], cobj](cobj()) PyNumber_Negative = Function[[cobj], cobj](cobj()) PyNumber_Positive = Function[[cobj], cobj](cobj()) PyNumber_Absolute = Function[[cobj], cobj](cobj()) PyNumber_Invert = Function[[cobj], cobj](cobj()) PyNumber_Lshift = Function[[cobj, cobj], cobj](cobj()) PyNumber_Rshift = Function[[cobj, cobj], cobj](cobj()) PyNumber_And = Function[[cobj, cobj], cobj](cobj()) PyNumber_Xor = Function[[cobj, cobj], cobj](cobj()) PyNumber_Or = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceAdd = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceSubtract = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceMultiply = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceMatrixMultiply = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceFloorDivide = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceTrueDivide = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceRemainder = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlacePower = Function[[cobj, cobj, cobj], cobj](cobj()) PyNumber_InPlaceLshift = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceRshift = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceAnd = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceXor = Function[[cobj, cobj], cobj](cobj()) PyNumber_InPlaceOr = Function[[cobj, cobj], cobj](cobj()) PyNumber_Long = Function[[cobj], cobj](cobj()) PyNumber_Float = Function[[cobj], cobj](cobj()) PyNumber_Index = Function[[cobj], cobj](cobj()) # object PyObject_Call = Function[[cobj, cobj, cobj], cobj](cobj()) PyObject_GetAttr = Function[[cobj, cobj], cobj](cobj()) PyObject_GetAttrString = Function[[cobj, cobj], cobj](cobj()) PyObject_GetIter = Function[[cobj], cobj](cobj()) PyObject_HasAttrString = Function[[cobj, cobj], int](cobj()) PyObject_IsTrue = Function[[cobj], int](cobj()) PyObject_Length = Function[[cobj], int](cobj()) PyObject_LengthHint = Function[[cobj, int], int](cobj()) PyObject_SetAttrString = Function[[cobj, cobj, cobj], cobj](cobj()) PyObject_Str = Function[[cobj], cobj](cobj()) PyObject_Repr = Function[[cobj], cobj](cobj()) PyObject_Hash = Function[[cobj], int](cobj()) PyObject_GetItem = Function[[cobj, cobj], cobj](cobj()) PyObject_SetItem = Function[[cobj, cobj, cobj], int](cobj()) PyObject_DelItem = Function[[cobj, cobj], int](cobj()) PyObject_RichCompare = Function[[cobj, cobj, i32], cobj](cobj()) # constants Py_None = cobj() Py_True = cobj() Py_False = cobj() Py_LT = 0 Py_LE = 1 Py_EQ = 2 Py_NE = 3 Py_GT = 4 Py_GE = 5 _PY_MODULE_CACHE = Dict[str, pyobj]() _PY_INIT = """ import io clsf = None clsa = None plt = None try: import matplotlib.figure import matplotlib.pyplot plt = matplotlib.pyplot clsf = matplotlib.figure.Figure clsa = matplotlib.artist.Artist except ModuleNotFoundError: pass def __codon_repr__(fig): if clsf and isinstance(fig, clsf): stream = io.StringIO() fig.savefig(stream, format="svg") return 'image/svg+xml', stream.getvalue() elif clsa and isinstance(fig, list) and all( isinstance(i, clsa) for i in fig ): stream = io.StringIO() plt.gcf().savefig(stream, format="svg") return 'image/svg+xml', stream.getvalue() elif hasattr(fig, "_repr_html_"): return 'text/html', fig._repr_html_() else: return 'text/plain', fig.__repr__() """ _PY_INITIALIZED = False def init_dl_handles(py_handle: cobj): global Py_DecRef global Py_IncRef global Py_Initialize global PyImport_AddModule global PyImport_AddModuleObject global PyImport_ImportModule global PyErr_Fetch global PyRun_SimpleString global PyEval_GetGlobals global PyLong_AsLong global PyLong_FromLong global PyFloat_AsDouble global PyFloat_FromDouble global PyBool_FromLong global PyBytes_AsString global PyList_New global PyList_GetItem global PyList_SetItem global PyDict_New global PyDict_Next global PyDict_GetItem global PyDict_SetItem global PySet_Add global PySet_New global PyTuple_GetItem global PyTuple_New global PyTuple_SetItem global PyUnicode_AsEncodedString global PyUnicode_DecodeFSDefaultAndSize global PyUnicode_FromString global PyComplex_FromDoubles global PyComplex_RealAsDouble global PyComplex_ImagAsDouble global PyIter_Next global PySlice_New global PySlice_Unpack global PyNumber_Add global PyNumber_Subtract global PyNumber_Multiply global PyNumber_MatrixMultiply global PyNumber_FloorDivide global PyNumber_TrueDivide global PyNumber_Remainder global PyNumber_Divmod global PyNumber_Power global PyNumber_Negative global PyNumber_Positive global PyNumber_Absolute global PyNumber_Invert global PyNumber_Lshift global PyNumber_Rshift global PyNumber_And global PyNumber_Xor global PyNumber_Or global PyNumber_InPlaceAdd global PyNumber_InPlaceSubtract global PyNumber_InPlaceMultiply global PyNumber_InPlaceMatrixMultiply global PyNumber_InPlaceFloorDivide global PyNumber_InPlaceTrueDivide global PyNumber_InPlaceRemainder global PyNumber_InPlacePower global PyNumber_InPlaceLshift global PyNumber_InPlaceRshift global PyNumber_InPlaceAnd global PyNumber_InPlaceXor global PyNumber_InPlaceOr global PyNumber_Long global PyNumber_Float global PyNumber_Index global PyObject_Call global PyObject_GetAttr global PyObject_GetAttrString global PyObject_GetIter global PyObject_HasAttrString global PyObject_IsTrue global PyObject_Length global PyObject_LengthHint global PyObject_SetAttrString global PyObject_Str global PyObject_Repr global PyObject_Hash global PyObject_GetItem global PyObject_SetItem global PyObject_DelItem global PyObject_RichCompare global Py_None global Py_True global Py_False Py_DecRef = dlsym(py_handle, "Py_DecRef") Py_IncRef = dlsym(py_handle, "Py_IncRef") Py_Initialize = dlsym(py_handle, "Py_Initialize") PyImport_AddModule = dlsym(py_handle, "PyImport_AddModule") PyImport_AddModuleObject = dlsym(py_handle, "PyImport_AddModuleObject") PyImport_ImportModule = dlsym(py_handle, "PyImport_ImportModule") PyErr_Fetch = dlsym(py_handle, "PyErr_Fetch") PyRun_SimpleString = dlsym(py_handle, "PyRun_SimpleString") PyEval_GetGlobals = dlsym(py_handle, "PyEval_GetGlobals") PyLong_AsLong = dlsym(py_handle, "PyLong_AsLong") PyLong_FromLong = dlsym(py_handle, "PyLong_FromLong") PyFloat_AsDouble = dlsym(py_handle, "PyFloat_AsDouble") PyFloat_FromDouble = dlsym(py_handle, "PyFloat_FromDouble") PyBool_FromLong = dlsym(py_handle, "PyBool_FromLong") PyBytes_AsString = dlsym(py_handle, "PyBytes_AsString") PyList_New = dlsym(py_handle, "PyList_New") PyList_GetItem = dlsym(py_handle, "PyList_GetItem") PyList_SetItem = dlsym(py_handle, "PyList_SetItem") PyDict_New = dlsym(py_handle, "PyDict_New") PyDict_Next = dlsym(py_handle, "PyDict_Next") PyDict_GetItem = dlsym(py_handle, "PyDict_GetItem") PyDict_SetItem = dlsym(py_handle, "PyDict_SetItem") PySet_Add = dlsym(py_handle, "PySet_Add") PySet_New = dlsym(py_handle, "PySet_New") PyTuple_GetItem = dlsym(py_handle, "PyTuple_GetItem") PyTuple_New = dlsym(py_handle, "PyTuple_New") PyTuple_SetItem = dlsym(py_handle, "PyTuple_SetItem") PyUnicode_AsEncodedString = dlsym(py_handle, "PyUnicode_AsEncodedString") PyUnicode_DecodeFSDefaultAndSize = dlsym(py_handle, "PyUnicode_DecodeFSDefaultAndSize") PyUnicode_FromString = dlsym(py_handle, "PyUnicode_FromString") PyComplex_FromDoubles = dlsym(py_handle, "PyComplex_FromDoubles") PyComplex_RealAsDouble = dlsym(py_handle, "PyComplex_RealAsDouble") PyComplex_ImagAsDouble = dlsym(py_handle, "PyComplex_ImagAsDouble") PyIter_Next = dlsym(py_handle, "PyIter_Next") PySlice_New = dlsym(py_handle, "PySlice_New") PySlice_Unpack = dlsym(py_handle, "PySlice_Unpack") PyNumber_Add = dlsym(py_handle, "PyNumber_Add") PyNumber_Subtract = dlsym(py_handle, "PyNumber_Subtract") PyNumber_Multiply = dlsym(py_handle, "PyNumber_Multiply") PyNumber_MatrixMultiply = dlsym(py_handle, "PyNumber_MatrixMultiply") PyNumber_FloorDivide = dlsym(py_handle, "PyNumber_FloorDivide") PyNumber_TrueDivide = dlsym(py_handle, "PyNumber_TrueDivide") PyNumber_Remainder = dlsym(py_handle, "PyNumber_Remainder") PyNumber_Divmod = dlsym(py_handle, "PyNumber_Divmod") PyNumber_Power = dlsym(py_handle, "PyNumber_Power") PyNumber_Negative = dlsym(py_handle, "PyNumber_Negative") PyNumber_Positive = dlsym(py_handle, "PyNumber_Positive") PyNumber_Absolute = dlsym(py_handle, "PyNumber_Absolute") PyNumber_Invert = dlsym(py_handle, "PyNumber_Invert") PyNumber_Lshift = dlsym(py_handle, "PyNumber_Lshift") PyNumber_Rshift = dlsym(py_handle, "PyNumber_Rshift") PyNumber_And = dlsym(py_handle, "PyNumber_And") PyNumber_Xor = dlsym(py_handle, "PyNumber_Xor") PyNumber_Or = dlsym(py_handle, "PyNumber_Or") PyNumber_InPlaceAdd = dlsym(py_handle, "PyNumber_InPlaceAdd") PyNumber_InPlaceSubtract = dlsym(py_handle, "PyNumber_InPlaceSubtract") PyNumber_InPlaceMultiply = dlsym(py_handle, "PyNumber_InPlaceMultiply") PyNumber_InPlaceMatrixMultiply = dlsym(py_handle, "PyNumber_InPlaceMatrixMultiply") PyNumber_InPlaceFloorDivide = dlsym(py_handle, "PyNumber_InPlaceFloorDivide") PyNumber_InPlaceTrueDivide = dlsym(py_handle, "PyNumber_InPlaceTrueDivide") PyNumber_InPlaceRemainder = dlsym(py_handle, "PyNumber_InPlaceRemainder") PyNumber_InPlacePower = dlsym(py_handle, "PyNumber_InPlacePower") PyNumber_InPlaceLshift = dlsym(py_handle, "PyNumber_InPlaceLshift") PyNumber_InPlaceRshift = dlsym(py_handle, "PyNumber_InPlaceRshift") PyNumber_InPlaceAnd = dlsym(py_handle, "PyNumber_InPlaceAnd") PyNumber_InPlaceXor = dlsym(py_handle, "PyNumber_InPlaceXor") PyNumber_InPlaceOr = dlsym(py_handle, "PyNumber_InPlaceOr") PyNumber_Long = dlsym(py_handle, "PyNumber_Long") PyNumber_Float = dlsym(py_handle, "PyNumber_Float") PyNumber_Index = dlsym(py_handle, "PyNumber_Index") PyObject_Call = dlsym(py_handle, "PyObject_Call") PyObject_GetAttr = dlsym(py_handle, "PyObject_GetAttr") PyObject_GetAttrString = dlsym(py_handle, "PyObject_GetAttrString") PyObject_GetIter = dlsym(py_handle, "PyObject_GetIter") PyObject_HasAttrString = dlsym(py_handle, "PyObject_HasAttrString") PyObject_IsTrue = dlsym(py_handle, "PyObject_IsTrue") PyObject_Length = dlsym(py_handle, "PyObject_Length") PyObject_LengthHint = dlsym(py_handle, "PyObject_LengthHint") PyObject_SetAttrString = dlsym(py_handle, "PyObject_SetAttrString") PyObject_Str = dlsym(py_handle, "PyObject_Str") PyObject_Repr = dlsym(py_handle, "PyObject_Repr") PyObject_Hash = dlsym(py_handle, "PyObject_Hash") PyObject_GetItem = dlsym(py_handle, "PyObject_GetItem") PyObject_SetItem = dlsym(py_handle, "PyObject_SetItem") PyObject_DelItem = dlsym(py_handle, "PyObject_DelItem") PyObject_RichCompare = dlsym(py_handle, "PyObject_RichCompare") Py_None = dlsym(py_handle, "_Py_NoneStruct") Py_True = dlsym(py_handle, "_Py_TrueStruct") Py_False = dlsym(py_handle, "_Py_FalseStruct") def setup_python(python_loaded: bool): global _PY_INITIALIZED if _PY_INITIALIZED: return py_handle = cobj() if python_loaded: py_handle = dlopen("", RTLD_LOCAL | RTLD_NOW) else: LD = os.getenv("CODON_PYTHON", default="libpython." + dlext()) py_handle = dlopen(LD, RTLD_LOCAL | RTLD_NOW) init_dl_handles(py_handle) if not python_loaded: Py_Initialize() _PY_INITIALIZED = True def ensure_initialized(python_loaded: bool = False): setup_python(python_loaded) PyRun_SimpleString(_PY_INIT.c_str()) def setup_decorator(): setup_python(True) @extend class pyobj: @__internal__ def __new__() -> pyobj: pass def __raw__(self) -> Ptr[byte]: return __internal__.class_raw(self) def __init__(self, p: Ptr[byte], steal: bool = False): self.p = p if not steal: self.incref() def __del__(self): self.decref() def _getattr(self, name: str) -> pyobj: return pyobj(pyobj.exc_wrap(PyObject_GetAttrString(self.p, name.c_str())), steal=True) def __add__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Add(self.p, other.__to_py__())), steal=True) def __radd__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Add(other.__to_py__(), self.p)), steal=True) def __sub__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Subtract(self.p, other.__to_py__())), steal=True) def __rsub__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Subtract(other.__to_py__(), self.p)), steal=True) def __mul__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Multiply(self.p, other.__to_py__())), steal=True) def __rmul__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Multiply(other.__to_py__(), self.p)), steal=True) def __matmul__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_MatrixMultiply(self.p, other.__to_py__())), steal=True) def __rmatmul__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_MatrixMultiply(other.__to_py__(), self.p)), steal=True) def __floordiv__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_FloorDivide(self.p, other.__to_py__())), steal=True) def __rfloordiv__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_FloorDivide(other.__to_py__(), self.p)), steal=True) def __truediv__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_TrueDivide(self.p, other.__to_py__())), steal=True) def __rtruediv__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_TrueDivide(other.__to_py__(), self.p)), steal=True) def __mod__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Remainder(self.p, other.__to_py__())), steal=True) def __rmod__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Remainder(other.__to_py__(), self.p)), steal=True) def __divmod__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Divmod(self.p, other.__to_py__())), steal=True) def __rdivmod__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Divmod(other.__to_py__(), self.p)), steal=True) def __pow__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Power(self.p, other.__to_py__(), Py_None)), steal=True) def __rpow__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Power(other.__to_py__(), self.p, Py_None)), steal=True) def __neg__(self): return pyobj(pyobj.exc_wrap(PyNumber_Negative(self.p)), steal=True) def __pos__(self): return pyobj(pyobj.exc_wrap(PyNumber_Positive(self.p)), steal=True) def __invert__(self): return pyobj(pyobj.exc_wrap(PyNumber_Invert(self.p)), steal=True) def __lshift__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Lshift(self.p, other.__to_py__())), steal=True) def __rlshift__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Lshift(other.__to_py__(), self.p)), steal=True) def __rshift__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Rshift(self.p, other.__to_py__())), steal=True) def __rrshift__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Rshift(other.__to_py__(), self.p)), steal=True) def __and__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_And(self.p, other.__to_py__())), steal=True) def __rand__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_And(other.__to_py__(), self.p)), steal=True) def __xor__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Xor(self.p, other.__to_py__())), steal=True) def __rxor__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Xor(other.__to_py__(), self.p)), steal=True) def __or__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Or(self.p, other.__to_py__())), steal=True) def __ror__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_Or(other.__to_py__(), self.p)), steal=True) def __iadd__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceAdd(self.p, other.__to_py__())), steal=True) def __isub__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceSubtract(self.p, other.__to_py__())), steal=True) def __imul__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceMultiply(self.p, other.__to_py__())), steal=True) def __imatmul__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceMatrixMultiply(self.p, other.__to_py__())), steal=True) def __ifloordiv__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceFloorDivide(self.p, other.__to_py__())), steal=True) def __itruediv__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceTrueDivide(self.p, other.__to_py__())), steal=True) def __imod__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceRemainder(self.p, other.__to_py__())), steal=True) def __ipow__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlacePower(self.p, other.__to_py__(), Py_None)), steal=True) def __ilshift__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceLshift(self.p, other.__to_py__())), steal=True) def __irshift__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceRshift(self.p, other.__to_py__())), steal=True) def __iand__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceAnd(self.p, other.__to_py__())), steal=True) def __ixor__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceXor(self.p, other.__to_py__())), steal=True) def __ior__(self, other): return pyobj(pyobj.exc_wrap(PyNumber_InPlaceOr(self.p, other.__to_py__())), steal=True) def __int__(self): o = pyobj.exc_wrap(PyNumber_Long(self.p)) x = int.__from_py__(o) pyobj.decref(o) return x def __float__(self): o = pyobj.exc_wrap(PyNumber_Float(self.p)) x = float.__from_py__(o) pyobj.decref(o) return x def __index__(self): o = pyobj.exc_wrap(PyNumber_Index(self.p)) x = int.__from_py__(o) pyobj.decref(o) return x def __len__(self) -> int: return pyobj.exc_wrap(PyObject_Length(self.p)) def __length_hint__(self) -> int: return pyobj.exc_wrap(PyObject_LengthHint(self.p)) def __getitem__(self, key): return pyobj(pyobj.exc_wrap(PyObject_GetItem(self.p, key.__to_py__())), steal=True) def __setitem__(self, key, v): pyobj.exc_wrap(PyObject_SetItem(self.p, key.__to_py__(), v.__to_py__())) def __delitem__(self, key): return pyobj.exc_wrap(PyObject_DelItem(self.p, key.__to_py__())) def __lt__(self, other): return pyobj(pyobj.exc_wrap(PyObject_RichCompare(self.p, other.__to_py__(), i32(Py_LT))), steal=True) def __le__(self, other): return pyobj(pyobj.exc_wrap(PyObject_RichCompare(self.p, other.__to_py__(), i32(Py_LE))), steal=True) def __eq__(self, other): return pyobj(pyobj.exc_wrap(PyObject_RichCompare(self.p, other.__to_py__(), i32(Py_EQ))), steal=True) def __ne__(self, other): return pyobj(pyobj.exc_wrap(PyObject_RichCompare(self.p, other.__to_py__(), i32(Py_NE))), steal=True) def __gt__(self, other): return pyobj(pyobj.exc_wrap(PyObject_RichCompare(self.p, other.__to_py__(), i32(Py_GT))), steal=True) def __ge__(self, other): return pyobj(pyobj.exc_wrap(PyObject_RichCompare(self.p, other.__to_py__(), i32(Py_GE))), steal=True) def __to_py__(self) -> cobj: return self.p def __from_py__(p: cobj) -> pyobj: return pyobj(p) def __str__(self) -> str: o = pyobj.exc_wrap(PyObject_Str(self.p)) return pyobj.exc_wrap(str.__from_py__(o)) def __repr__(self) -> str: o = pyobj.exc_wrap(PyObject_Repr(self.p)) return pyobj.exc_wrap(str.__from_py__(o)) def __hash__(self) -> int: return pyobj.exc_wrap(PyObject_Hash(self.p)) def __iter__(self) -> Generator[pyobj]: it = PyObject_GetIter(self.p) if not it: raise ValueError("Python object is not iterable") try: while i := PyIter_Next(it): yield pyobj(pyobj.exc_wrap(i), steal=True) finally: pyobj.decref(it) pyobj.exc_check() def to_str(self, errors: str, empty: str = "") -> str: return pyobj.to_str(self.p, errors, empty) def to_str(p: cobj, errors: str, empty: str = "") -> str: obj = PyUnicode_AsEncodedString(p, "utf-8".c_str(), errors.c_str()) if obj == cobj(): return empty bts = PyBytes_AsString(obj) res = str.from_ptr(bts) pyobj.decref(obj) return res def exc_check(): ptype, pvalue, ptraceback = cobj(), cobj(), cobj() PyErr_Fetch(__ptr__(ptype), __ptr__(pvalue), __ptr__(ptraceback)) if ptype != cobj(): py_msg = PyObject_Str(pvalue) if pvalue != cobj() else pvalue msg = pyobj.to_str(py_msg, "ignore", "") py_typ = PyObject_GetAttrString(ptype, "__name__".c_str()) typ = pyobj.to_str(py_typ, "ignore") pyobj.decref(ptype) pyobj.decref(pvalue) pyobj.decref(ptraceback) pyobj.decref(py_msg) pyobj.decref(py_typ) raise PyError(msg, typ) def exc_wrap(_retval: T, T: type) -> T: pyobj.exc_check() return _retval def incref(self): Py_IncRef(self.p) return self def incref(ptr: Ptr[byte]): Py_IncRef(ptr) def decref(self): Py_DecRef(self.p) return self def decref(ptr: Ptr[byte]): Py_DecRef(ptr) def __call__(self, *args, **kwargs): args_py = args.__to_py__() kws_py = cobj() if staticlen(kwargs) > 0: names = iter(kwargs.__dict__()) kws = {next(names): pyobj(i.__to_py__(), steal=True) for i in kwargs} kws_py = kws.__to_py__() return pyobj(pyobj.exc_wrap(PyObject_Call(self.p, args_py, kws_py)), steal=True) def _tuple_new(length: int): return pyobj.exc_wrap(PyTuple_New(length)) def _tuple_set(p: cobj, idx: int, val: cobj): PyTuple_SetItem(p, idx, val) pyobj.exc_check() def _tuple_get(p: cobj, idx: int) -> cobj: return pyobj.exc_wrap(PyTuple_GetItem(p, idx)) def _import(name: str) -> pyobj: ensure_initialized() if name in _PY_MODULE_CACHE: return _PY_MODULE_CACHE[name] m = pyobj(pyobj.exc_wrap(PyImport_ImportModule(name.c_str())), steal=True) _PY_MODULE_CACHE[name] = m return m def _exec(code: str): ensure_initialized() PyRun_SimpleString(code.c_str()) def _globals() -> pyobj: return pyobj(PyEval_GetGlobals()) def _get_module(name: str) -> pyobj: p = pyobj(pyobj.exc_wrap(PyImport_AddModule(name.c_str()))) return p def _main_module() -> pyobj: return pyobj._get_module("__main__") def _repr_mimebundle_(self, bundle=Set[str]()) -> Dict[str, str]: fn = pyobj._main_module()._getattr("__codon_repr__") assert fn.p != cobj(), "cannot find python.__codon_repr__" mime, txt = Tuple[str, str].__from_py__(fn.__call__(self).p) return {mime: txt} def __bool__(self): return bool(pyobj.exc_wrap(PyObject_IsTrue(self.p) == 1)) # Type conversions @extend class NoneType: def __to_py__(self) -> cobj: Py_IncRef(Py_None) return Py_None def __from_py__(i: cobj) -> None: return @extend class int: def __to_py__(self) -> cobj: return pyobj.exc_wrap(PyLong_FromLong(self)) def __from_py__(i: cobj) -> int: return pyobj.exc_wrap(PyLong_AsLong(i)) @extend class float: def __to_py__(self) -> cobj: return pyobj.exc_wrap(PyFloat_FromDouble(self)) def __from_py__(d: cobj) -> float: return pyobj.exc_wrap(PyFloat_AsDouble(d)) @extend class bool: def __to_py__(self) -> cobj: return pyobj.exc_wrap(PyBool_FromLong(int(self))) def __from_py__(b: cobj) -> bool: return pyobj.exc_wrap(PyObject_IsTrue(b)) != 0 @extend class byte: def __to_py__(self) -> cobj: return str.__to_py__(str(__ptr__(self), 1)) def __from_py__(c: cobj) -> byte: return str.__from_py__(c).ptr[0] @extend class str: def __to_py__(self) -> cobj: return pyobj.exc_wrap(PyUnicode_DecodeFSDefaultAndSize(self.ptr, self.len)) def __from_py__(s: cobj) -> str: return pyobj.exc_wrap(pyobj.to_str(s, "strict")) @extend class complex: def __to_py__(self) -> cobj: return pyobj.exc_wrap(PyComplex_FromDoubles(self.real, self.imag)) def __from_py__(c: cobj) -> complex: real = pyobj.exc_wrap(PyComplex_RealAsDouble(c)) imag = pyobj.exc_wrap(PyComplex_ImagAsDouble(c)) return complex(real, imag) @extend class List: def __to_py__(self) -> cobj: pylist = PyList_New(len(self)) pyobj.exc_check() idx = 0 for a in self: PyList_SetItem(pylist, idx, a.__to_py__()) pyobj.exc_check() idx += 1 return pylist def __from_py__(v: cobj) -> List[T]: n = pyobj.exc_wrap(PyObject_Length(v)) t = List[T](n) for i in range(n): elem = PyList_GetItem(v, i) pyobj.exc_check() t.append(T.__from_py__(elem)) return t @extend class Dict: def __to_py__(self) -> cobj: pydict = PyDict_New() pyobj.exc_check() for k, v in self.items(): PyDict_SetItem(pydict, k.__to_py__(), v.__to_py__()) pyobj.exc_check() return pydict def __from_py__(d: cobj) -> Dict[K, V]: b = dict[K, V]() pos = 0 k_ptr = cobj() v_ptr = cobj() while PyDict_Next(d, __ptr__(pos), __ptr__(k_ptr), __ptr__(v_ptr)): pyobj.exc_check() k = K.__from_py__(k_ptr) v = V.__from_py__(v_ptr) b[k] = v return b @extend class Set: def __to_py__(self) -> cobj: pyset = PySet_New(cobj()) pyobj.exc_check() for a in self: PySet_Add(pyset, a.__to_py__()) pyobj.exc_check() return pyset def __from_py__(s: cobj) -> Set[K]: b = set[K]() s_iter = pyobj.exc_wrap(PyObject_GetIter(s)) while True: k_ptr = pyobj.exc_wrap(PyIter_Next(s_iter)) if not k_ptr: break k = K.__from_py__(k_ptr) pyobj.decref(k_ptr) b.add(k) pyobj.decref(s_iter) return b @extend class Slice: def __to_py__(self) -> cobj: start = self.start stop = self.stop step = self.step start_py = start.__to_py__() if start is not None else cobj() stop_py = stop.__to_py__() if stop is not None else cobj() step_py = step.__to_py__() if step is not None else cobj() return PySlice_New(start_py, stop_py, step_py) def __from_py__(s: cobj) -> Slice: start = 0 stop = 0 step = 0 pyobj.exc_wrap(PySlice_Unpack(s, __ptr__(start), __ptr__(stop), __ptr__(step))) return Slice(Optional(start), Optional(stop), Optional(step)) @extend class Optional: def __to_py__(self) -> cobj: if self is None: return Py_None else: return self.__val__().__to_py__() def __from_py__(o: cobj) -> Optional[T]: if o == Py_None: return Optional[T]() else: return Optional[T](T.__from_py__(o))