mirror of https://github.com/go-python/gopy.git
major progress -- handling most things in emer now except emer itself..
This commit is contained in:
parent
3c4cffd8dd
commit
849847c8d4
|
@ -15,6 +15,10 @@ import (
|
|||
func (g *pybindGen) genFuncSig(sym *symbol, fsym Func) bool {
|
||||
isMethod := (sym != nil)
|
||||
|
||||
if fsym.sig == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
sig := fsym.sig
|
||||
args := sig.Params()
|
||||
res := sig.Results()
|
||||
|
@ -175,6 +179,9 @@ if err != nil {
|
|||
g.gofile.Indent()
|
||||
if nres > 0 {
|
||||
ret := res[0]
|
||||
if ret.sym.zval == "" {
|
||||
fmt.Printf("gopy: programmer error: empty zval zero value in symbol: %v\n", ret.sym)
|
||||
}
|
||||
if ret.sym.go2py != "" {
|
||||
g.gofile.Printf("return %s(%s)\n", ret.sym.go2py, ret.sym.zval)
|
||||
} else {
|
||||
|
@ -216,9 +223,9 @@ if err != nil {
|
|||
na := ""
|
||||
if arg.sym.py2go != "" {
|
||||
if arg.sym.hasHandle() && !arg.sym.isPtrOrIface() {
|
||||
na = fmt.Sprintf("*%s(%s)", arg.sym.py2go, arg.Name())
|
||||
na = fmt.Sprintf("*%s(%s)%s", arg.sym.py2go, arg.Name(), arg.sym.py2goParenEx)
|
||||
} else {
|
||||
na = fmt.Sprintf("%s(%s)", arg.sym.py2go, arg.Name())
|
||||
na = fmt.Sprintf("%s(%s)%s", arg.sym.py2go, arg.Name(), arg.sym.py2goParenEx)
|
||||
}
|
||||
} else {
|
||||
na = arg.Name()
|
||||
|
|
|
@ -149,7 +149,7 @@ otherwise parameter is a python list that we copy from
|
|||
g.gofile.Indent()
|
||||
g.gofile.Printf("s := *ptrFmHandle_%s(handle)\n", slNm)
|
||||
if esym.py2go != "" {
|
||||
g.gofile.Printf("s[idx] = %s(value)\n", esym.py2go)
|
||||
g.gofile.Printf("s[idx] = %s(value)%s\n", esym.py2go, esym.py2goParenEx)
|
||||
} else {
|
||||
g.gofile.Printf("s[idx] = value\n")
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ otherwise parameter is a python list that we copy from
|
|||
g.gofile.Indent()
|
||||
g.gofile.Printf("s := ptrFmHandle_%s(handle)\n", slNm)
|
||||
if esym.py2go != "" {
|
||||
g.gofile.Printf("*s = append(*s, %s(value))\n", esym.py2go)
|
||||
g.gofile.Printf("*s = append(*s, %s(value)%s)\n", esym.py2go, esym.py2goParenEx)
|
||||
} else {
|
||||
g.gofile.Printf("*s = append(*s, value)\n")
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ func (g *pybindGen) genStructMembers(s Struct) {
|
|||
typ := s.Struct()
|
||||
for i := 0; i < typ.NumFields(); i++ {
|
||||
f := typ.Field(i)
|
||||
if !f.Exported() {
|
||||
if !f.Exported() || f.Embedded() {
|
||||
continue
|
||||
}
|
||||
g.genStructMemberGetter(s, i, f)
|
||||
|
@ -178,9 +178,9 @@ func (g *pybindGen) genStructMemberSetter(s Struct, i int, f types.Object) {
|
|||
g.gofile.Printf("op := ptrFmHandle_%s(handle)\n", s.GoName())
|
||||
if ret.go2py != "" {
|
||||
if ret.hasHandle() && !ret.isPtrOrIface() {
|
||||
g.gofile.Printf("op.%s = *%s(val)", f.Name(), ret.py2go)
|
||||
g.gofile.Printf("op.%s = *%s(val)%s", f.Name(), ret.py2go, ret.py2goParenEx)
|
||||
} else {
|
||||
g.gofile.Printf("op.%s = %s(val)", f.Name(), ret.py2go)
|
||||
g.gofile.Printf("op.%s = %s(val)%s", f.Name(), ret.py2go, ret.py2goParenEx)
|
||||
}
|
||||
} else {
|
||||
g.gofile.Printf("op.%s = val", f.Name())
|
||||
|
|
|
@ -34,31 +34,37 @@ func (g *pybindGen) genType(sym *symbol) {
|
|||
}
|
||||
|
||||
func (g *pybindGen) genTypeHandlePtr(sym *symbol) {
|
||||
g.gofile.Printf("\n// Converters for pointer handles for type: %s\n", sym.gofmt())
|
||||
g.gofile.Printf("func %s(h CGoHandle) %s {\n", sym.py2go, sym.gofmt())
|
||||
gonm := sym.gofmt()
|
||||
g.gofile.Printf("\n// Converters for pointer handles for type: %s\n", gonm)
|
||||
g.gofile.Printf("func %s(h CGoHandle) %s {\n", sym.py2go, gonm)
|
||||
g.gofile.Indent()
|
||||
g.gofile.Printf("p := gopyh.VarHand.VarFmHandle((gopyh.CGoHandle)(h), %[1]q)\n", sym.gofmt())
|
||||
g.gofile.Printf("p := gopyh.VarHand.VarFmHandle((gopyh.CGoHandle)(h), %[1]q)\n", gonm)
|
||||
g.gofile.Printf("if p == nil {\n")
|
||||
g.gofile.Indent()
|
||||
g.gofile.Printf("return nil\n")
|
||||
g.gofile.Outdent()
|
||||
g.gofile.Printf("}\n")
|
||||
g.gofile.Printf("return p.(%[1]s)\n", sym.gofmt())
|
||||
g.gofile.Printf("return p.(%[1]s)\n", gonm)
|
||||
g.gofile.Outdent()
|
||||
g.gofile.Printf("}\n")
|
||||
g.gofile.Printf("func %s(p interface{}) CGoHandle {\n", sym.go2py)
|
||||
g.gofile.Indent()
|
||||
g.gofile.Printf("return CGoHandle(gopyh.VarHand.Register(\"%s\", p))\n", sym.gofmt())
|
||||
g.gofile.Printf("return CGoHandle(gopyh.VarHand.Register(\"%s\", p))\n", gonm)
|
||||
g.gofile.Outdent()
|
||||
g.gofile.Printf("}\n")
|
||||
}
|
||||
|
||||
func (g *pybindGen) genTypeHandle(sym *symbol) {
|
||||
ptrnm := "*" + sym.gofmt()
|
||||
g.gofile.Printf("\n// Converters for non-pointer handles for type: %s\n", sym.gofmt())
|
||||
g.gofile.Printf("func %s(h CGoHandle) %s {\n", sym.py2go, ptrnm)
|
||||
gonm := sym.gofmt()
|
||||
ptrnm := "*" + gonm
|
||||
py2go := sym.py2go
|
||||
if py2go[0] == '*' {
|
||||
py2go = py2go[1:]
|
||||
}
|
||||
g.gofile.Printf("\n// Converters for non-pointer handles for type: %s\n", gonm)
|
||||
g.gofile.Printf("func %s(h CGoHandle) %s {\n", py2go, ptrnm)
|
||||
g.gofile.Indent()
|
||||
g.gofile.Printf("p := gopyh.VarHand.VarFmHandle((gopyh.CGoHandle)(h), %[1]q)\n", sym.gofmt())
|
||||
g.gofile.Printf("p := gopyh.VarHand.VarFmHandle((gopyh.CGoHandle)(h), %[1]q)\n", gonm)
|
||||
g.gofile.Printf("if p == nil {\n")
|
||||
g.gofile.Indent()
|
||||
g.gofile.Printf("return nil\n")
|
||||
|
@ -69,7 +75,7 @@ func (g *pybindGen) genTypeHandle(sym *symbol) {
|
|||
g.gofile.Printf("}\n")
|
||||
g.gofile.Printf("func %s(p interface{}) CGoHandle {\n", sym.go2py)
|
||||
g.gofile.Indent()
|
||||
g.gofile.Printf("return CGoHandle(gopyh.VarHand.Register(\"%s\", p))\n", sym.gofmt())
|
||||
g.gofile.Printf("return CGoHandle(gopyh.VarHand.Register(\"%s\", p))\n", gonm)
|
||||
g.gofile.Outdent()
|
||||
g.gofile.Printf("}\n")
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ func (g *pybindGen) genVarSetter(v Var) {
|
|||
g.gofile.Indent()
|
||||
if v.sym.go2py != "" {
|
||||
if v.sym.hasHandle() && !v.sym.isPtrOrIface() {
|
||||
g.gofile.Printf("%s = *%s(val)", qVn, v.sym.py2go)
|
||||
g.gofile.Printf("%s = *%s(val)%s", qVn, v.sym.py2go, v.sym.py2goParenEx)
|
||||
} else {
|
||||
g.gofile.Printf("%s = %s(val)", qVn, v.sym.py2go)
|
||||
g.gofile.Printf("%s = %s(val)%s", qVn, v.sym.py2go, v.sym.py2goParenEx)
|
||||
}
|
||||
} else {
|
||||
g.gofile.Printf("%s = val", qVn)
|
||||
|
|
|
@ -86,6 +86,11 @@ func (p *Package) getDoc(parent string, o types.Object) string {
|
|||
}
|
||||
|
||||
case *types.Func:
|
||||
sig := o.Type().(*types.Signature)
|
||||
err, _, _ := isPyCompatFunc(sig)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
doc := func() string {
|
||||
if o.Parent() == nil || (o.Parent() != nil && parent != "") {
|
||||
for _, typ := range p.doc.Types {
|
||||
|
@ -116,8 +121,6 @@ func (p *Package) getDoc(parent string, o types.Object) string {
|
|||
return ""
|
||||
}()
|
||||
|
||||
sig := o.Type().(*types.Signature)
|
||||
|
||||
parseFn := func(tup *types.Tuple) []string {
|
||||
params := []string{}
|
||||
if tup == nil {
|
||||
|
@ -318,10 +321,7 @@ func (p *Package) process() error {
|
|||
mname := types.ObjectString(m, nil)
|
||||
msym := p.syms.sym(mname)
|
||||
if msym == nil {
|
||||
panic(fmt.Errorf(
|
||||
"gopy: could not retrieve symbol for %q",
|
||||
m.FullName(),
|
||||
))
|
||||
continue
|
||||
}
|
||||
msym.doc = doc
|
||||
}
|
||||
|
|
314
bind/symbols.go
314
bind/symbols.go
|
@ -77,39 +77,40 @@ func (k symkind) String() string {
|
|||
|
||||
// symbol is an exported symbol in a go package
|
||||
type symbol struct {
|
||||
kind symkind
|
||||
gopkg *types.Package
|
||||
goobj types.Object
|
||||
gotyp types.Type
|
||||
doc string
|
||||
id string // mangled name of entity (eg: <pkg>_<name>)
|
||||
goname string // name of go entity
|
||||
pyname string // name of python entity (nonptrname, cleaned-up slice name)
|
||||
cgoname string // type name of entity for cgo -- handle for objs
|
||||
cpyname string // type name of entity for cgo - python -- handle..
|
||||
pysig string // type string for doc-signatures
|
||||
go2py string // name of go->py converter function
|
||||
py2go string // name of py->go converter function
|
||||
zval string // zero value representation
|
||||
kind symkind
|
||||
gopkg *types.Package
|
||||
goobj types.Object
|
||||
gotyp types.Type
|
||||
doc string
|
||||
id string // mangled name of entity (eg: <pkg>_<name>)
|
||||
goname string // name of go entity
|
||||
pyname string // name of python entity (nonptrname, cleaned-up slice name)
|
||||
cgoname string // type name of entity for cgo -- handle for objs
|
||||
cpyname string // type name of entity for cgo - python -- handle..
|
||||
pysig string // type string for doc-signatures
|
||||
go2py string // name of go->py converter function
|
||||
py2go string // name of py->go converter function
|
||||
py2goParenEx string // extra parentheses needed at end of py2go (beyond 1 default)
|
||||
zval string // zero value representation
|
||||
}
|
||||
|
||||
func isPrivate(s string) bool {
|
||||
return (strings.ToLower(s[0:1]) == s[0:1])
|
||||
}
|
||||
|
||||
func (s symbol) isType() bool {
|
||||
func (s *symbol) isType() bool {
|
||||
return (s.kind & skType) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isNamed() bool {
|
||||
func (s *symbol) isNamed() bool {
|
||||
return (s.kind & skNamed) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isBasic() bool {
|
||||
func (s *symbol) isBasic() bool {
|
||||
return (s.kind & skBasic) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isNamedBasic() bool {
|
||||
func (s *symbol) isNamedBasic() bool {
|
||||
if !s.isNamed() {
|
||||
return false
|
||||
}
|
||||
|
@ -120,65 +121,65 @@ func (s symbol) isNamedBasic() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (s symbol) isArray() bool {
|
||||
func (s *symbol) isArray() bool {
|
||||
return (s.kind & skArray) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isInterface() bool {
|
||||
func (s *symbol) isInterface() bool {
|
||||
return (s.kind & skInterface) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isSignature() bool {
|
||||
func (s *symbol) isSignature() bool {
|
||||
return (s.kind & skSignature) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isMap() bool {
|
||||
func (s *symbol) isMap() bool {
|
||||
return (s.kind & skMap) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isPySequence() bool {
|
||||
func (s *symbol) isPySequence() bool {
|
||||
return s.isArray() || s.isSlice() || s.isMap()
|
||||
}
|
||||
|
||||
func (s symbol) isSlice() bool {
|
||||
func (s *symbol) isSlice() bool {
|
||||
return (s.kind & skSlice) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isStruct() bool {
|
||||
func (s *symbol) isStruct() bool {
|
||||
return (s.kind & skStruct) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isPointer() bool {
|
||||
func (s *symbol) isPointer() bool {
|
||||
return (s.kind & skPointer) != 0
|
||||
}
|
||||
|
||||
func (s symbol) isPtrOrIface() bool {
|
||||
func (s *symbol) isPtrOrIface() bool {
|
||||
return s.isPointer() || s.isInterface()
|
||||
}
|
||||
|
||||
func (s symbol) hasHandle() bool {
|
||||
func (s *symbol) hasHandle() bool {
|
||||
return !s.isBasic()
|
||||
}
|
||||
|
||||
func (s symbol) hasConverter() bool {
|
||||
func (s *symbol) hasConverter() bool {
|
||||
return (s.go2py != "" || s.py2go != "")
|
||||
}
|
||||
|
||||
func (s symbol) pkgname() string {
|
||||
func (s *symbol) pkgname() string {
|
||||
if s.gopkg == nil {
|
||||
return ""
|
||||
}
|
||||
return s.gopkg.Name()
|
||||
}
|
||||
|
||||
func (s symbol) GoType() types.Type {
|
||||
func (s *symbol) GoType() types.Type {
|
||||
if s.goobj != nil {
|
||||
return s.goobj.Type()
|
||||
}
|
||||
return s.gotyp
|
||||
}
|
||||
|
||||
func (s symbol) cgotypename() string {
|
||||
func (s *symbol) cgotypename() string {
|
||||
typ := s.gotyp
|
||||
switch typ := typ.(type) {
|
||||
case *types.Basic:
|
||||
|
@ -201,11 +202,10 @@ func (s symbol) cgotypename() string {
|
|||
return s.cgoname
|
||||
}
|
||||
|
||||
func (s symbol) gofmt() string {
|
||||
func (s *symbol) gofmt() string {
|
||||
return types.TypeString(
|
||||
s.GoType(),
|
||||
func(*types.Package) string { return s.pkgname() },
|
||||
)
|
||||
func(pkg *types.Package) string { return pkg.Name() })
|
||||
}
|
||||
|
||||
// symtab is a table of symbols in a go package
|
||||
|
@ -314,20 +314,22 @@ func (sym *symtab) addSymbol(obj types.Object) {
|
|||
sym.addType(obj, obj.Type())
|
||||
|
||||
case *types.Func:
|
||||
sym.syms[fn] = &symbol{
|
||||
gopkg: pkg,
|
||||
goobj: obj,
|
||||
kind: skFunc,
|
||||
id: id,
|
||||
goname: n,
|
||||
pyname: pyname,
|
||||
cgoname: n,
|
||||
cpyname: n,
|
||||
}
|
||||
sig := obj.Type().Underlying().(*types.Signature)
|
||||
sym.processTuple(sig.Params())
|
||||
sym.processTuple(sig.Results())
|
||||
|
||||
err, _, _ := isPyCompatFunc(sig)
|
||||
if err == nil {
|
||||
sym.syms[fn] = &symbol{
|
||||
gopkg: pkg,
|
||||
goobj: obj,
|
||||
kind: skFunc,
|
||||
id: id,
|
||||
goname: n,
|
||||
pyname: pyname,
|
||||
cgoname: n,
|
||||
cpyname: n,
|
||||
}
|
||||
sym.processTuple(sig.Params())
|
||||
sym.processTuple(sig.Results())
|
||||
}
|
||||
case *types.TypeName:
|
||||
sym.addType(obj, obj.Type())
|
||||
|
||||
|
@ -350,16 +352,46 @@ func (sym *symtab) processTuple(tuple *types.Tuple) {
|
|||
}
|
||||
}
|
||||
|
||||
// typePackage gets the package for a given types.Type
|
||||
func typePackage(t types.Type) *types.Package {
|
||||
if tn, ok := t.(*types.Named); ok {
|
||||
return tn.Obj().Pkg()
|
||||
// isPyCompatFunc checks if function signature is a python-compatible function.
|
||||
// Returns nil if function is compatible, err message if not.
|
||||
// Also returns the return type of the function
|
||||
// extra bool is true if 2nd arg is an error type, which is only
|
||||
// supported form of multi-return-value functions
|
||||
func isPyCompatFunc(sig *types.Signature) (error, types.Type, bool) {
|
||||
haserr := false
|
||||
res := sig.Results()
|
||||
var ret types.Type
|
||||
|
||||
switch res.Len() {
|
||||
case 2:
|
||||
if !isErrorType(res.At(1).Type()) {
|
||||
return fmt.Errorf("gopy: second result value must be of type error: %s", sig.String()), ret, haserr
|
||||
}
|
||||
haserr = true
|
||||
ret = res.At(0).Type()
|
||||
case 1:
|
||||
if isErrorType(res.At(0).Type()) {
|
||||
haserr = true
|
||||
ret = nil
|
||||
} else {
|
||||
ret = res.At(0).Type()
|
||||
}
|
||||
case 0:
|
||||
ret = nil
|
||||
default:
|
||||
return fmt.Errorf("gopy: too many results to return: %s", sig.String()), ret, haserr
|
||||
}
|
||||
switch tt := t.(type) {
|
||||
case *types.Pointer:
|
||||
return typePackage(tt.Elem())
|
||||
|
||||
args := sig.Params()
|
||||
nargs := args.Len()
|
||||
for i := 0; i < nargs; i++ {
|
||||
arg := args.At(i)
|
||||
argt := arg.Type()
|
||||
if _, isSig := argt.(*types.Signature); isSig {
|
||||
return fmt.Errorf("gopy: func args (signature) not supported: %s", sig.String()), ret, haserr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, ret, haserr
|
||||
}
|
||||
|
||||
// goToPyName translates a go type name to a safe python-usable
|
||||
|
@ -371,21 +403,35 @@ func goToPyName(gon string) string {
|
|||
return pyn
|
||||
}
|
||||
|
||||
func (sym *symtab) addType(obj types.Object, t types.Type) {
|
||||
fn := sym.typename(t, nil)
|
||||
// typePkg gets the package for a given types.Type
|
||||
func typePkg(t types.Type) *types.Package {
|
||||
if tn, ok := t.(*types.Named); ok {
|
||||
return tn.Obj().Pkg()
|
||||
}
|
||||
switch tt := t.(type) {
|
||||
case *types.Pointer:
|
||||
return typePkg(tt.Elem())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// typeNamePkg gets the name and package for a given types.Type -- deals with
|
||||
// naming for types in other packages, and adds those packages to imports paths.
|
||||
// Falls back on sym.pkg if no other package info avail.
|
||||
func (sym *symtab) typeNamePkg(t types.Type) (string, *types.Package) {
|
||||
n := sym.typename(t, sym.pkg)
|
||||
var pkg *types.Package
|
||||
if lidx := strings.LastIndex(n, "/"); lidx > 0 {
|
||||
qnm := n[lidx+1:]
|
||||
n = strings.Replace(qnm, ".", "_", 1)
|
||||
pkg = typePackage(t)
|
||||
pkg = typePkg(t)
|
||||
if pkg != nil {
|
||||
ip := pkg.Path()
|
||||
sym.imports[ip] = ip
|
||||
}
|
||||
} else if pidx := strings.LastIndex(n, "."); pidx > 0 {
|
||||
n = strings.Replace(n, ".", "_", 1)
|
||||
pkg = typePackage(t)
|
||||
pkg = typePkg(t)
|
||||
if pkg != nil {
|
||||
ip := pkg.Path()
|
||||
sym.imports[ip] = ip
|
||||
|
@ -394,6 +440,12 @@ func (sym *symtab) addType(obj types.Object, t types.Type) {
|
|||
if pkg == nil {
|
||||
pkg = sym.pkg
|
||||
}
|
||||
return n, pkg
|
||||
}
|
||||
|
||||
func (sym *symtab) addType(obj types.Object, t types.Type) {
|
||||
fn := sym.typename(t, nil)
|
||||
n, pkg := sym.typeNamePkg(t)
|
||||
id := n
|
||||
if pkg != nil {
|
||||
id = pkg.Name() + "_" + n
|
||||
|
@ -407,6 +459,9 @@ func (sym *symtab) addType(obj types.Object, t types.Type) {
|
|||
panic(fmt.Errorf("builtin type not already known [%s]!", n))
|
||||
}
|
||||
|
||||
case *types.Pointer:
|
||||
sym.addPointerType(pkg, obj, t, kind, id, n)
|
||||
|
||||
case *types.Array:
|
||||
sym.addArrayType(pkg, obj, t, kind, id, n)
|
||||
|
||||
|
@ -424,19 +479,28 @@ func (sym *symtab) addType(obj types.Object, t types.Type) {
|
|||
|
||||
case *types.Basic:
|
||||
styp := sym.symtype(st)
|
||||
py2go := pkg.Name() + "." + sym.typename(t, pkg)
|
||||
py2goParEx := ""
|
||||
if styp.py2go != "" {
|
||||
py2go += "(" + styp.py2go
|
||||
py2goParEx = ")"
|
||||
}
|
||||
|
||||
sym.syms[fn] = &symbol{
|
||||
gopkg: pkg,
|
||||
goobj: obj,
|
||||
gotyp: t,
|
||||
kind: kind | skBasic,
|
||||
id: id,
|
||||
goname: styp.goname,
|
||||
pyname: styp.pyname,
|
||||
cgoname: styp.cgoname,
|
||||
cpyname: styp.cpyname,
|
||||
pysig: styp.pysig,
|
||||
go2py: styp.cgoname,
|
||||
py2go: pkg.Name() + "." + n,
|
||||
gopkg: pkg,
|
||||
goobj: obj,
|
||||
gotyp: t,
|
||||
kind: kind | skBasic,
|
||||
id: id,
|
||||
goname: styp.goname,
|
||||
pyname: styp.pyname,
|
||||
cgoname: styp.cgoname,
|
||||
cpyname: styp.cpyname,
|
||||
pysig: styp.pysig,
|
||||
go2py: styp.cgoname,
|
||||
py2go: py2go,
|
||||
py2goParenEx: py2goParEx,
|
||||
zval: styp.zval,
|
||||
}
|
||||
|
||||
case *types.Array:
|
||||
|
@ -471,9 +535,6 @@ func (sym *symtab) addType(obj types.Object, t types.Type) {
|
|||
}
|
||||
}
|
||||
|
||||
case *types.Pointer:
|
||||
sym.addPointerType(pkg, obj, t, kind, id, n)
|
||||
|
||||
case *types.Map:
|
||||
sym.addMapType(pkg, obj, t, kind, id, n)
|
||||
|
||||
|
@ -491,10 +552,13 @@ func (sym *symtab) addArrayType(pkg *types.Package, obj types.Object, t types.Ty
|
|||
if elt == nil || elt.goname == "" {
|
||||
eltname := sym.typename(typ.Elem(), pkg)
|
||||
eobj := sym.pkg.Scope().Lookup(eltname)
|
||||
if eobj == nil {
|
||||
panic(fmt.Errorf("could not look-up %q!\n", enam))
|
||||
if eobj != nil {
|
||||
sym.addSymbol(eobj)
|
||||
} else {
|
||||
if ntyp, ok := typ.Elem().(*types.Named); ok {
|
||||
sym.addType(ntyp.Obj(), typ.Elem())
|
||||
}
|
||||
}
|
||||
sym.addSymbol(eobj)
|
||||
elt = sym.sym(enam)
|
||||
if elt == nil {
|
||||
panic(fmt.Errorf(
|
||||
|
@ -528,21 +592,22 @@ func (sym *symtab) addMapType(pkg *types.Package, obj types.Object, t types.Type
|
|||
fn := sym.typename(t, nil)
|
||||
typ := t.Underlying().(*types.Map)
|
||||
kind |= skMap
|
||||
enam := sym.typename(typ.Elem(), nil)
|
||||
elt := sym.sym(enam)
|
||||
if elt == nil || elt.goname == "" {
|
||||
eltname := sym.typename(typ.Elem(), pkg)
|
||||
elt := typ.Elem()
|
||||
enam := sym.typename(elt, nil)
|
||||
elsym := sym.sym(enam)
|
||||
if elsym == nil || elsym.goname == "" {
|
||||
eltname, _ := sym.typeNamePkg(elt)
|
||||
eobj := sym.pkg.Scope().Lookup(eltname)
|
||||
if eobj == nil {
|
||||
panic(fmt.Errorf("could not look-up %q!\n", enam))
|
||||
if eobj != nil {
|
||||
sym.addSymbol(eobj)
|
||||
} else {
|
||||
if ntyp, ok := elt.(*types.Named); ok {
|
||||
sym.addType(ntyp.Obj(), elt)
|
||||
}
|
||||
}
|
||||
sym.addSymbol(eobj)
|
||||
elt = sym.sym(enam)
|
||||
if elt == nil {
|
||||
panic(fmt.Errorf(
|
||||
"gopy: could not retrieve map-elt symbol for %q",
|
||||
enam,
|
||||
))
|
||||
elsym = sym.sym(enam)
|
||||
if elsym == nil {
|
||||
panic(fmt.Errorf("gopy: map key type must be named type if outside current package: %q", enam))
|
||||
}
|
||||
}
|
||||
pyname := n
|
||||
|
@ -570,22 +635,24 @@ func (sym *symtab) addSliceType(pkg *types.Package, obj types.Object, t types.Ty
|
|||
fn := sym.typename(t, nil)
|
||||
typ := t.Underlying().(*types.Slice)
|
||||
kind |= skSlice
|
||||
enam := sym.typename(typ.Elem(), nil)
|
||||
elt := sym.sym(enam)
|
||||
if elt == nil || elt.goname == "" {
|
||||
eltname := sym.typename(typ.Elem(), pkg)
|
||||
elt := typ.Elem()
|
||||
enam := sym.typename(elt, nil)
|
||||
elsym := sym.sym(enam)
|
||||
if elsym == nil || elsym.goname == "" {
|
||||
eltname, _ := sym.typeNamePkg(elt)
|
||||
eobj := sym.pkg.Scope().Lookup(eltname)
|
||||
if eobj == nil {
|
||||
panic(fmt.Errorf("could not look-up %q!\n", enam))
|
||||
if eobj != nil {
|
||||
sym.addSymbol(eobj)
|
||||
} else {
|
||||
if ntyp, ok := elt.(*types.Named); ok {
|
||||
sym.addType(ntyp.Obj(), elt)
|
||||
}
|
||||
}
|
||||
sym.addSymbol(eobj)
|
||||
elt = sym.sym(enam)
|
||||
if elt == nil {
|
||||
panic(fmt.Errorf(
|
||||
"gopy: could not retrieve slice-elt symbol for %q",
|
||||
enam,
|
||||
))
|
||||
elsym = sym.sym(enam)
|
||||
if elsym == nil {
|
||||
panic(fmt.Errorf("gopy: slice type must be named type if outside current package: %q", enam))
|
||||
}
|
||||
n = "[]" + elsym.goname
|
||||
}
|
||||
pyname := goToPyName(n)
|
||||
sym.syms[fn] = &symbol{
|
||||
|
@ -598,7 +665,7 @@ func (sym *symtab) addSliceType(pkg *types.Package, obj types.Object, t types.Ty
|
|||
pyname: pyname,
|
||||
cgoname: "CGoHandle",
|
||||
cpyname: PyHandle,
|
||||
pysig: "[]" + elt.pysig,
|
||||
pysig: "[]" + elsym.pysig,
|
||||
go2py: "handleFmPtr_" + pyname,
|
||||
py2go: "ptrFmHandle_" + pyname,
|
||||
zval: "nil",
|
||||
|
@ -638,7 +705,7 @@ func (sym *symtab) addStructType(pkg *types.Package, obj types.Object, t types.T
|
|||
cpyname: PyHandle,
|
||||
pysig: "object",
|
||||
go2py: "handleFmPtr_" + n,
|
||||
py2go: "ptrFmHandle_" + n,
|
||||
py2go: "*ptrFmHandle_" + n,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -666,22 +733,25 @@ func (sym *symtab) addSignatureType(pkg *types.Package, obj types.Object, t type
|
|||
}
|
||||
|
||||
func (sym *symtab) addMethod(pkg *types.Package, obj types.Object, t types.Type, kind symkind, id, n string) {
|
||||
fn := types.ObjectString(obj, nil)
|
||||
kind |= skFunc
|
||||
sym.syms[fn] = &symbol{
|
||||
gopkg: pkg,
|
||||
goobj: obj,
|
||||
gotyp: t,
|
||||
kind: kind,
|
||||
id: id,
|
||||
goname: n,
|
||||
pyname: n,
|
||||
cgoname: fn + "_" + n,
|
||||
cpyname: fn + "_" + n,
|
||||
}
|
||||
sig := t.Underlying().(*types.Signature)
|
||||
sym.processTuple(sig.Results())
|
||||
sym.processTuple(sig.Params())
|
||||
err, _, _ := isPyCompatFunc(sig)
|
||||
if err == nil {
|
||||
fn := types.ObjectString(obj, nil)
|
||||
kind |= skFunc
|
||||
sym.syms[fn] = &symbol{
|
||||
gopkg: pkg,
|
||||
goobj: obj,
|
||||
gotyp: t,
|
||||
kind: kind,
|
||||
id: id,
|
||||
goname: n,
|
||||
pyname: n,
|
||||
cgoname: fn + "_" + n,
|
||||
cpyname: fn + "_" + n,
|
||||
}
|
||||
sym.processTuple(sig.Results())
|
||||
sym.processTuple(sig.Params())
|
||||
}
|
||||
}
|
||||
|
||||
func (sym *symtab) addPointerType(pkg *types.Package, obj types.Object, t types.Type, kind symkind, id, n string) {
|
||||
|
@ -1022,7 +1092,7 @@ func init() {
|
|||
kind: skType | skBasic,
|
||||
goname: "rune",
|
||||
pyname: "str",
|
||||
cpyname: "GoRune",
|
||||
cpyname: "int32_t",
|
||||
cgoname: "C.long",
|
||||
pysig: "str",
|
||||
go2py: "C.long",
|
||||
|
|
|
@ -229,42 +229,9 @@ type Func struct {
|
|||
}
|
||||
|
||||
func newFuncFrom(p *Package, parent string, obj types.Object, sig *types.Signature) (Func, error) {
|
||||
haserr := false
|
||||
res := sig.Results()
|
||||
var ret types.Type
|
||||
|
||||
switch res.Len() {
|
||||
case 2:
|
||||
if !isErrorType(res.At(1).Type()) {
|
||||
return Func{}, fmt.Errorf(
|
||||
"bind: second result value must be of type error: %s",
|
||||
obj,
|
||||
)
|
||||
}
|
||||
haserr = true
|
||||
ret = res.At(0).Type()
|
||||
|
||||
case 1:
|
||||
if isErrorType(res.At(0).Type()) {
|
||||
haserr = true
|
||||
ret = nil
|
||||
} else {
|
||||
ret = res.At(0).Type()
|
||||
}
|
||||
case 0:
|
||||
ret = nil
|
||||
default:
|
||||
return Func{}, fmt.Errorf("bind: too many results to return: %v", obj)
|
||||
}
|
||||
|
||||
args := sig.Params()
|
||||
nargs := args.Len()
|
||||
for i := 0; i < nargs; i++ {
|
||||
arg := args.At(i)
|
||||
argt := arg.Type()
|
||||
if _, isSig := argt.(*types.Signature); isSig {
|
||||
return Func{}, fmt.Errorf("bind: func args (signature) not supported: %v", obj)
|
||||
}
|
||||
err, ret, haserr := isPyCompatFunc(sig)
|
||||
if err != nil {
|
||||
return Func{}, err
|
||||
}
|
||||
|
||||
id := obj.Pkg().Name() + "_" + obj.Name()
|
||||
|
|
276
gen/test.py
276
gen/test.py
|
@ -1,276 +0,0 @@
|
|||
# Copyright 2015 The go-python Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import hi
|
||||
|
||||
print("--- doc(hi)...")
|
||||
print(hi.__doc__)
|
||||
|
||||
print("--- hi.Universe:", hi.Universe)
|
||||
print("--- hi.Version:", hi.Version)
|
||||
|
||||
print("--- hi.Debug():",hi.Debug())
|
||||
print("--- hi.SetDebug(true)")
|
||||
hi.SetDebug(True)
|
||||
print("--- hi.Debug():",hi.Debug())
|
||||
print("--- hi.SetDebug(false)")
|
||||
hi.SetDebug(False)
|
||||
print("--- hi.Debug():",hi.Debug())
|
||||
|
||||
print("--- hi.Anon():",hi.Anon())
|
||||
anon = hi.NewPerson('you',24)
|
||||
print("--- new anon:",anon)
|
||||
print("--- hi.SetAnon(hi.NewPerson('you', 24))...")
|
||||
hi.SetAnon(anon)
|
||||
print("--- hi.Anon():",hi.Anon())
|
||||
|
||||
print("--- doc(hi.Hi)...")
|
||||
print(hi.Hi.__doc__)
|
||||
|
||||
print("--- hi.Hi()...")
|
||||
hi.Hi()
|
||||
|
||||
print("--- doc(hi.Hello)...")
|
||||
print(hi.Hello.__doc__)
|
||||
|
||||
print("--- hi.Hello('you')...")
|
||||
hi.Hello("you")
|
||||
|
||||
print("--- doc(hi.Add)...")
|
||||
print(hi.Add.__doc__)
|
||||
|
||||
print("--- hi.Add(1, 41)...")
|
||||
print(hi.Add(1,41))
|
||||
|
||||
print("--- hi.Concat('4', '2')...")
|
||||
print(hi.Concat("4","2"))
|
||||
|
||||
print("--- hi.LookupQuestion(42)...")
|
||||
print(hi.LookupQuestion(42))
|
||||
|
||||
print("--- hi.LookupQuestion(12)...")
|
||||
try:
|
||||
hi.LookupQuestion(12)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err)
|
||||
pass
|
||||
|
||||
print("--- doc(hi.Person):")
|
||||
print(hi.Person.__doc__)
|
||||
|
||||
print("--- p = hi.Person()...")
|
||||
p = hi.Person()
|
||||
print("--- p:", p)
|
||||
|
||||
print("--- p.Name:", p.Name)
|
||||
print("--- p.Age:",p.Age)
|
||||
|
||||
print("--- doc(hi.Greet):")
|
||||
print(p.Greet.__doc__)
|
||||
print("--- p.Greet()...")
|
||||
print(p.Greet())
|
||||
|
||||
print("--- p.String()...")
|
||||
print(p.String())
|
||||
|
||||
print("--- doc(p):")
|
||||
print(p.__doc__)
|
||||
|
||||
print("--- p.Name = \"foo\"...")
|
||||
p.Name = "foo"
|
||||
|
||||
print("--- p.Age = 42...")
|
||||
p.Age = 42
|
||||
|
||||
print("--- p.String()...")
|
||||
print(p.String())
|
||||
print("--- p.Age:", p.Age)
|
||||
print("--- p.Name:",p.Name)
|
||||
|
||||
print("--- p.Work(2)...")
|
||||
p.Work(2)
|
||||
|
||||
print("--- p.Work(24)...")
|
||||
try:
|
||||
p.Work(24)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err)
|
||||
pass
|
||||
|
||||
print("--- p.Salary(2):", p.Salary(2))
|
||||
try:
|
||||
print("--- p.Salary(24):",p.Salary(24))
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("--- p.Salary(24): caught:", err)
|
||||
pass
|
||||
|
||||
## test ctor args
|
||||
print("--- Person.__init__")
|
||||
try:
|
||||
hi.Person(1)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err, "| err-type:",type(err))
|
||||
pass
|
||||
|
||||
try:
|
||||
hi.Person("name","2")
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err, "| err-type:",type(err))
|
||||
pass
|
||||
|
||||
try:
|
||||
hi.Person("name",2,3)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err, "| err-type:",type(err))
|
||||
pass
|
||||
|
||||
p = hi.Person("name")
|
||||
print(p)
|
||||
p = hi.Person("name", 42)
|
||||
print(p)
|
||||
p = hi.Person(Name="name", Age=42)
|
||||
print(p)
|
||||
p = hi.Person(Age=42, Name="name")
|
||||
print(p)
|
||||
|
||||
## test ctors
|
||||
print("--- hi.NewPerson('me', 666):", hi.NewPerson("me", 666))
|
||||
print("--- hi.NewPersonWithAge(666):", hi.NewPersonWithAge(666))
|
||||
print("--- hi.NewActivePerson(4):")
|
||||
p = hi.NewActivePerson(4)
|
||||
print(p)
|
||||
|
||||
## test cross-package
|
||||
# todo: need to be able to import multiple packages
|
||||
#s2 = p.ReturnS2Ptr()
|
||||
#print("s2: ", s2)
|
||||
|
||||
## test interface
|
||||
pif = hi.PersonAsIface("me", 666)
|
||||
print("--- hi.PersonAsIface('me', 666):", pif)
|
||||
print("--- pif.GetName():", pif.GetName())
|
||||
print("--- pif.GetAge():", pif.GetAge())
|
||||
print("--- pif.SetAge(22):", pif.SetAge(22))
|
||||
print("--- pif.GetAge():", pif.GetAge())
|
||||
|
||||
# test Couple
|
||||
print("--- c = hi.Couple()...")
|
||||
c = hi.Couple()
|
||||
print(c)
|
||||
print("--- c.P1:", c.P1)
|
||||
c.P1 = hi.NewPerson("tom", 5)
|
||||
c.P2 = hi.NewPerson("bob", 2)
|
||||
print("--- c:", c)
|
||||
|
||||
print("--- c = hi.NewCouple(tom, bob)...")
|
||||
c = hi.NewCouple(hi.NewPerson("tom", 50), hi.NewPerson("bob", 41))
|
||||
print(c.String())
|
||||
c.P1.Name = "mom"
|
||||
c.P2.Age = 51
|
||||
print(c.String())
|
||||
|
||||
# test Couple.__init__
|
||||
print("--- Couple.__init__")
|
||||
#c = hi.NewCouple(hi.NewPerson("p1", 42))
|
||||
#print(c)
|
||||
c = hi.NewCouple(hi.NewPerson("p1", 42), hi.NewPerson("p2", 52))
|
||||
print(c.String())
|
||||
# note: not supporting named args -- not worth it for now!
|
||||
#c = hi.NewCouple(P1=hi.NewPerson("p1", 42), P2=hi.NewPerson("p2", 52))
|
||||
#print(c)
|
||||
#c = hi.NewCouple(P2=hi.NewPerson("p1", 42), P1=hi.NewPerson("p2", 52))
|
||||
#print(c)
|
||||
|
||||
try:
|
||||
hi.Couple(1)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err, "| err-type:",type(err))
|
||||
pass
|
||||
|
||||
try:
|
||||
hi.Couple(1,2)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err, "| err-type:",type(err))
|
||||
pass
|
||||
|
||||
try:
|
||||
hi.Couple(P2=1)
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("caught:", err, "| err-type:",type(err))
|
||||
pass
|
||||
|
||||
### test gc
|
||||
print("--- testing GC...")
|
||||
#NMAX = 100000
|
||||
NMAX = 10
|
||||
objs = []
|
||||
for i in range(NMAX):
|
||||
p1 = hi.NewPerson("p1-%d" % i, i)
|
||||
p2 = hi.NewPerson("p2-%d" % i, i)
|
||||
objs.append(hi.NewCouple(p1,p2))
|
||||
pass
|
||||
print("--- len(objs):",len(objs))
|
||||
vs = []
|
||||
for i,o in enumerate(objs):
|
||||
v = "%d: %s" % (i, o)
|
||||
vs.append(v)
|
||||
pass
|
||||
print("--- len(vs):",len(vs))
|
||||
del objs
|
||||
print("--- testing GC... [ok]")
|
||||
|
||||
print("--- testing slice...")
|
||||
s = hi.IntSlice()
|
||||
print("slice:",s)
|
||||
print("len(slice):",len(s))
|
||||
print("slice[0]:",s[0])
|
||||
print("slice[1]:",s[1])
|
||||
try:
|
||||
print("slice[2]:", s[2])
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("slice[2]: caught:",err)
|
||||
pass
|
||||
s[1] = 42
|
||||
print("slice:",s)
|
||||
print("len(slice):",len(s))
|
||||
try:
|
||||
print("mem(slice):",len(memoryview(s)))
|
||||
except Exception as err:
|
||||
print("mem(slice): caught:",err)
|
||||
pass
|
||||
|
||||
print("--- testing array...")
|
||||
arr = hi.IntArray()
|
||||
print("arr:",arr)
|
||||
print("len(arr):",len(arr))
|
||||
print("arr[0]:",arr[0])
|
||||
print("arr[1]:",arr[1])
|
||||
try:
|
||||
print("arr[2]:", arr[2])
|
||||
print("*ERROR* no exception raised!")
|
||||
except Exception as err:
|
||||
print("arr[2]: caught:",err)
|
||||
pass
|
||||
arr[1] = 42
|
||||
print("arr:",arr)
|
||||
print("len(arr):",len(arr))
|
||||
try:
|
||||
print("mem(arr):",len(memoryview(arr)))
|
||||
except Exception as err:
|
||||
print("mem(arr): caught:",err)
|
||||
pass
|
||||
|
||||
print("OK")
|
Loading…
Reference in New Issue