Skip to content

Commit

Permalink
clean func signature and debug
Browse files Browse the repository at this point in the history
  • Loading branch information
cpunion committed Oct 30, 2024
1 parent 0f7f2de commit b1d1c72
Show file tree
Hide file tree
Showing 15 changed files with 26 additions and 70 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# go-python: a CPython wrapper for Go

Make Go and Python code inter-operable.

## Goal

- Provide automatically DecRef for Python objects.
- Wrap generic PyObject(s) to typed Python objects.
- Provide a way to define Python objects in LLGo.
- Provide a way to define Python objects in Go.

## Python types wrapper design

Expand All @@ -13,7 +17,7 @@ type pyObject struct {
obj *C.PyObject
}

func newObject(obj *C.PyObject) *pyObject {
func newObject(obj *PyObject) *pyObject {
o := &pyObject{obj}
runtime.SetFinalizer(o, func(o *pyObject) {
o.obj.DecRef()
Expand Down
8 changes: 0 additions & 8 deletions _demo/gradio/gradio.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import "C"

import (
"os"
"unsafe"

"github.com/cpunion/go-python"
)
Expand Down Expand Up @@ -48,13 +47,6 @@ func UpdateExamples(country string) python.Object {
}
}

//export UpdateExamples2
func UpdateExamples2(self, args *C.PyObject) *C.PyObject {
argsTuple := python.FromPy((*python.PyObject)(unsafe.Pointer(args))).AsTuple()
country := argsTuple.Get(0).String()
return (*C.PyObject)(unsafe.Pointer(UpdateExamples(country).Obj()))
}

func main() {
if len(os.Args) > 2 {
// avoid gradio start subprocesses
Expand Down
2 changes: 1 addition & 1 deletion bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Bool struct {
Object
}

func newBool(obj *C.PyObject) Bool {
func newBool(obj *PyObject) Bool {
return Bool{newObject(obj)}
}

Expand Down
2 changes: 1 addition & 1 deletion bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Bytes struct {
Object
}

func newBytes(obj *C.PyObject) Bytes {
func newBytes(obj *PyObject) Bytes {
return Bytes{newObject(obj)}
}

Expand Down
2 changes: 1 addition & 1 deletion complex.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Complex struct {
Object
}

func newComplex(obj *C.PyObject) Complex {
func newComplex(obj *PyObject) Complex {
return Complex{newObject(obj)}
}

Expand Down
4 changes: 2 additions & 2 deletions dict.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ type Dict struct {
Object
}

func newDict(obj *C.PyObject) Dict {
func newDict(obj *PyObject) Dict {
return Dict{newObject(obj)}
}

func NewDict(obj *C.PyObject) Dict {
func NewDict(obj *PyObject) Dict {
return newDict(obj)
}

Expand Down
2 changes: 1 addition & 1 deletion float.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Float struct {
Object
}

func newFloat(obj *C.PyObject) Float {
func newFloat(obj *PyObject) Float {
return Float{newObject(obj)}
}

Expand Down
51 changes: 5 additions & 46 deletions function.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Func struct {
Object
}

func newFunc(obj *C.PyObject) Func {
func newFunc(obj *PyObject) Func {
return Func{newObject(obj)}
}

Expand Down Expand Up @@ -69,30 +69,23 @@ func (f Func) Call(args ...any) Object {

type wrapperContext struct {
v any
t reflect.Type
}

//export wrapperFunc
func wrapperFunc(self, args *C.PyObject) *C.PyObject {
func wrapperFunc(self, args *PyObject) *PyObject {
wCtx := (*wrapperContext)(C.PyCapsule_GetPointer(self, AllocCStr("wrapperContext")))
fmt.Printf("wrapperContext: %p\n", wCtx)
// 恢复上下文
v := reflect.ValueOf(wCtx.v)
t := v.Type()
fmt.Printf("wrapperFunc type: %v\n", t)
// 构建参数

goArgs := make([]reflect.Value, t.NumIn())
argsTuple := FromPy(args).AsTuple()
fmt.Printf("args: %v\n", argsTuple)
for i := range goArgs {
goArgs[i] = reflect.New(t.In(i)).Elem()
ToValue(FromPy(C.PyTuple_GetItem(args, C.Py_ssize_t(i))), goArgs[i])
fmt.Printf("goArgs[%d]: %T\n", i, goArgs[i].Interface())
}

// 调用原始函数
results := v.Call(goArgs)

// 处理返回值
if len(results) == 0 {
return None().Obj()
}
Expand All @@ -117,8 +110,6 @@ func FuncOf1(name string, fn unsafe.Pointer, doc string) Func {
return newFunc(pyFn)
}

var ctxs = make(map[unsafe.Pointer]*wrapperContext)

func FuncOf(name string, fn any, doc string) Func {
m := MainModule()
v := reflect.ValueOf(fn)
Expand All @@ -127,13 +118,8 @@ func FuncOf(name string, fn any, doc string) Func {
fmt.Printf("type: %T, kind: %d\n", fn, t.Kind())
panic("AddFunction: fn must be a function")
}
println("FuncOf name:", name)
fmt.Printf("FuncOf type: %v\n", t)
ctx := new(wrapperContext)
ctx.v = fn
ctx := &wrapperContext{v: fn, t: t}
obj := C.PyCapsule_New(unsafe.Pointer(ctx), AllocCStr("wrapperContext"), nil)
fmt.Printf("FuncOf ctx: %p\n", ctx)
ctxs[unsafe.Pointer(ctx)] = ctx
def := &C.PyMethodDef{
ml_name: AllocCStr(name),
ml_meth: C.PyCFunction(C.wrapperFunc),
Expand All @@ -146,30 +132,3 @@ func FuncOf(name string, fn any, doc string) Func {
}
return newFunc(pyFn)
}

func buildFormatString(t reflect.Type) *C.char {
format := ""
for i := 0; i < t.NumIn(); i++ {
switch t.In(i).Kind() {
case reflect.Int, reflect.Int64:
format += "i"
case reflect.Float64:
format += "d"
case reflect.String:
format += "s"
// Add more types as needed
default:
panic(fmt.Sprintf("Unsupported argument type: %v", t.In(i)))
}
}
return AllocCStr(format)
}

func buildArgPointers(args []reflect.Value) []interface{} {
pointers := make([]interface{}, len(args))
for i := range args {
args[i] = reflect.New(args[i].Type()).Elem()
pointers[i] = args[i].Addr().Interface()
}
return pointers
}
2 changes: 1 addition & 1 deletion list.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type List struct {
Object
}

func newList(obj *C.PyObject) List {
func newList(obj *PyObject) List {
return List{newObject(obj)}
}

Expand Down
2 changes: 1 addition & 1 deletion long.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Long struct {
Object
}

func newLong(obj *C.PyObject) Long {
func newLong(obj *PyObject) Long {
return Long{newObject(obj)}
}

Expand Down
2 changes: 1 addition & 1 deletion module.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Module struct {
Object
}

func newModule(obj *C.PyObject) Module {
func newModule(obj *PyObject) Module {
return Module{newObject(obj)}
}

Expand Down
6 changes: 3 additions & 3 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type pyObject struct {
obj *C.PyObject
}

func (obj *pyObject) Obj() *C.PyObject {
func (obj *pyObject) Obj() *PyObject {
if obj == nil {
return nil
}
Expand Down Expand Up @@ -50,7 +50,7 @@ func (obj Object) object() Object {
return obj
}

func newObject(obj *C.PyObject) Object {
func newObject(obj *PyObject) Object {
if obj == nil {
C.PyErr_Print()
panic("nil Python object")
Expand Down Expand Up @@ -173,7 +173,7 @@ func (obj Object) String() string {
return newStr(C.PyObject_Str(obj.obj)).String()
}

func (obj Object) Obj() *C.PyObject {
func (obj Object) Obj() *PyObject {
if obj.Nil() {
return nil
}
Expand Down
1 change: 1 addition & 0 deletions python.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import "C"
import "unsafe"

type PyObject = C.PyObject
type PyCFunction = C.PyCFunction

func Initialize() {
C.Py_Initialize()
Expand Down
2 changes: 1 addition & 1 deletion tuple.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type Tuple struct {
Object
}

func newTuple(obj *C.PyObject) Tuple {
func newTuple(obj *PyObject) Tuple {
return Tuple{newObject(obj)}
}

Expand Down
2 changes: 1 addition & 1 deletion unicode.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Str struct {
Object
}

func newStr(obj *C.PyObject) Str {
func newStr(obj *PyObject) Str {
return Str{newObject(obj)}
}

Expand Down

0 comments on commit b1d1c72

Please sign in to comment.