diff --git a/_examples/arrays/arrays.go b/_examples/arrays/arrays.go new file mode 100644 index 0000000..888703e --- /dev/null +++ b/_examples/arrays/arrays.go @@ -0,0 +1,17 @@ +// Copyright 2017 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. + +package arrays + +func IntSum(a [4]int) int { + sum := 0 + for i := 0; i < len(a); i++ { + sum += a[i] + } + return sum +} + +func CreateArray() [4]int { + return [4]int{1, 2, 3, 4} +} diff --git a/_examples/arrays/test.py b/_examples/arrays/test.py new file mode 100644 index 0000000..17e806b --- /dev/null +++ b/_examples/arrays/test.py @@ -0,0 +1,13 @@ +# Copyright 2017 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 arrays + +a = [1,2,3,4] +b = arrays.CreateArray() +print ("Python list:", a) +print ("Go array: ", b) +print ("arrays.IntSum from Python list:", arrays.IntSum(a)) +print ("arrays.IntSum from Go array:", arrays.IntSum(b)) diff --git a/_examples/slices/slices.go b/_examples/slices/slices.go new file mode 100644 index 0000000..9b552cf --- /dev/null +++ b/_examples/slices/slices.go @@ -0,0 +1,17 @@ +// Copyright 2017 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. + +package slices + +func IntSum(s []int) int { + sum := 0 + for _, value := range s { + sum += value + } + return sum +} + +func CreateSlice() []int { + return []int{1, 2, 3, 4} +} diff --git a/_examples/slices/test.py b/_examples/slices/test.py new file mode 100644 index 0000000..bfe2537 --- /dev/null +++ b/_examples/slices/test.py @@ -0,0 +1,13 @@ +# Copyright 2017 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 slices + +a = [1,2,3,4] +b = slices.CreateSlice() +print ("Python list:", a) +print ("Go slice: ", b) +print ("slices.IntSum from Python list:", slices.IntSum(a)) +print ("slices.IntSum from Go slice:", slices.IntSum(b)) diff --git a/bind/gencffi_type.go b/bind/gencffi_type.go index 1aacff5..0e3fff5 100644 --- a/bind/gencffi_type.go +++ b/bind/gencffi_type.go @@ -227,8 +227,50 @@ func (g *cffiGen) genTypeConverter(sym *symbol) { g.wrapper.Printf("@staticmethod\n") g.wrapper.Printf("def cffi_cgopy_cnv_py2c_%[1]s(o):\n", sym.id) g.wrapper.Indent() + g.wrapper.Printf("if type(o) is %[1]s:\n", typename) + g.wrapper.Indent() g.wrapper.Printf("return o.cgopy\n") g.wrapper.Outdent() + switch { + case sym.isBasic(): + g.wrapper.Printf("return _cffi_helper.cffi_cgopy_cnv_py2c_%[1]s(o)\n", sym.goname) + case sym.isArray(): + g.wrapper.Printf("if not isinstance(o, collections.Iterable):\n") + g.wrapper.Indent() + g.wrapper.Printf("raise TypeError('%[1]s.__init__ takes a sequence as argument')\n", sym.goname) + g.wrapper.Outdent() + typ := sym.GoType().Underlying().(*types.Array) + esym := g.pkg.syms.symtype(typ.Elem()) + g.wrapper.Printf("if len(o) > %[1]d:\n", typ.Len()) + g.wrapper.Indent() + g.wrapper.Printf("raise ValueError('%[1]s.__init__ takes a sequence of size at most %[2]d')\n", + sym.goname, + typ.Len(), + ) + g.wrapper.Outdent() + g.wrapper.Printf("c = _cffi_helper.lib.cgo_func_%[1]s_new()\n", sym.id) + g.wrapper.Printf("for idx, elt in enumerate(o):\n") + g.wrapper.Indent() + g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(elt)\n", esym.py2c) + g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_ass_item(c, idx, pyitem)\n", sym.id) + g.wrapper.Outdent() + g.wrapper.Printf("return c\n") + case sym.isSlice(): + g.wrapper.Printf("if not isinstance(o, collections.Iterable):\n") + g.wrapper.Indent() + g.wrapper.Printf("raise TypeError('%[1]s.__init__ takes a sequence as argument')\n", sym.goname) + g.wrapper.Outdent() + typ := sym.GoType().Underlying().(*types.Slice) + esym := g.pkg.syms.symtype(typ.Elem()) + g.wrapper.Printf("c = _cffi_helper.lib.cgo_func_%[1]s_new()\n", sym.id) + g.wrapper.Printf("for elt in o:\n") + g.wrapper.Indent() + g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(elt)\n", esym.py2c) + g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_append(c, pyitem)\n", sym.id) + g.wrapper.Outdent() + g.wrapper.Printf("return c\n") + } + g.wrapper.Outdent() g.wrapper.Printf("\n") g.wrapper.Printf("@staticmethod\n") g.wrapper.Printf("def cffi_cgopy_cnv_c2py_%[1]s(c):\n", sym.id) diff --git a/main_test.go b/main_test.go index cb5817a..0ca12dd 100644 --- a/main_test.go +++ b/main_test.go @@ -932,3 +932,27 @@ pyerrors.Div(5, 2) = 2 `), }) } + +func TestBuiltinArrays(t *testing.T) { + t.Parallel() + testPkgWithCFFI(t, pkg{ + path: "_examples/arrays", + want: []byte(`Python list: [1, 2, 3, 4] +Go array: [4]int{1, 2, 3, 4} +arrays.IntSum from Python list: 10 +arrays.IntSum from Go array: 10 +`), + }) +} + +func TestBuiltinSlices(t *testing.T) { + t.Parallel() + testPkgWithCFFI(t, pkg{ + path: "_examples/slices", + want: []byte(`Python list: [1, 2, 3, 4] +Go slice: []int{1, 2, 3, 4} +slices.IntSum from Python list: 10 +slices.IntSum from Go slice: 10 +`), + }) +}