Skip to content

Commit 31d6377

Browse files
corona10sbinet
authored andcommitted
cffi: Implement wrapping of functions with slices/arrays of builtin arguments
1 parent 61290c1 commit 31d6377

File tree

6 files changed

+126
-0
lines changed

6 files changed

+126
-0
lines changed

_examples/arrays/arrays.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017 The go-python Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package arrays
6+
7+
func IntSum(a [4]int) int {
8+
sum := 0
9+
for i := 0; i < len(a); i++ {
10+
sum += a[i]
11+
}
12+
return sum
13+
}
14+
15+
func CreateArray() [4]int {
16+
return [4]int{1, 2, 3, 4}
17+
}

_examples/arrays/test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2017 The go-python Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style
3+
# license that can be found in the LICENSE file.
4+
5+
from __future__ import print_function
6+
import arrays
7+
8+
a = [1,2,3,4]
9+
b = arrays.CreateArray()
10+
print ("Python list:", a)
11+
print ("Go array: ", b)
12+
print ("arrays.IntSum from Python list:", arrays.IntSum(a))
13+
print ("arrays.IntSum from Go array:", arrays.IntSum(b))

_examples/slices/slices.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2017 The go-python Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package slices
6+
7+
func IntSum(s []int) int {
8+
sum := 0
9+
for _, value := range s {
10+
sum += value
11+
}
12+
return sum
13+
}
14+
15+
func CreateSlice() []int {
16+
return []int{1, 2, 3, 4}
17+
}

_examples/slices/test.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2017 The go-python Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style
3+
# license that can be found in the LICENSE file.
4+
5+
from __future__ import print_function
6+
import slices
7+
8+
a = [1,2,3,4]
9+
b = slices.CreateSlice()
10+
print ("Python list:", a)
11+
print ("Go slice: ", b)
12+
print ("slices.IntSum from Python list:", slices.IntSum(a))
13+
print ("slices.IntSum from Go slice:", slices.IntSum(b))

bind/gencffi_type.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,50 @@ func (g *cffiGen) genTypeConverter(sym *symbol) {
227227
g.wrapper.Printf("@staticmethod\n")
228228
g.wrapper.Printf("def cffi_cgopy_cnv_py2c_%[1]s(o):\n", sym.id)
229229
g.wrapper.Indent()
230+
g.wrapper.Printf("if type(o) is %[1]s:\n", typename)
231+
g.wrapper.Indent()
230232
g.wrapper.Printf("return o.cgopy\n")
231233
g.wrapper.Outdent()
234+
switch {
235+
case sym.isBasic():
236+
g.wrapper.Printf("return _cffi_helper.cffi_cgopy_cnv_py2c_%[1]s(o)\n", sym.goname)
237+
case sym.isArray():
238+
g.wrapper.Printf("if not isinstance(o, collections.Iterable):\n")
239+
g.wrapper.Indent()
240+
g.wrapper.Printf("raise TypeError('%[1]s.__init__ takes a sequence as argument')\n", sym.goname)
241+
g.wrapper.Outdent()
242+
typ := sym.GoType().Underlying().(*types.Array)
243+
esym := g.pkg.syms.symtype(typ.Elem())
244+
g.wrapper.Printf("if len(o) > %[1]d:\n", typ.Len())
245+
g.wrapper.Indent()
246+
g.wrapper.Printf("raise ValueError('%[1]s.__init__ takes a sequence of size at most %[2]d')\n",
247+
sym.goname,
248+
typ.Len(),
249+
)
250+
g.wrapper.Outdent()
251+
g.wrapper.Printf("c = _cffi_helper.lib.cgo_func_%[1]s_new()\n", sym.id)
252+
g.wrapper.Printf("for idx, elt in enumerate(o):\n")
253+
g.wrapper.Indent()
254+
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(elt)\n", esym.py2c)
255+
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_ass_item(c, idx, pyitem)\n", sym.id)
256+
g.wrapper.Outdent()
257+
g.wrapper.Printf("return c\n")
258+
case sym.isSlice():
259+
g.wrapper.Printf("if not isinstance(o, collections.Iterable):\n")
260+
g.wrapper.Indent()
261+
g.wrapper.Printf("raise TypeError('%[1]s.__init__ takes a sequence as argument')\n", sym.goname)
262+
g.wrapper.Outdent()
263+
typ := sym.GoType().Underlying().(*types.Slice)
264+
esym := g.pkg.syms.symtype(typ.Elem())
265+
g.wrapper.Printf("c = _cffi_helper.lib.cgo_func_%[1]s_new()\n", sym.id)
266+
g.wrapper.Printf("for elt in o:\n")
267+
g.wrapper.Indent()
268+
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(elt)\n", esym.py2c)
269+
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_append(c, pyitem)\n", sym.id)
270+
g.wrapper.Outdent()
271+
g.wrapper.Printf("return c\n")
272+
}
273+
g.wrapper.Outdent()
232274
g.wrapper.Printf("\n")
233275
g.wrapper.Printf("@staticmethod\n")
234276
g.wrapper.Printf("def cffi_cgopy_cnv_c2py_%[1]s(c):\n", sym.id)

main_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,3 +932,27 @@ pyerrors.Div(5, 2) = 2
932932
`),
933933
})
934934
}
935+
936+
func TestBuiltinArrays(t *testing.T) {
937+
t.Parallel()
938+
testPkgWithCFFI(t, pkg{
939+
path: "_examples/arrays",
940+
want: []byte(`Python list: [1, 2, 3, 4]
941+
Go array: [4]int{1, 2, 3, 4}
942+
arrays.IntSum from Python list: 10
943+
arrays.IntSum from Go array: 10
944+
`),
945+
})
946+
}
947+
948+
func TestBuiltinSlices(t *testing.T) {
949+
t.Parallel()
950+
testPkgWithCFFI(t, pkg{
951+
path: "_examples/slices",
952+
want: []byte(`Python list: [1, 2, 3, 4]
953+
Go slice: []int{1, 2, 3, 4}
954+
slices.IntSum from Python list: 10
955+
slices.IntSum from Go slice: 10
956+
`),
957+
})
958+
}

0 commit comments

Comments
 (0)