2017-07-13 11:03:40 +00:00
|
|
|
// 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 bind
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"go/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
// genType generates a Python class wrapping the given Go type.
|
|
|
|
func (g *cffiGen) genType(sym *symbol) {
|
|
|
|
if !sym.isType() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if sym.isStruct() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if sym.isBasic() && !sym.isNamed() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-07-18 14:41:47 +00:00
|
|
|
var typename string
|
|
|
|
|
|
|
|
if sym.isNamed() {
|
|
|
|
typename = sym.goname
|
|
|
|
} else {
|
|
|
|
typename = sym.cgoname
|
|
|
|
}
|
|
|
|
|
2017-07-13 11:03:40 +00:00
|
|
|
pkgname := g.pkg.pkg.Name()
|
|
|
|
g.wrapper.Printf(`
|
|
|
|
# Python type for %[1]s.%[2]s
|
|
|
|
class %[2]s(object):
|
|
|
|
""%[3]q""
|
|
|
|
`, pkgname,
|
2017-07-18 14:41:47 +00:00
|
|
|
typename,
|
2017-07-13 11:03:40 +00:00
|
|
|
sym.doc,
|
|
|
|
)
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.genTypeInit(sym)
|
|
|
|
g.genTypeMethod(sym)
|
2017-07-18 14:41:47 +00:00
|
|
|
g.genTypeTPRepr(sym)
|
2017-07-13 11:03:40 +00:00
|
|
|
g.genTypeTPStr(sym)
|
2017-07-18 14:41:47 +00:00
|
|
|
|
|
|
|
if sym.isPySequence() {
|
|
|
|
g.genTypeLen(sym)
|
|
|
|
g.genTypeGetItem(sym)
|
|
|
|
g.genTypeSetItem(sym)
|
|
|
|
}
|
|
|
|
|
2017-07-13 11:03:40 +00:00
|
|
|
if sym.isSlice() {
|
|
|
|
g.genTypeIAdd(sym)
|
|
|
|
}
|
2017-07-18 14:41:47 +00:00
|
|
|
|
2017-07-13 11:03:40 +00:00
|
|
|
g.wrapper.Outdent()
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeIAdd generates Type __iadd__.
|
|
|
|
func (g *cffiGen) genTypeIAdd(sym *symbol) {
|
|
|
|
g.wrapper.Printf("def __iadd__(self, value):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
switch {
|
|
|
|
case sym.isSlice():
|
|
|
|
g.wrapper.Printf("if not isinstance(value, collections.Iterable):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise TypeError('%[1]s.__iadd__ takes a iterable type as argument')\n", sym.goname)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Slice)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("for elt in value:\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(self.cgopy, pyitem)\n", sym.id)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
default:
|
|
|
|
panic(fmt.Errorf(
|
|
|
|
"gopy: __iadd__ for %s not handled",
|
|
|
|
sym.gofmt(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
g.wrapper.Printf("return self\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
2017-07-18 14:41:47 +00:00
|
|
|
// genTypeGetItem generates __getitem__ of a type.
|
|
|
|
func (g *cffiGen) genTypeGetItem(sym *symbol) {
|
|
|
|
g.wrapper.Printf("def __getitem__(self, idx):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
switch {
|
|
|
|
case sym.isArray():
|
|
|
|
g.wrapper.Printf("if idx >= len(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise IndexError('array index out of range')\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Array)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("item = _cffi_helper.lib.cgo_func_%[1]s_item(self.cgopy, idx)\n", sym.id)
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(item)\n", esym.c2py)
|
|
|
|
case sym.isSlice():
|
|
|
|
g.wrapper.Printf("if idx >= len(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise IndexError('slice index out of range')\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Slice)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("item = _cffi_helper.lib.cgo_func_%[1]s_item(self.cgopy, idx)\n", sym.id)
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(item)\n", esym.c2py)
|
2017-08-09 09:16:55 +00:00
|
|
|
case sym.isMap():
|
|
|
|
typ := sym.GoType().Underlying().(*types.Map)
|
|
|
|
ksym := g.pkg.syms.symtype(typ.Key())
|
|
|
|
vsym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("pykey = _cffi_helper.cffi_%[1]s(idx)\n", ksym.py2c)
|
|
|
|
g.wrapper.Printf("item = _cffi_helper.lib.cgo_func_%[1]s_get(self.cgopy, pykey)\n", sym.id)
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(item)\n", vsym.c2py)
|
2017-07-18 14:41:47 +00:00
|
|
|
default:
|
|
|
|
panic(fmt.Errorf(
|
|
|
|
"gopy: __getitem__ for %s not handled",
|
|
|
|
sym.gofmt(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
g.wrapper.Printf("return pyitem\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeInit generates __init__ of a type.
|
2017-07-13 11:03:40 +00:00
|
|
|
func (g *cffiGen) genTypeInit(sym *symbol) {
|
|
|
|
nargs := 1
|
|
|
|
g.wrapper.Printf("def __init__(self, *args, **kwargs):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("nkwds = len(kwargs)\n")
|
|
|
|
g.wrapper.Printf("nargs = len(args)\n")
|
|
|
|
g.wrapper.Printf("if nkwds + nargs > %[1]d:\n", nargs)
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise TypeError('%s.__init__ takes at most %d argument(s)')\n",
|
|
|
|
sym.goname,
|
|
|
|
nargs,
|
|
|
|
)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("self.cgopy = _cffi_helper.lib.cgo_func_%[1]s_new()\n", sym.id)
|
|
|
|
switch {
|
|
|
|
case sym.isBasic():
|
|
|
|
bsym := g.pkg.syms.symtype(sym.GoType().Underlying())
|
|
|
|
g.wrapper.Printf("if len(args) == 1:\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("self.cgopy = _cffi_helper.cffi_%[1]s(args[0])\n",
|
|
|
|
bsym.py2c,
|
|
|
|
)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
case sym.isArray():
|
|
|
|
g.wrapper.Printf("if args:\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("if not isinstance(args[0], collections.Sequence):\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(args[0]) > %[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("for idx, elt in enumerate(args[0]):\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(self.cgopy, idx, pyitem)\n", sym.id)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
case sym.isSlice():
|
|
|
|
g.wrapper.Printf("if args:\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("if not isinstance(args[0], 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("for elt in args[0]:\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(self.cgopy, pyitem)\n", sym.id)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
case sym.isMap():
|
2017-08-09 09:16:55 +00:00
|
|
|
g.wrapper.Printf("if args:\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("if not isinstance(args[0], collections.Mapping):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise TypeError('%[1]s.__init__ takes a mapping as argument')\n", sym.goname)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Map)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
ksym := g.pkg.syms.symtype(typ.Key())
|
|
|
|
g.wrapper.Printf("for k, v in args[0].items():\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("pykey = _cffi_helper.cffi_%[1]s(k)\n", ksym.py2c)
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(v)\n", esym.py2c)
|
|
|
|
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_set(self.cgopy, pykey, pyitem)\n", sym.id)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Outdent()
|
2017-07-13 11:03:40 +00:00
|
|
|
case sym.isSignature():
|
|
|
|
//TODO(corona10)
|
|
|
|
case sym.isInterface():
|
|
|
|
//TODO(corona10)
|
|
|
|
default:
|
|
|
|
panic(fmt.Errorf(
|
|
|
|
"gopy: init for %s not handled",
|
|
|
|
sym.gofmt(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeConverter generates a Type converter between C and Python.
|
2017-07-18 14:41:47 +00:00
|
|
|
func (g *cffiGen) genTypeLen(sym *symbol) {
|
|
|
|
g.wrapper.Printf("def __len__(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
switch {
|
|
|
|
case sym.isArray():
|
|
|
|
typ := sym.GoType().Underlying().(*types.Array)
|
|
|
|
g.wrapper.Printf("return %[1]d\n", typ.Len())
|
|
|
|
case sym.isSlice():
|
|
|
|
g.wrapper.Printf("return ffi.cast('GoSlice*', self.cgopy).len\n")
|
2017-08-09 09:16:55 +00:00
|
|
|
case sym.isMap():
|
|
|
|
g.wrapper.Printf("return _cffi_helper.lib.cgo_func_%[1]s_len(self.cgopy)\n", sym.id)
|
2017-07-18 14:41:47 +00:00
|
|
|
default:
|
|
|
|
panic(fmt.Errorf(
|
|
|
|
"gopy: len for %s not handled",
|
|
|
|
sym.gofmt(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeConverter generates Type converter between C and Python.
|
2017-07-13 11:03:40 +00:00
|
|
|
func (g *cffiGen) genTypeConverter(sym *symbol) {
|
2017-07-18 14:41:47 +00:00
|
|
|
var typename string
|
|
|
|
if sym.isNamed() {
|
|
|
|
typename = sym.goname
|
|
|
|
} else {
|
|
|
|
typename = sym.cgoname
|
|
|
|
}
|
2017-07-13 11:03:40 +00:00
|
|
|
g.wrapper.Printf("# converters for %s - %s\n", sym.id, sym.goname)
|
|
|
|
g.wrapper.Printf("@staticmethod\n")
|
|
|
|
g.wrapper.Printf("def cffi_cgopy_cnv_py2c_%[1]s(o):\n", sym.id)
|
|
|
|
g.wrapper.Indent()
|
2017-08-05 09:49:02 +00:00
|
|
|
g.wrapper.Printf("if type(o) is %[1]s:\n", typename)
|
|
|
|
g.wrapper.Indent()
|
2017-07-18 14:41:47 +00:00
|
|
|
g.wrapper.Printf("return o.cgopy\n")
|
2017-07-13 11:03:40 +00:00
|
|
|
g.wrapper.Outdent()
|
2017-08-05 09:49:02 +00:00
|
|
|
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")
|
2017-08-09 09:16:55 +00:00
|
|
|
case sym.isMap():
|
|
|
|
g.wrapper.Printf("if not isinstance(o, collections.Mapping):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise TypeError('%[1]s.__init__ takes a mapping as argument')\n", sym.goname)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Map)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
ksym := g.pkg.syms.symtype(typ.Key())
|
|
|
|
g.wrapper.Printf("c = _cffi_helper.lib.cgo_func_%[1]s_new()\n", sym.id)
|
|
|
|
g.wrapper.Printf("for k, v in o.items():\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("pykey = _cffi_helper.cffi_%[1]s(k)\n", ksym.py2c)
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(v)\n", esym.py2c)
|
|
|
|
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_set(c, pykey, pyitem)\n", sym.id)
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("return c\n")
|
2017-08-05 09:49:02 +00:00
|
|
|
}
|
|
|
|
g.wrapper.Outdent()
|
2017-07-13 11:03:40 +00:00
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
g.wrapper.Printf("@staticmethod\n")
|
|
|
|
g.wrapper.Printf("def cffi_cgopy_cnv_c2py_%[1]s(c):\n", sym.id)
|
|
|
|
g.wrapper.Indent()
|
2017-07-18 14:41:47 +00:00
|
|
|
g.wrapper.Printf("o = %[1]s()\n", typename)
|
|
|
|
g.wrapper.Printf("o.cgopy = c\n")
|
|
|
|
g.wrapper.Printf("return o\n")
|
2017-07-13 11:03:40 +00:00
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeMethod generates Type methods.
|
|
|
|
func (g *cffiGen) genTypeMethod(sym *symbol) {
|
|
|
|
g.wrapper.Printf("# methods for %s\n", sym.gofmt())
|
|
|
|
if sym.isNamed() {
|
|
|
|
typ := sym.GoType().(*types.Named)
|
|
|
|
for imeth := 0; imeth < typ.NumMethods(); imeth++ {
|
|
|
|
m := typ.Method(imeth)
|
|
|
|
if !m.Exported() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
mname := types.ObjectString(m, nil)
|
|
|
|
msym := g.pkg.syms.sym(mname)
|
|
|
|
if msym == nil {
|
|
|
|
panic(fmt.Errorf(
|
|
|
|
"gopy: could not find symbol for [%[1]T] (%#[1]v) (%[2]s)",
|
|
|
|
m.Type(),
|
|
|
|
m.Name()+" || "+m.FullName(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
g.genTypeFunc(sym, msym)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeTPStr generates Type __str__ method.
|
2017-07-18 14:41:47 +00:00
|
|
|
func (g *cffiGen) genTypeTPRepr(sym *symbol) {
|
|
|
|
g.wrapper.Printf("def __repr__(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("cret = _cffi_helper.lib.cgo_func_%[1]s_str(self.cgopy)\n", sym.id)
|
|
|
|
g.wrapper.Printf("ret = _cffi_helper.cffi_cgopy_cnv_c2py_string(cret)\n")
|
|
|
|
g.wrapper.Printf("return ret\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
// genTypeTPStr generates __str__ method of a type.
|
2017-07-13 11:03:40 +00:00
|
|
|
func (g *cffiGen) genTypeTPStr(sym *symbol) {
|
|
|
|
g.wrapper.Printf("def __str__(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("cret = _cffi_helper.lib.cgo_func_%[1]s_str(self.cgopy)\n", sym.id)
|
|
|
|
g.wrapper.Printf("ret = _cffi_helper.cffi_cgopy_cnv_c2py_string(cret)\n")
|
|
|
|
g.wrapper.Printf("return ret\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|
2017-07-18 14:41:47 +00:00
|
|
|
|
|
|
|
// genTypeSetItem generates __setitem__ of a type.
|
|
|
|
func (g *cffiGen) genTypeSetItem(sym *symbol) {
|
|
|
|
g.wrapper.Printf("def __setitem__(self, idx, item):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
switch {
|
|
|
|
case sym.isArray():
|
|
|
|
g.wrapper.Printf("if idx >= len(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise IndexError('array index out of range')\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Array)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(item)\n", esym.py2c)
|
|
|
|
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_ass_item(self.cgopy, idx, pyitem)\n", sym.id)
|
|
|
|
case sym.isSlice():
|
|
|
|
g.wrapper.Printf("if idx >= len(self):\n")
|
|
|
|
g.wrapper.Indent()
|
|
|
|
g.wrapper.Printf("raise IndexError('slice index out of range')\n")
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
typ := sym.GoType().Underlying().(*types.Slice)
|
|
|
|
esym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(item)\n", esym.py2c)
|
|
|
|
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_ass_item(self.cgopy, idx, pyitem)\n", sym.id)
|
2017-08-09 09:16:55 +00:00
|
|
|
case sym.isMap():
|
|
|
|
typ := sym.GoType().Underlying().(*types.Map)
|
|
|
|
ksym := g.pkg.syms.symtype(typ.Key())
|
|
|
|
vsym := g.pkg.syms.symtype(typ.Elem())
|
|
|
|
g.wrapper.Printf("pykey = _cffi_helper.cffi_%[1]s(idx)\n", ksym.py2c)
|
|
|
|
g.wrapper.Printf("pyitem = _cffi_helper.cffi_%[1]s(item)\n", vsym.py2c)
|
|
|
|
g.wrapper.Printf("_cffi_helper.lib.cgo_func_%[1]s_set(self.cgopy, pykey, pyitem)\n", sym.id)
|
2017-07-18 14:41:47 +00:00
|
|
|
default:
|
|
|
|
panic(fmt.Errorf(
|
|
|
|
"gopy: __setitem__ for %s not handled",
|
|
|
|
sym.gofmt(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
g.wrapper.Outdent()
|
|
|
|
g.wrapper.Printf("\n")
|
|
|
|
}
|