func makeCFunction(name string, fn interface{}, doc string, mod_name *C.PyObject) (*CFunction, error) { ml := C.newMethodDef() switch fn.(type) { case func() (Object, error): C.set_call_noargs(&ml.ml_meth) ml.ml_flags = C.METH_NOARGS case func(a *Tuple) (Object, error): C.set_call_args(&ml.ml_meth) ml.ml_flags = C.METH_VARARGS case func(a *Tuple, k *Dict) (Object, error): C.set_call_keywords(&ml.ml_meth) ml.ml_flags = C.METH_VARARGS | C.METH_KEYWORDS default: C.free(unsafe.Pointer(ml)) return nil, TypeError.Err("CFunction_New: unknown func type for %s", name) } ret := C.PyCFunction_NewEx(ml, saveFunc(fn), mod_name) if ret == nil { C.free(unsafe.Pointer(ml)) return nil, exception() } ml.ml_name = C.CString(name) ml.ml_doc = C.CString(doc) return newCFunction(ret), nil }
func (closure *Closure) NewFunction(name string, nin int, doc string) *Base { d := &closure.methodDef d.ml_name = C.CString(name) defer C.free(unsafe.Pointer(d.ml_name)) if C.setMethod(d, C.int(nin)) != 0 { panic("Invalid arguments: nin") } if doc != "" { d.ml_doc = C.CString(doc) defer C.free(unsafe.Pointer(d.ml_doc)) } ctx := uintptr(unsafe.Pointer(closure)) self := C.PyLong_FromLongLong(C.longlong(ctx)) defer C.decref(self) f := C.PyCFunction_NewEx(d, self, nil) return (*Base)(unsafe.Pointer(f)) }