mirror of https://github.com/go-python/gopy.git
One test case of variadic functions now passing. More to clear.
This commit is contained in:
parent
fcad870bd8
commit
ece09eda60
|
@ -0,0 +1,15 @@
|
|||
# Copyright 2018 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.
|
||||
import variadic, go
|
||||
|
||||
varResult = variadic.VariFunc(1,2,3,4,5)
|
||||
print("Variadic 1+2+3+4+5 = %d" % varResult)
|
||||
|
||||
nonvarResult = variadic.NonVariFunc(1, go.Slice_int([2,3,4]),5)
|
||||
print("NonVariadic 1+[2+3+4]+5 = %d" % nonvarResult)
|
||||
|
||||
if isinstance(varResult, int):
|
||||
print("Type OK")
|
||||
else:
|
||||
print("Type Not OK")
|
|
@ -0,0 +1,19 @@
|
|||
package variadic
|
||||
|
||||
func VariFunc(vargs ...int) int{
|
||||
total := 0
|
||||
for _, num := range vargs {
|
||||
total += num
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
func NonVariFunc(arg1 int, arg2 []int, arg3 int) int{
|
||||
total := arg1
|
||||
for _, num := range arg2 {
|
||||
total += num
|
||||
}
|
||||
total += arg3
|
||||
|
||||
return total
|
||||
}
|
|
@ -87,18 +87,22 @@ func (g *pyGen) genFuncSig(sym *symbol, fsym *Func) bool {
|
|||
return false
|
||||
}
|
||||
anm := pySafeArg(arg.Name(), i)
|
||||
|
||||
if ifchandle && arg.sym.goname == "interface{}" {
|
||||
goArgs = append(goArgs, fmt.Sprintf("%s %s", anm, CGoHandle))
|
||||
pyArgs = append(pyArgs, fmt.Sprintf("param('%s', '%s')", PyHandle, anm))
|
||||
} else {
|
||||
goArgs = append(goArgs, fmt.Sprintf("%s %s", anm, sarg.cgoname))
|
||||
if sarg.cpyname == "PyObject*" {
|
||||
pyArgs = append(pyArgs, fmt.Sprintf("param('%s', '%s', transfer_ownership=False)", sarg.cpyname, anm))
|
||||
pyArgs = append(pyArgs, fmt.Sprintf("param('%s', '%s%s', transfer_ownership=False)", sarg.cpyname, anm))
|
||||
} else {
|
||||
pyArgs = append(pyArgs, fmt.Sprintf("param('%s', '%s')", sarg.cpyname, anm))
|
||||
}
|
||||
}
|
||||
wpArgs = append(wpArgs, anm)
|
||||
|
||||
if i!=nargs-1 || !fsym.isVariadic {
|
||||
wpArgs = append(wpArgs, anm)
|
||||
}
|
||||
}
|
||||
|
||||
// support for optional arg to run in a separate go routine -- only if no return val
|
||||
|
@ -108,6 +112,11 @@ func (g *pyGen) genFuncSig(sym *symbol, fsym *Func) bool {
|
|||
wpArgs = append(wpArgs, "goRun=False")
|
||||
}
|
||||
|
||||
// To support variadic args, we add *args at the end.
|
||||
if fsym.isVariadic {
|
||||
wpArgs = append(wpArgs, "*args")
|
||||
}
|
||||
|
||||
// When building the pybindgen builder code, we start with
|
||||
// a function that adds function calls with exception checking.
|
||||
// But given specific return types, we may want to add more
|
||||
|
@ -276,25 +285,6 @@ if __err != nil {
|
|||
g.gofile.Printf("var __err error\n")
|
||||
}
|
||||
|
||||
// pywrap output
|
||||
mnm := fsym.ID()
|
||||
if isMethod {
|
||||
mnm = sym.id + "_" + fsym.GoName()
|
||||
}
|
||||
rvHasHandle := false
|
||||
if nres > 0 {
|
||||
ret := res[0]
|
||||
if !rvIsErr && ret.sym.hasHandle() {
|
||||
rvHasHandle = true
|
||||
cvnm := ret.sym.pyPkgId(g.pkg.pkg)
|
||||
g.pywrap.Printf("return %s(handle=_%s.%s(", cvnm, pkgname, mnm)
|
||||
} else {
|
||||
g.pywrap.Printf("return _%s.%s(", pkgname, mnm)
|
||||
}
|
||||
} else {
|
||||
g.pywrap.Printf("_%s.%s(", pkgname, mnm)
|
||||
}
|
||||
|
||||
callArgs := []string{}
|
||||
wrapArgs := []string{}
|
||||
if isMethod {
|
||||
|
@ -313,6 +303,9 @@ if __err != nil {
|
|||
default:
|
||||
na = anm
|
||||
}
|
||||
if i == len(args) - 1 && fsym.isVariadic {
|
||||
na = na + "..."
|
||||
}
|
||||
callArgs = append(callArgs, na)
|
||||
switch {
|
||||
case arg.sym.goname == "interface{}":
|
||||
|
@ -326,6 +319,30 @@ if __err != nil {
|
|||
default:
|
||||
wrapArgs = append(wrapArgs, anm)
|
||||
}
|
||||
|
||||
// To support variadic args, we add *args at the end.
|
||||
if fsym.isVariadic && i == len(args)-1 {
|
||||
g.pywrap.Printf("%s = go.Slice_int(args)\n", anm)
|
||||
}
|
||||
}
|
||||
|
||||
// pywrap output
|
||||
mnm := fsym.ID()
|
||||
if isMethod {
|
||||
mnm = sym.id + "_" + fsym.GoName()
|
||||
}
|
||||
rvHasHandle := false
|
||||
if nres > 0 {
|
||||
ret := res[0]
|
||||
if !rvIsErr && ret.sym.hasHandle() {
|
||||
rvHasHandle = true
|
||||
cvnm := ret.sym.pyPkgId(g.pkg.pkg)
|
||||
g.pywrap.Printf("return %s(handle=_%s.%s(", cvnm, pkgname, mnm)
|
||||
} else {
|
||||
g.pywrap.Printf("return _%s.%s(", pkgname, mnm)
|
||||
}
|
||||
} else {
|
||||
g.pywrap.Printf("_%s.%s(", pkgname, mnm)
|
||||
}
|
||||
|
||||
hasRetCvt := false
|
||||
|
|
|
@ -153,11 +153,6 @@ func isPyCompatField(f *types.Var) (*symbol, error) {
|
|||
func isPyCompatFunc(sig *types.Signature) (ret types.Type, haserr, hasfun bool, err error) {
|
||||
res := sig.Results()
|
||||
|
||||
if sig.Variadic() {
|
||||
err = fmt.Errorf("gopy: not yet supporting variadic functions: %s", sig.String())
|
||||
return
|
||||
}
|
||||
|
||||
switch res.Len() {
|
||||
case 2:
|
||||
if !isErrorType(res.At(1).Type()) {
|
||||
|
|
|
@ -367,12 +367,13 @@ type Func struct {
|
|||
obj types.Object
|
||||
name string
|
||||
|
||||
id string
|
||||
doc string
|
||||
ret types.Type // return type, if any
|
||||
err bool // true if original go func has comma-error
|
||||
ctor bool // true if this is a newXXX function
|
||||
hasfun bool // true if this function has a function argument
|
||||
id string
|
||||
doc string
|
||||
ret types.Type // return type, if any
|
||||
err bool // true if original go func has comma-error
|
||||
ctor bool // true if this is a newXXX function
|
||||
hasfun bool // true if this function has a function argument
|
||||
isVariadic bool // True, if this is a variadic function.
|
||||
}
|
||||
|
||||
func newFuncFrom(p *Package, parent string, obj types.Object, sig *types.Signature) (*Func, error) {
|
||||
|
@ -392,16 +393,17 @@ func newFuncFrom(p *Package, parent string, obj types.Object, sig *types.Signatu
|
|||
}
|
||||
|
||||
return &Func{
|
||||
obj: obj,
|
||||
pkg: p,
|
||||
sig: sv,
|
||||
typ: obj.Type(),
|
||||
name: obj.Name(),
|
||||
id: id,
|
||||
doc: p.getDoc(parent, obj),
|
||||
ret: ret,
|
||||
err: haserr,
|
||||
hasfun: hasfun,
|
||||
obj: obj,
|
||||
pkg: p,
|
||||
sig: sv,
|
||||
typ: obj.Type(),
|
||||
name: obj.Name(),
|
||||
id: id,
|
||||
doc: p.getDoc(parent, obj),
|
||||
ret: ret,
|
||||
err: haserr,
|
||||
hasfun: hasfun,
|
||||
isVariadic: sig.Variadic(),
|
||||
}, nil
|
||||
|
||||
// TODO: could optimize by generating code once for each type of callback
|
||||
|
|
16
main_test.go
16
main_test.go
|
@ -48,6 +48,7 @@ var (
|
|||
"_examples/gopygc": []string{"py2", "py3"},
|
||||
"_examples/cstrings": []string{"py2", "py3"},
|
||||
"_examples/pkgconflict": []string{"py2", "py3"},
|
||||
"_examples/variadic": []string{"py3"},
|
||||
}
|
||||
|
||||
testEnvironment = os.Environ()
|
||||
|
@ -811,6 +812,21 @@ func TestPkgConflict(t *testing.T) {
|
|||
// })
|
||||
// }
|
||||
|
||||
func TestBindVariadic(t *testing.T) {
|
||||
// t.Parallel()
|
||||
path := "_examples/variadic"
|
||||
testPkg(t, pkg{
|
||||
path: path,
|
||||
lang: features[path],
|
||||
cmd: "build",
|
||||
extras: nil,
|
||||
want: []byte(`Variadic 1+2+3+4+5 = 15
|
||||
NonVariadic 1+[2+3+4]+5 = 15
|
||||
Type OK
|
||||
`),
|
||||
})
|
||||
}
|
||||
|
||||
// Generate / verify SUPPORT_MATRIX.md from features map.
|
||||
func TestCheckSupportMatrix(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
|
|
Loading…
Reference in New Issue