diff --git a/bind/gencpy.go b/bind/gencpy.go index cad715a..817f960 100644 --- a/bind/gencpy.go +++ b/bind/gencpy.go @@ -86,7 +86,7 @@ func (g *cpyGen) gen() error { case *types.Func: funcs = append(funcs, cpyFunc{typ: obj}) - docs[obj.Name()] = g.pkg.getDoc(obj) + docs[obj.Name()] = g.getPyDoc(obj) case *types.TypeName: named := obj.Type().(*types.Named) @@ -322,7 +322,7 @@ func (g *cpyGen) genStruct(cpy cpyStruct) { g.impl.Printf("0,\t/*tp_setattro*/\n") g.impl.Printf("0,\t/*tp_as_buffer*/\n") g.impl.Printf("Py_TPFLAGS_DEFAULT,\t/*tp_flags*/\n") - g.impl.Printf("%q,\t/* tp_doc */\n", g.pkg.getDoc(obj)) + g.impl.Printf("%q,\t/* tp_doc */\n", g.getPyDoc(obj)) g.impl.Printf("0,\t/* tp_traverse */\n") g.impl.Printf("0,\t/* tp_clear */\n") g.impl.Printf("0,\t/* tp_richcompare */\n") @@ -549,3 +549,46 @@ func (g *cpyGen) genPreamble() { n := g.pkg.pkg.Name() g.decl.Printf(cPreamble, n, g.pkg.pkg.Path(), filepath.Base(n)) } + +func (g *cpyGen) getPyDoc(o types.Object) string { + doc := g.pkg.getDoc(o) + + switch o.(type) { + + case *types.Func: + sig := o.Type().(*types.Signature) + + parseFn := func(tup *types.Tuple) []string { + params := []string{} + if tup == nil { + return params + } + for i := 0; i < tup.Len(); i++ { + paramVar := tup.At(i) + paramType := pyTypeName(paramVar.Type()) + if paramVar.Name() != "" { + paramType = fmt.Sprintf("%s %s", paramType, paramVar.Name()) + } + params = append(params, paramType) + } + return params + } + + params := parseFn(sig.Params()) + results := parseFn(sig.Results()) + + paramString := strings.Join(params, ", ") + resultString := strings.Join(results, ", ") + + docSig := fmt.Sprintf("%s(%s) %s", o.Name(), paramString, resultString) + + if doc != "" { + doc = fmt.Sprintf("%s\n\n%s", docSig, doc) + } else { + doc = docSig + } + + } + + return doc +} diff --git a/bind/types.go b/bind/types.go index 4dc3a3d..6bdee33 100644 --- a/bind/types.go +++ b/bind/types.go @@ -45,10 +45,23 @@ func cgoTypeName(typ types.Type) string { return typ.String() } +func pyTypeName(typ types.Type) string { + switch typ := typ.(type) { + case *types.Basic: + kind := typ.Kind() + o, ok := typedescr[kind] + if ok { + return o.pysig + } + } + return "object" +} + type typedesc struct { ctype string cgotype string pyfmt string + pysig string } var typedescr = map[types.BasicKind]typedesc{ @@ -56,101 +69,118 @@ var typedescr = map[types.BasicKind]typedesc{ ctype: "_Bool", cgotype: "GoBool", pyfmt: "b", + pysig: "bool", }, types.Int: typedesc{ ctype: "int", cgotype: "GoInt", pyfmt: "i", + pysig: "int", }, types.Int8: typedesc{ ctype: "int8_t", cgotype: "GoInt8", pyfmt: "c", + pysig: "int", }, types.Int16: typedesc{ ctype: "int16_t", cgotype: "GoInt16", pyfmt: "h", + pysig: "int", }, types.Int32: typedesc{ ctype: "int32_t", cgotype: "GoInt32", pyfmt: "i", + pysig: "long", }, types.Int64: typedesc{ ctype: "int64_t", cgotype: "GoInt64", pyfmt: "k", + pysig: "long", }, types.Uint: typedesc{ ctype: "unsigned int", cgotype: "GoUint", pyfmt: "I", + pysig: "int", }, types.Uint8: typedesc{ ctype: "uint8_t", cgotype: "GoUint8", pyfmt: "b", + pysig: "int", }, types.Uint16: typedesc{ ctype: "uint16_t", cgotype: "GoUint16", pyfmt: "H", + pysig: "int", }, types.Uint32: typedesc{ ctype: "uint32_t", cgotype: "GoUint32", pyfmt: "I", + pysig: "long", }, types.Uint64: typedesc{ ctype: "uint64_t", cgotype: "GoUint64", pyfmt: "K", + pysig: "long", }, types.Float32: typedesc{ ctype: "float", cgotype: "float", pyfmt: "f", + pysig: "float", }, types.Float64: typedesc{ ctype: "double", cgotype: "double", pyfmt: "d", + pysig: "float", }, types.Complex64: typedesc{ ctype: "float complex", cgotype: "GoComplex64", pyfmt: "D", + pysig: "float", }, types.Complex128: typedesc{ ctype: "double complex", cgotype: "GoComplex128", pyfmt: "D", + pysig: "float", }, types.String: typedesc{ ctype: "const char*", cgotype: "GoString", pyfmt: "s", + pysig: "str", }, types.UnsafePointer: typedesc{ ctype: "void*", cgotype: "void*", pyfmt: "?", + pysig: "object", }, }