mirror of https://github.com/go-python/gopy.git
552 lines
13 KiB
Go
552 lines
13 KiB
Go
![]() |
// 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.
|
||
|
|
||
|
package bind
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"go/token"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
|
||
|
"golang.org/x/tools/go/types"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
cPreamble = `/*
|
||
|
C stubs for package %[1]s.
|
||
|
gopy gen -lang=python %[1]s
|
||
|
|
||
|
File is generated by gopy gen. Do not edit.
|
||
|
*/
|
||
|
|
||
|
#ifdef _POSIX_C_SOURCE
|
||
|
#undef _POSIX_C_SOURCE
|
||
|
#endif
|
||
|
|
||
|
#include "Python.h"
|
||
|
#include "structmember.h"
|
||
|
|
||
|
// header exported from 'go tool cgo'
|
||
|
#include "%[3]s.h"
|
||
|
|
||
|
`
|
||
|
)
|
||
|
|
||
|
type cpyGen struct {
|
||
|
decl *printer
|
||
|
impl *printer
|
||
|
|
||
|
fset *token.FileSet
|
||
|
pkg *Package
|
||
|
err ErrorList
|
||
|
}
|
||
|
|
||
|
type cpyFunc struct {
|
||
|
typ *types.Func
|
||
|
}
|
||
|
|
||
|
type cpyStruct struct {
|
||
|
obj *types.TypeName
|
||
|
typ *types.Struct
|
||
|
}
|
||
|
|
||
|
func (c *cpyStruct) prefix(s string) string {
|
||
|
pkgname := c.obj.Pkg().Name()
|
||
|
return pkgname + s + c.obj.Name()
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) gen() error {
|
||
|
|
||
|
g.genPreamble()
|
||
|
|
||
|
var funcs []cpyFunc
|
||
|
var structs []cpyStruct
|
||
|
|
||
|
docs := make(map[string]string)
|
||
|
|
||
|
scope := g.pkg.pkg.Scope()
|
||
|
names := scope.Names()
|
||
|
for _, name := range names {
|
||
|
obj := scope.Lookup(name)
|
||
|
if !obj.Exported() {
|
||
|
debugf("ignore %q (not exported)\n", name)
|
||
|
continue
|
||
|
}
|
||
|
debugf("processing %q...\n", name)
|
||
|
|
||
|
switch obj := obj.(type) {
|
||
|
case *types.Const:
|
||
|
// TODO(sbinet)
|
||
|
panic(fmt.Errorf("not yet supported: %v (%T)", obj, obj))
|
||
|
case *types.Var:
|
||
|
// TODO(sbinet)
|
||
|
panic(fmt.Errorf("not yet supported: %v (%T)", obj, obj))
|
||
|
|
||
|
case *types.Func:
|
||
|
funcs = append(funcs, cpyFunc{typ: obj})
|
||
|
docs[obj.Name()] = g.pkg.getDoc(obj)
|
||
|
|
||
|
case *types.TypeName:
|
||
|
named := obj.Type().(*types.Named)
|
||
|
switch typ := named.Underlying().(type) {
|
||
|
case *types.Struct:
|
||
|
structs = append(structs, cpyStruct{typ: typ, obj: obj})
|
||
|
|
||
|
case *types.Interface:
|
||
|
// TODO(sbinet)
|
||
|
panic(fmt.Errorf("not yet supported: %v (%T)", typ, obj))
|
||
|
default:
|
||
|
// TODO(sbinet)
|
||
|
panic(fmt.Errorf("not yet supported: %v (%T)", typ, obj))
|
||
|
}
|
||
|
|
||
|
default:
|
||
|
// TODO(sbinet)
|
||
|
panic(fmt.Errorf("not yet supported: %v (%T)", obj, obj))
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// first, process structs
|
||
|
for _, s := range structs {
|
||
|
g.genStruct(s)
|
||
|
}
|
||
|
|
||
|
for _, f := range funcs {
|
||
|
g.genFunc(f.typ)
|
||
|
}
|
||
|
|
||
|
g.impl.Printf("static PyMethodDef GoPy_%s_Methods[] = {\n", g.pkg.pkg.Name())
|
||
|
g.impl.Indent()
|
||
|
for _, f := range funcs {
|
||
|
name := f.typ.Name()
|
||
|
//obj := scope.Lookup(name)
|
||
|
g.impl.Printf("{%[1]q, %[2]s, METH_VARARGS, %[3]q},\n",
|
||
|
name, "gopy_"+name, docs[name],
|
||
|
)
|
||
|
}
|
||
|
g.impl.Printf("{NULL, NULL, 0, NULL} /* Sentinel */\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("};\n\n")
|
||
|
|
||
|
g.impl.Printf("PyMODINIT_FUNC\ninit%[1]s(void)\n{\n", g.pkg.pkg.Name())
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("PyObject *module = NULL;\n\n")
|
||
|
|
||
|
for _, s := range structs {
|
||
|
prefix := s.prefix("_")
|
||
|
g.impl.Printf("if (PyType_Ready(&_gopy_%sType) < 0) { return; }\n", prefix)
|
||
|
}
|
||
|
|
||
|
g.impl.Printf("module = Py_InitModule3(%[1]q, GoPy_%[1]s_Methods, %[2]q);\n\n",
|
||
|
g.pkg.pkg.Name(),
|
||
|
g.pkg.doc.Doc,
|
||
|
)
|
||
|
|
||
|
for _, s := range structs {
|
||
|
prefix := s.prefix("_")
|
||
|
|
||
|
g.impl.Printf("Py_INCREF(&_gopy_%sType);\n", prefix)
|
||
|
g.impl.Printf("PyModule_AddObject(module, %q, (PyObject*)&_gopy_%sType);\n\n",
|
||
|
s.obj.Name(), prefix,
|
||
|
)
|
||
|
}
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
|
||
|
if len(g.err) > 0 {
|
||
|
return g.err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genFunc(o *types.Func) {
|
||
|
|
||
|
g.impl.Printf(`
|
||
|
/* pythonization of: %[2]s.%[1]s */
|
||
|
static PyObject*
|
||
|
gopy_%[1]s(PyObject *self, PyObject *args) {
|
||
|
`,
|
||
|
o.Name(), g.pkg.pkg.Name(),
|
||
|
)
|
||
|
|
||
|
g.impl.Indent()
|
||
|
g.genFuncBody(o)
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genFuncBody(o *types.Func) {
|
||
|
|
||
|
funcArgs := []string{}
|
||
|
|
||
|
sig := o.Type().(*types.Signature)
|
||
|
res := newVars(sig.Results())
|
||
|
args := newVars(sig.Params())
|
||
|
for _, arg := range args {
|
||
|
arg.genDecl(g.impl)
|
||
|
funcArgs = append(funcArgs, arg.getFuncArg())
|
||
|
}
|
||
|
|
||
|
// FIXME(sbinet) pythonize (turn errors into python exceptions)
|
||
|
if len(res) > 0 {
|
||
|
switch len(res) {
|
||
|
case 1:
|
||
|
ret := res[0]
|
||
|
ret.genRetDecl(g.impl)
|
||
|
default:
|
||
|
g.impl.Printf("struct %[1]s_return c_gopy_ret;\n", o.Name())
|
||
|
/*
|
||
|
for i := 0; i < res.Len(); i++ {
|
||
|
ret := res.At(i)
|
||
|
n := ret.Name()
|
||
|
if n == "" {
|
||
|
n = "gopy_" + strconv.Itoa(i)
|
||
|
}
|
||
|
g.impl.Printf("%[1]s c_%[2]s;\n", ctypeName(ret.Type()), n)
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
}
|
||
|
|
||
|
g.impl.Printf("\n")
|
||
|
|
||
|
if len(args) > 0 {
|
||
|
g.impl.Printf("if (!PyArg_ParseTuple(args, ")
|
||
|
format := []string{}
|
||
|
pyaddrs := []string{}
|
||
|
for _, arg := range args {
|
||
|
pyfmt, addr := arg.getArgParse()
|
||
|
format = append(format, pyfmt)
|
||
|
pyaddrs = append(pyaddrs, addr)
|
||
|
}
|
||
|
g.impl.Printf("%q, %s)) {\n", strings.Join(format, ""), strings.Join(pyaddrs, ", "))
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("return NULL;\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
}
|
||
|
|
||
|
if len(args) > 0 {
|
||
|
for _, arg := range args {
|
||
|
arg.genFuncPreamble(g.impl)
|
||
|
}
|
||
|
g.impl.Printf("\n")
|
||
|
}
|
||
|
|
||
|
if len(res) > 0 {
|
||
|
g.impl.Printf("c_gopy_ret = ")
|
||
|
}
|
||
|
|
||
|
g.impl.Printf("GoPy_%[1]s(%[2]s);\n", o.Name(), strings.Join(funcArgs, ", "))
|
||
|
|
||
|
g.impl.Printf("\n")
|
||
|
|
||
|
if len(res) <= 0 {
|
||
|
g.impl.Printf("Py_INCREF(Py_None);\nreturn Py_None;\n")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
format := []string{}
|
||
|
funcArgs = []string{}
|
||
|
switch len(res) {
|
||
|
case 1:
|
||
|
ret := res[0]
|
||
|
pyfmt, _ := ret.getArgParse()
|
||
|
format = append(format, pyfmt)
|
||
|
funcArgs = append(funcArgs, "c_gopy_ret")
|
||
|
default:
|
||
|
for _, ret := range res {
|
||
|
pyfmt, _ := ret.getArgParse()
|
||
|
format = append(format, pyfmt)
|
||
|
funcArgs = append(funcArgs, ret.getFuncArg())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
g.impl.Printf("return Py_BuildValue(%q, %s);\n",
|
||
|
strings.Join(format, ""),
|
||
|
strings.Join(funcArgs, ", "),
|
||
|
)
|
||
|
//g.impl.Printf("return NULL;\n")
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genStruct(cpy cpyStruct) {
|
||
|
obj := cpy.obj
|
||
|
|
||
|
pkgname := obj.Pkg().Name()
|
||
|
prefix := cpy.prefix("_")
|
||
|
|
||
|
//fmt.Printf("obj: %#v\ntyp: %#v\n", obj, typ)
|
||
|
g.decl.Printf("/* --- decls for struct %s.%v --- */\n", pkgname, obj.Name())
|
||
|
g.decl.Printf("typedef void* GoPy_%s;\n\n", obj.Name())
|
||
|
g.decl.Printf("/* type for struct %s.%v\n", pkgname, obj.Name())
|
||
|
g.decl.Printf(" */\ntypedef struct {\n")
|
||
|
g.decl.Indent()
|
||
|
g.decl.Printf("PyObject_HEAD\n")
|
||
|
g.decl.Printf("GoPy_%[1]s cgopy; /* unsafe.Pointer to %[1]s */\n", obj.Name())
|
||
|
g.decl.Outdent()
|
||
|
g.decl.Printf("} _gopy_%s;\n", prefix)
|
||
|
g.decl.Printf("\n\n")
|
||
|
|
||
|
g.impl.Printf("/* --- impl for %s.%v */\n\n", pkgname, obj.Name())
|
||
|
|
||
|
g.genStructNew(cpy)
|
||
|
g.genStructDealloc(cpy)
|
||
|
g.genStructInit(cpy)
|
||
|
g.genStructMembers(cpy)
|
||
|
g.genStructMethods(cpy)
|
||
|
|
||
|
g.impl.Printf("static PyTypeObject _gopy_%sType = {\n", prefix)
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("PyObject_HEAD_INIT(NULL)\n")
|
||
|
g.impl.Printf("0,\t/*ob_size*/\n")
|
||
|
g.impl.Printf("\"%s.%s\",\t/*tp_name*/\n", pkgname, obj.Name())
|
||
|
g.impl.Printf("sizeof(_gopy_%s),\t/*tp_basicsize*/\n", prefix)
|
||
|
g.impl.Printf("0,\t/*tp_itemsize*/\n")
|
||
|
g.impl.Printf("(destructor)_gopy_%s_dealloc,\t/*tp_dealloc*/\n", prefix)
|
||
|
g.impl.Printf("0,\t/*tp_print*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_getattr*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_setattr*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_compare*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_repr*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_as_number*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_as_sequence*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_as_mapping*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_hash */\n")
|
||
|
g.impl.Printf("0,\t/*tp_call*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_str*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_getattro*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_setattro*/\n")
|
||
|
g.impl.Printf("0,\t/*tp_as_buffer*/\n")
|
||
|
g.impl.Printf("Py_TPFLAGS_DEFAULT,\t/*tp_flags*/\n")
|
||
|
g.impl.Printf("%q,\t/* tp_doc */\n", g.pkg.getDoc(obj))
|
||
|
g.impl.Printf("0,\t/* tp_traverse */\n")
|
||
|
g.impl.Printf("0,\t/* tp_clear */\n")
|
||
|
g.impl.Printf("0,\t/* tp_richcompare */\n")
|
||
|
g.impl.Printf("0,\t/* tp_weaklistoffset */\n")
|
||
|
g.impl.Printf("0,\t/* tp_iter */\n")
|
||
|
g.impl.Printf("0,\t/* tp_iternext */\n")
|
||
|
g.impl.Printf("_gopy_%s_methods, /* tp_methods */\n", prefix)
|
||
|
g.impl.Printf("0,\t/* tp_members */\n")
|
||
|
g.impl.Printf("_gopy_%s_getsets,\t/* tp_getset */\n", prefix)
|
||
|
g.impl.Printf("0,\t/* tp_base */\n")
|
||
|
g.impl.Printf("0,\t/* tp_dict */\n")
|
||
|
g.impl.Printf("0,\t/* tp_descr_get */\n")
|
||
|
g.impl.Printf("0,\t/* tp_descr_set */\n")
|
||
|
g.impl.Printf("0,\t/* tp_dictoffset */\n")
|
||
|
g.impl.Printf("(initproc)_gopy_%s_init, /* tp_init */\n", prefix)
|
||
|
g.impl.Printf("0, /* tp_alloc */\n")
|
||
|
g.impl.Printf("_gopy_%s_new,\t/* tp_new */\n", prefix)
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("};\n\n")
|
||
|
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genStructDealloc(cpy cpyStruct) {
|
||
|
obj := cpy.obj
|
||
|
pkgname := obj.Pkg().Name()
|
||
|
prefix := cpy.prefix("_")
|
||
|
|
||
|
g.decl.Printf("/* tp_dealloc for %s.%v */\n", pkgname, obj.Name())
|
||
|
g.decl.Printf("static void\n_gopy_%[1]s_dealloc(_gopy_%[1]s *self);\n", prefix)
|
||
|
|
||
|
g.impl.Printf("/* tp_dealloc for %s.%v */\n", pkgname, obj.Name())
|
||
|
g.impl.Printf("static void\n_gopy_%[1]s_dealloc(_gopy_%[1]s *self) {\n", prefix)
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("self->ob_type->tp_free((PyObject*)self);\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genStructNew(cpy cpyStruct) {
|
||
|
obj := cpy.obj
|
||
|
pkgname := obj.Pkg().Name()
|
||
|
prefix := cpy.prefix("_")
|
||
|
|
||
|
g.decl.Printf("/* tp_new for %s.%v */\n", pkgname, obj.Name())
|
||
|
g.decl.Printf("static PyObject*\n_gopy_%s_new(PyTypeObject *type, PyObject *args, PyObject *kwds);\n", prefix)
|
||
|
|
||
|
g.impl.Printf("/* tp_new */\n")
|
||
|
g.impl.Printf("static PyObject*\n_gopy_%s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {\n", prefix)
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("_gopy_%s *self;\n", prefix)
|
||
|
g.impl.Printf("self = (_gopy_%s *)type->tp_alloc(type, 0);\n", prefix)
|
||
|
g.impl.Printf("self->cgopy = GoPy_%s_new();\n", obj.Name())
|
||
|
g.impl.Printf("return (PyObject*)self;\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genStructInit(cpy cpyStruct) {
|
||
|
obj := cpy.obj
|
||
|
pkgname := obj.Pkg().Name()
|
||
|
prefix := cpy.prefix("_")
|
||
|
|
||
|
g.decl.Printf("/* tp_init for %s.%v */\n", pkgname, obj.Name())
|
||
|
g.decl.Printf(
|
||
|
"static int\n_gopy_%[1]s_init(_gopy_%[1]s *self, PyObject *args, PyObject *kwds);\n",
|
||
|
prefix,
|
||
|
)
|
||
|
|
||
|
g.impl.Printf("/* tp_init */\n")
|
||
|
g.impl.Printf(
|
||
|
"static int\n_gopy_%[1]s_init(_gopy_%[1]s *self, PyObject *args, PyObject *kwds) {\n",
|
||
|
prefix,
|
||
|
)
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("return 0;\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genStructMembers(cpy cpyStruct) {
|
||
|
|
||
|
obj := cpy.obj
|
||
|
pkgname := obj.Pkg().Name()
|
||
|
prefix := cpy.prefix("_")
|
||
|
|
||
|
g.decl.Printf("/* tp_getset for %s.%v */\n", pkgname, obj.Name())
|
||
|
for i := 0; i < cpy.typ.NumFields(); i++ {
|
||
|
f := cpy.typ.Field(i)
|
||
|
if !f.Exported() {
|
||
|
continue
|
||
|
}
|
||
|
ft := f.Type()
|
||
|
g.decl.Printf("static PyObject*\n")
|
||
|
g.decl.Printf(
|
||
|
"_gopy_%[1]s_getter_%[2]d(_gopy_%[1]s *self, void *closure); /* %[3]s */\n",
|
||
|
prefix,
|
||
|
i+1,
|
||
|
f.Name(),
|
||
|
)
|
||
|
|
||
|
g.impl.Printf("static PyObject*\n")
|
||
|
g.impl.Printf(
|
||
|
"_gopy_%[1]s_getter_%[2]d(_gopy_%[1]s *self, void *closure) /* %[3]s */ {\n",
|
||
|
prefix,
|
||
|
i+1,
|
||
|
f.Name(),
|
||
|
)
|
||
|
g.impl.Indent()
|
||
|
ftname := cgoTypeName(ft)
|
||
|
if needWrapType(ft) {
|
||
|
ftname = fmt.Sprintf("GoPy_%[1]s_field_%d", obj.Name(), i+1)
|
||
|
g.impl.Printf(
|
||
|
"%[1]s ret = GoPy_%[2]s_getter_%[3]d(self->cgopy);\n",
|
||
|
ftname,
|
||
|
obj.Name(),
|
||
|
i+1,
|
||
|
)
|
||
|
} else {
|
||
|
g.impl.Printf(
|
||
|
"%[1]s ret = GoPy_%[2]s_getter_%[3]d(self->cgopy);\n",
|
||
|
ftname,
|
||
|
obj.Name(),
|
||
|
i+1,
|
||
|
)
|
||
|
}
|
||
|
g.impl.Printf("Py_RETURN_NONE;\n") // FIXME(sbinet)
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
|
||
|
g.decl.Printf("static int\n")
|
||
|
g.decl.Printf(
|
||
|
"_gopy_%[1]s_setter_%[2]d(_gopy_%[1]s *self, PyObject *value, void *closure);\n",
|
||
|
prefix,
|
||
|
i+1,
|
||
|
)
|
||
|
|
||
|
g.impl.Printf("static int\n")
|
||
|
g.impl.Printf(
|
||
|
"_gopy_%[1]s_setter_%[2]d(_gopy_%[1]s *self, PyObject *value, void *closure) {\n",
|
||
|
prefix,
|
||
|
i+1,
|
||
|
)
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("return 0;\n") // FIXME(sbinet)
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("}\n\n")
|
||
|
}
|
||
|
|
||
|
g.impl.Printf("/* tp_getset for %s.%v */\n", pkgname, obj.Name())
|
||
|
g.impl.Printf("static PyGetSetDef _gopy_%s_getsets[] = {\n", prefix)
|
||
|
g.impl.Indent()
|
||
|
for i := 0; i < cpy.typ.NumFields(); i++ {
|
||
|
f := cpy.typ.Field(i)
|
||
|
if !f.Exported() {
|
||
|
continue
|
||
|
}
|
||
|
doc := "doc for " + f.Name() // FIXME(sbinet) retrieve doc for fields
|
||
|
g.impl.Printf("{%q, ", f.Name())
|
||
|
g.impl.Printf("(getter)_gopy_%[1]s_getter_%[2]d, ", prefix, i+1)
|
||
|
g.impl.Printf("(setter)_gopy_%[1]s_setter_%[2]d, ", prefix, i+1)
|
||
|
g.impl.Printf("%q, NULL},\n", doc)
|
||
|
}
|
||
|
g.impl.Printf("{NULL} /* Sentinel */\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("};\n\n")
|
||
|
/*
|
||
|
static PyGetSetDef Noddy_getseters[] = {
|
||
|
{"first",
|
||
|
(getter)Noddy_getfirst, (setter)Noddy_setfirst,
|
||
|
"first name",
|
||
|
NULL},
|
||
|
{"last",
|
||
|
(getter)Noddy_getlast, (setter)Noddy_setlast,
|
||
|
"last name",
|
||
|
NULL},
|
||
|
{NULL}
|
||
|
};
|
||
|
*/
|
||
|
/*
|
||
|
static PyObject *
|
||
|
Noddy_getfirst(Noddy *self, void *closure)
|
||
|
{
|
||
|
Py_INCREF(self->first);
|
||
|
return self->first;
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
|
||
|
{
|
||
|
if (value == NULL) {
|
||
|
PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (! PyString_Check(value)) {
|
||
|
PyErr_SetString(PyExc_TypeError,
|
||
|
"The first attribute value must be a string");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
Py_DECREF(self->first);
|
||
|
Py_INCREF(value);
|
||
|
self->first = value;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genStructMethods(cpy cpyStruct) {
|
||
|
|
||
|
prefix := cpy.prefix("_")
|
||
|
|
||
|
g.impl.Printf("static PyMethodDef _gopy_%s_methods[] = {\n", prefix)
|
||
|
g.impl.Indent()
|
||
|
g.impl.Printf("{NULL} /* sentinel */\n")
|
||
|
g.impl.Outdent()
|
||
|
g.impl.Printf("};\n\n")
|
||
|
|
||
|
}
|
||
|
|
||
|
func (g *cpyGen) genPreamble() {
|
||
|
n := g.pkg.pkg.Name()
|
||
|
g.decl.Printf(cPreamble, n, g.pkg.pkg.Path(), filepath.Base(n))
|
||
|
}
|