From c4d1855cf18a96abe94bd921a48fef2e81c71be5 Mon Sep 17 00:00:00 2001 From: Micro Liu Date: Tue, 30 Sep 2025 11:59:15 +0800 Subject: [PATCH 1/3] feat: add signature source --- _xtool/pydump/pydump.go | 45 ++++++++++++++++++++++++----------------- symbol/symbol.go | 21 +++++++++++++++---- tool/pygen/genfunc.go | 4 ++-- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/_xtool/pydump/pydump.go b/_xtool/pydump/pydump.go index 7b8be43..9a45b4d 100644 --- a/_xtool/pydump/pydump.go +++ b/_xtool/pydump/pydump.go @@ -1,10 +1,11 @@ package main import ( - "os" + "encoding/json" "fmt" + "os" "strings" - "encoding/json" + "github.com/goplus/lib/c" "github.com/goplus/lib/py" "github.com/goplus/lib/py/inspect" @@ -38,55 +39,57 @@ func extractSignatureFromDoc(doc, funcName string) string { return strings.Join(fields, " ") } -func getSignature(val *py.Object, sym *symbol.Symbol) string { - // function, method, class, or implement __call__ +func getSignature(val *py.Object, sym *symbol.Symbol) (*symbol.Signature, error) { + // which implement __call__ if val.Callable() == 0 { - return "" + return nil, fmt.Errorf("not callable") } - // get signature from inspect + // inspect sigFromInspect := inspect.Signature(val) if sigFromInspect != nil { sig := c.GoString(sigFromInspect.Str().CStr()) - if sig != "(*args, **kwargs)" { - return sig - } + return &symbol.Signature{ + Source: symbol.SigSourceInspect, + Str: sig, + }, nil } - // get signature from doc + // doc sigFromDoc := extractSignatureFromDoc(sym.Doc, sym.Name) if sigFromDoc != "" { - return sigFromDoc + return &symbol.Signature{ + Source: symbol.SigSourceDoc, + Str: sigFromDoc, + }, nil } // Paradigms if pyFuncTypes[sym.Type] { - return "(*args, **kwargs)" + return &symbol.Signature{ + Source: symbol.SigSourceParadigm, + Str: "(*args, **kwargs)", + }, nil } - return "" + return nil, fmt.Errorf("failed to get signature") } // moduleName: Python module name func pydump(moduleName string) (*symbol.Module, error) { - // import module mod := py.ImportModule(c.AllocaCStr(moduleName)) if mod == nil { return nil, fmt.Errorf("failed to import module %s", moduleName) } - // get dict, python list Object keys := mod.ModuleGetDict().DictKeys() if keys == nil { return nil, fmt.Errorf("failed to get dict keys of %s", moduleName) } - // create module instance modInstance := &symbol.Module{ Name: moduleName, } - // get symbols for i, n := 0, keys.ListLen(); i < n; i++ { key := keys.ListItem(i) val := mod.GetAttr(key) if val == nil { continue } - // define symbol sym := &symbol.Symbol{} sym.Name = c.GoString(key.CStr()) sym.Type = c.GoString(val.Type().TypeName().CStr()) @@ -96,7 +99,11 @@ func pydump(moduleName string) (*symbol.Module, error) { } // functions if pyFuncTypes[sym.Type] { - sym.Sig = getSignature(val, sym) + sig, err := getSignature(val, sym) + if err != nil { + return nil, err + } + sym.Sig = *sig modInstance.Functions = append(modInstance.Functions, sym) } // TODO: variables, classes, etc. diff --git a/symbol/symbol.go b/symbol/symbol.go index e0e5d2b..9f159ce 100644 --- a/symbol/symbol.go +++ b/symbol/symbol.go @@ -1,10 +1,10 @@ package symbol type Symbol struct { - Name string `json:"name"` - Type string `json:"type"` - Doc string `json:"doc"` - Sig string `json:"sig"` + Name string `json:"name"` + Type string `json:"type"` + Doc string `json:"doc"` + Sig Signature `json:"sig"` } type Module struct { @@ -12,3 +12,16 @@ type Module struct { Functions []*Symbol `json:"functions"` // package functions // TODO: variables, classes, etc. } + +type SigSource int + +const ( + SigSourceDoc SigSource = iota + SigSourceInspect + SigSourceParadigm +) + +type Signature struct { + Str string `json:"str"` + Source SigSource `json:"source"` +} diff --git a/tool/pygen/genfunc.go b/tool/pygen/genfunc.go index 9474b7d..f34eada 100644 --- a/tool/pygen/genfunc.go +++ b/tool/pygen/genfunc.go @@ -13,12 +13,12 @@ func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol.Symbol) { if len(name) == 0 || name[0] == '_' { return } - if symSig == "" { // no signature + if symSig.Str == "" { // no signature ctx.skips = append(ctx.skips, *sym) return } // signature - params, variadic := ctx.genParams(pkg, symSig) + params, variadic := ctx.genParams(pkg, symSig.Str) goName := ctx.genName(name, -1) sig := types.NewSignatureType(nil, nil, nil, params, ctx.ret, variadic) // ret: *py.Object fn := pkg.NewFuncDecl(token.NoPos, goName, sig) From 3e852fb376f2e86cca58959c5a6d748df63b8be4 Mon Sep 17 00:00:00 2001 From: Micro Liu <858039956@qq.com> Date: Tue, 30 Sep 2025 12:06:06 +0800 Subject: [PATCH 2/3] chore: supplement signature comments Co-authored-by: niupilot[bot] <230321281+niupilot[bot]@users.noreply.github.com> Signed-off-by: Micro Liu <858039956@qq.com> --- symbol/symbol.go | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/symbol/symbol.go b/symbol/symbol.go index 9f159ce..ad40fe8 100644 --- a/symbol/symbol.go +++ b/symbol/symbol.go @@ -1,5 +1,23 @@ package symbol +// represents the origin of a function signature +type SigSource int + +const ( + // signature extracted from docstring + SigSourceDoc SigSource = iota + // signature from Python inspect module + SigSourceInspect + // generic fallback signature + SigSourceParadigm +) + +// represents a function signature with its source information +type Signature struct { + Str string `json:"str"` // The signature string + Source SigSource `json:"source"` // Where the signature was obtained +} + type Symbol struct { Name string `json:"name"` Type string `json:"type"` @@ -12,16 +30,3 @@ type Module struct { Functions []*Symbol `json:"functions"` // package functions // TODO: variables, classes, etc. } - -type SigSource int - -const ( - SigSourceDoc SigSource = iota - SigSourceInspect - SigSourceParadigm -) - -type Signature struct { - Str string `json:"str"` - Source SigSource `json:"source"` -} From 0b9d4ac4d9dde2a594dffdc12bead4fff15ecec1 Mon Sep 17 00:00:00 2001 From: Micro Liu Date: Fri, 10 Oct 2025 17:26:51 +0800 Subject: [PATCH 3/3] remove redundant check --- tool/pygen/genfunc.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tool/pygen/genfunc.go b/tool/pygen/genfunc.go index f34eada..40685ed 100644 --- a/tool/pygen/genfunc.go +++ b/tool/pygen/genfunc.go @@ -13,10 +13,6 @@ func (ctx *context) genFunc(pkg *gogen.Package, sym *symbol.Symbol) { if len(name) == 0 || name[0] == '_' { return } - if symSig.Str == "" { // no signature - ctx.skips = append(ctx.skips, *sym) - return - } // signature params, variadic := ctx.genParams(pkg, symSig.Str) goName := ctx.genName(name, -1)