major progress -- handling most things in emer now except emer itself..

This commit is contained in:
Randall C. O'Reilly 2019-02-19 02:46:15 -07:00 committed by Sebastien Binet
parent 3c4cffd8dd
commit 849847c8d4
9 changed files with 233 additions and 459 deletions

View File

@ -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()

View File

@ -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")
}

View File

@ -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())

View File

@ -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")
}

View File

@ -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)

View File

@ -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
}

View File

@ -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",

View File

@ -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()

View File

@ -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")