Giter Club home page Giter Club logo

gopy's Introduction

gopy

GoDoc CI Build status

gopy generates (and compiles) a CPython extension module from a go package.

This is an improved version that works with current versions of Go (e.g., 1.15 -- should work with any future version going forward), and uses unique int64 handles to interface with python, so that no pointers are interchanged, making everything safe for the more recent moving garbage collector.

It also supports python modules having any number of Go packages, and generates a separate .py module file for each package, which link into a single common binding library. It has been tested extensively on reproducing complex Go code in large libraries -- most stuff "just works". For example, the GoGi GUI library is fully usable from python now (do make; make install in the python directory there, and try the examples/widgets/widgets.py demo).

New features:

  • Callback methods from Go into Python now work: you can pass a python function to a Go function that has a function argument, and it will call the python function appropriately.
  • The first embedded struct field (i.e., Go's version of type inheritance) is used to establish a corresponding class inheritance in the Python class wrappers, which then efficiently inherit all the methods, properties, etc.

Installation

Gopy now assumes that you are working with modules-based builds, and requires a valid go.mod file, and works only with Go versions 1.15 and above.

Currently using pybindgen to generate the low-level c-to-python bindings, but support for cffi should be relatively straightforward for those using PyPy instead of CPython (pybindgen should be significantly faster for CPython apparently). You also need goimports to ensure the correct imports are included.

$ python3 -m pip install pybindgen
$ go install golang.org/x/tools/cmd/goimports@latest
$ go install github.com/go-python/gopy@latest

(This all assumes you have already installed Go itself, and added ~/go/bin to your PATH).

To install python modules, you will need the python install packages:

python3 -m pip install --upgrade setuptools wheel

IMPORTANT: many errors will be avoided by specifying the -vm option to gopy, with a full path if needed, or typically just -vm=python3 to use python3 instead of version 2, which is often the default for the plain python command.

Linux

On linux, you may need to ensure that the linker ld will look in the current directory for library files -- add this to your .bashrc file (and source that file after editing, or enter command locally):

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

Windows

As of version 0.4.0, windows is now better supported, and is passing tests (on at least one developers machine). You may still need to set some environment variables depending on your python installation, but a vanilla standard install is working.

Install Python from the main Python distribution: https://www.python.org/downloads/windows/ -- do not install from the Microsoft Store app! -- while that is very convenient, it creates symbolic links to access the python executables, which is incompatible with go exec.Command to run it, despite too many hours of trying to get around that.

The standard python install does not create a python3.exe which gopy looks for -- follow instructions here: https://stackoverflow.com/questions/39910730/python3-is-not-recognized-as-an-internal-or-external-command-operable-program/41492852 (just make a copy of python.exe to python3.exe in the relevant installed location).

If you get a bunch of errors during linking in the build process, set LIBDIR or GOPY_LIBDIR to path to python libraries, and LIBRARY or GOPY_PYLIB to name of python library (e.g., python39 for 3.9).

Community

See the CONTRIBUTING guide for pointers on how to contribute to gopy.

Documentation

A presentation was given at dotgo-2015. A longer version of that talk is also available here. An article was also posted on the GopherAcademy Advent-2015.

Documentation is available on godoc: https://godoc.org/github.com/go-python/gopy

The pkg and exe commands are for end-users and create a full standalone python package that can be installed locally using make install based on the auto-generated Makefile. Theoretically these packages could be uploaded to https://pypi.org/ for wider distribution, but that would require a lot more work to handle all the different possible python versions and coordination with the Go source version, so it is easier to just do the local make install on your system. The gen and build commands are used for testing and just generate / build the raw binding files only.

IMPORTANT: many errors will be avoided by specifying the -vm option to gopy, with a full path if needed, or typically just -vm=python3 to use python3 instead of version 2, which is often the default for the plain python command.

Here are some (slightly enhanced) docs from the help command:

$ gopy help
gopy - 

Commands:

    pkg         generate and compile Python bindings for Go, automatically including subdirs
                    also creates all the python files needed to install module
    exe         like pkg but makes a standalone executable with Go packages bultin
                    this is particularly useful when using -main arg to start process on
    gen         generate (C)Python language bindings for Go
    build       generate and compile 
                    main thread -- python interpreter can run on another thread.

Use "gopy help <command>" for more information about a command.


$ gopy help pkg
Usage: gopy pkg <go-package-name> [other-go-package...]

pkg generates and compiles (C)Python language bindings for a Go package, including subdirectories, and generates python module packaging suitable for distribution.  if setup.py file does not yet exist in the target directory, then it is created along with other default packaging files, using arguments.  Typically you create initial default versions of these files and then edit them, and after that, only regenerate the Go binding files.

ex:
 $ gopy pkg [options] <go-package-name> [other-go-package...]
 $ gopy pkg github.com/go-python/gopy/_examples/hi

Options:
  -author="gopy": author name
  -desc="": short description of project (long comes from README.md)
  -email="[email protected]": author email
  -exclude="": comma-separated list of package names to exclude
  -main="": code string to run in the Go GoPyInit() function in the cgo library
  -name="": name of output package (otherwise name of first package is used)
  -output="": output directory for root of package
  -symbols=true: include symbols in output
  -url="https://github.com/go-python/gopy": home page for project
  -user="": username on https://www.pypa.io/en/latest/ for package name suffix
  -version="0.1.0": semantic version number -- can use e.g., git to get this from tag and pass as argument
  -vm="python": path to python interpreter
  -dynamic-link=false: whether to link output shared library dynamically to Python
  -build-tags="": build tags to be passed to `go build`


$ gopy help exe
Usage: gopy exe <go-package-name> [other-go-package...]

exe generates and compiles (C)Python language bindings for a Go package, including subdirectories, and generates a standalone python executable and associated module packaging suitable for distribution.  if setup.py file does not yet exist in the target directory, then it along with other default packaging files are created, using arguments.  Typically you create initial default versions of these files and then edit them, and after that, only regenerate the Go binding files.

The primary need for an exe instead of a pkg dynamic library is when the main thread must be used for something other than running the python interpreter, such as for a GUI library where the main thread must be used for running the GUI event loop (e.g., GoGi).

ex:
 $ gopy exe [options] <go-package-name> [other-go-package...]
 $ gopy exe github.com/go-python/gopy/_examples/hi

Options:
  -author="gopy": author name
  -desc="": short description of project (long comes from README.md)
  -email="[email protected]": author email
  -exclude="": comma-separated list of package names to exclude
  -main="": code string to run in the Go main() function in the cgo library -- defaults to GoPyMainRun() but typically should be overriden
  -name="": name of output package (otherwise name of first package is used)
  -output="": output directory for root of package
  -symbols=true: include symbols in output
  -url="https://github.com/go-python/gopy": home page for project
  -user="": username on https://www.pypa.io/en/latest/ for package name suffix
  -version="0.1.0": semantic version number -- can use e.g., git to get this from tag and pass as argument
  -vm="python": path to python interpreter
  -dynamic-link=false: whether to link output shared library dynamically to Python
  -build-tags="": build tags to be passed to `go build`

$ gopy help gen
Usage: gopy gen <go-package-name> [other-go-package...]

gen generates (C)Python language bindings for Go package(s).

ex:
 $ gopy gen [options] <go-package-name> [other-go-package...]
 $ gopy gen github.com/go-python/gopy/_examples/hi

Options:
  -build-tags="": build tags to be passed to `go build`
  -dynamic-link=false: whether to link output shared library dynamically to Python
  -main="": code string to run in the go main() function in the cgo library
  -name="": name of output package (otherwise name of first package is used)
  -no-make=false: do not generate a Makefile, e.g., when called from Makefile
  -no-warn=false: suppress warning messages, which may be expected
  -output="": output directory for bindings
  -package-prefix=".": custom package prefix used when generating import statements for generated package
  -rename=false: rename Go symbols to python PEP snake_case
  -vm="python": path to python interpreter

$ gopy help build
Usage: gopy build <go-package-name> [other-go-package...]

build generates and compiles (C)Python language bindings for Go package(s).

ex:
 $ gopy build [options] <go-package-name> [other-go-package...]
 $ gopy build github.com/go-python/gopy/_examples/hi

Options:
  -build-tags="": build tags to be passed to `go build`
  -dynamic-link=false: whether to link output shared library dynamically to Python
  -main="": code string to run in the go main() function in the cgo library
  -name="": name of output package (otherwise name of first package is used)
  -no-make=false: do not generate a Makefile, e.g., when called from Makefile
  -no-warn=false: suppress warning messages, which may be expected
  -output="": output directory for bindings
  -package-prefix=".": custom package prefix used when generating import statements for generated package
  -rename=false: rename Go symbols to python PEP snake_case
  -symbols=true: include symbols in output
  -vm="python": path to python interpreter

Examples

From the command line

Note: you now need to make a go.mod file if you don't already have one in your environment, and get the package before building:

$ go mod init dummy.com/dum
$ go get github.com/go-python/gopy/_examples/hi
$ gopy build -output=out -vm=python3 github.com/go-python/gopy/_examples/hi
$ ls out
Makefile  __init__.py  __pycache__/  _hi.so*  build.py  go.py  hi.c  hi.go  hi.py  hi_go.h  hi_go.so
$ cd out
$ python3
>>> from out import hi
>>> dir(hi)
['Add', 'Concat', 'Hello', 'Hi', 'NewPerson', 'Person', '__doc__', '__file__', '__name__', '__package__']

>>> hi.Hello("you")
hello you from go

You can also run:

go test -v -run=TestHi
...

From the python shell (NOT YET WORKING)

NOTE: following not yet working in new version:

gopy comes with a little python module allowing to wrap and compile go packages directly from the python interactive shell:

>>> import gopy
>>> hi = gopy.load("github.com/go-python/gopy/_examples/hi")
gopy> inferring package name...
gopy> loading 'github.com/go-python/gopy/_examples/hi'...
gopy> importing 'github.com/go-python/gopy/_examples/hi'

>>> print hi
<module 'github.com/go-python/gopy/_examples/hi' from '/some/path/.../hi.so'>

>>> print hi.__doc__
package hi exposes a few Go functions to be wrapped and used from Python.

Binding generation using Docker (for cross-platform builds)

$ cd github.com/go-python/gopy/_examples/hi
$ docker run --rm -v `pwd`:/go/src/in -v `pwd`:/out gopy/gopy app bind -output=/out in
$ file hi.so
hi.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped

The docker image can also be built on local machine:

$ cd $GOPATH/src/github.com/go-python/gopy
$ docker build -t go-python/gopy .
$ docker run -it --rm go-python/gopy

Support Matrix

To know what features are supported on what backends, please refer to the Support matrix .

setup.py

Here's an example for how to use setup.py with gopy to make an installable package: https://github.com/raptor-ml/raptor/blob/master/labsdk/setup.py

Also, see this for cross-platform build: https://github.com/raptor-ml/raptor/blob/master/.github/workflows/labsdk-release.yaml

Troubleshooting

python version mismatches

Many errors will be avoided by specifying the -vm option to gopy, with a full path if needed, or typically just -vm=python3 to use python3 instead of version 2, which is often the default for the plain python command.

If you get any kind of error about the library module not being able to be imported, or apparently a large number of other random-looking errors, a mismatch between the python version used for compiling vs. what you are using to run is the most likely explanation.

If you get an error like this after importing a generated module:

Fatal Python error: _PyInterpreterState_Get(): no current thread state

it means you are running a different version of python than the one that build the library you are importing -- make sure you've got the paths in your -vm arg aligned with what you are using to import.

linux: cannot find .so file

If your import statement fails to find the module .so file, and it is in the current directory, you may need to ensure that the linker ld will look in the current directory for library files -- add this to your .bashrc file (and source that file after editing, or enter command locally):

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

you may also need to add your python path, but that is less likely to be an issue.

Contribute

gopy is part of the go-python organization and licensed under BSD-3. When you want to contribute a patch or some code to gopy, please send a pull request against the gopy issue tracker AND a pull request against go-python/license adding yourself to the AUTHORS and CONTRIBUTORS files.

gopy's People

Contributors

buinvest avatar corona10 avatar cosnicolaou avatar evanoman avatar foxever avatar inotart avatar jorropo avatar juicestus avatar justinfx avatar keithcat1 avatar kellrott avatar kevjumba avatar kjahed avatar lhartung avatar mlange-42 avatar nishant-rudderstack avatar noamk-cr avatar ondra avatar psha- avatar pyalex avatar rameshg87 avatar rcoreilly avatar richecr avatar sbinet avatar soren-n avatar testwill avatar theodoree avatar tomoris avatar vmarkovtsev avatar xlab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gopy's Issues

bind: wrap go.func values

right now, this fails:

package funcs

type Func func()

type S1 struct {
    F Func
}

type S2 struct {
    F func()
}

like so:

sh> gopy bind ./_examples/funcs
2015/08/07 09:07:03 work: /home/binet/dev/go/root/tmp/gopy-798639975
github.com/go-python/gopy/_examples/funcs
_/home/binet/dev/go/root/tmp/gopy-798639975
# _/home/binet/dev/go/root/tmp/gopy-798639975
./funcs.go:161: cannot use ret.F (type funcs.Func) as type cgo_type_0x2908729187 in return argument
./funcs.go:166: cannot use v (type cgo_type_0x2908729187) as type funcs.Func in assignment
./funcs.go:191: cannot use ret.F (type func()) as type cgo_type_0x2173681852 in return argument
./funcs.go:196: cannot use v (type cgo_type_0x2173681852) as type func() in assignment
2015/08/07 09:07:04 error dispatching command: exit status 2

bind: refactor codegen

refactor codegen.

  • introduce bind.Struct to collect all methods + ctor-funcs related to a go.Struct
  • introduce bind.Func for all go.Funcs (but the ctor-funcs)
  • introduce bind.Type to tie the 2?
  • introduce bind.Convert to handle (codegen) conversion b/w types?
  • lift all go.values to pointers so handling is easier in the cgo-code?
  • introduce bind.Block to model a basic block/scope
  • attach DeclVar(name, type), Call(recv,args), Return{Results []Value} functions and types to operate on a bind.Block
type Block struct {
 blocks []*Block // sub-blocks
 instrs []Instruction
}

// Instruction is a statement that consumes values and performs a computation.
type Instruction interface {
  Operands(rands []*Value) []*Value
}

// Value is an expression that yields a value
type Value interface {
  Name() string
  Type() types.Type
}

type DeclVar struct {
  n string
  t types.Type
}

type Call struct {
  recv Value
  args []*Value 
}

// ...

another possibility is to build a full AST as Cython does (here)
(need some more design legwork)

support for kwargs calls

gopy should perhaps generate code with support for kwargs.

consider:

package pkg
func Hello(arg1, arg2 string) string {...}

should be callable from python like so:

import pkg
pkg.Hello("1","2")
pkg.Hello(arg1="1", arg2="2")

gopy bind performances

on my desktop, generating+binding the C-extention module takes:

sh> time gopy bind github.com/go-python/gopy/_examples/simple
2015/08/06 17:55:13 work: /home/binet/dev/go/root/tmp/gopy-129374957
runtime
sync/atomic
errors
math
unicode/utf8
github.com/go-python/gopy/_examples/simple
sync
io
syscall
strconv
time
reflect
os
fmt
runtime/cgo
_/home/binet/dev/go/root/tmp/gopy-129374957

real    0m5.098s
user    0m8.107s
sys 0m0.707s

the current breakdown is:

sh> time gopy gen -lang=go github.com/go-python/gopy/_examples/simple

real    0m0.076s
user    0m0.047s
sys 0m0.017s

sh> time gopy gen -lang=py2 github.com/go-python/gopy/_examples/simple

real    0m0.004s
user    0m0.003s
sys 0m0.000s

sh> time go build -v -buildmode=c-shared -o simple.so .
runtime
errors
sync/atomic
math
github.com/go-python/gopy/_examples/simple
unicode/utf8
sync
io
syscall
strconv
time
reflect
os
fmt
runtime/cgo
github.com/go-python/gopy/tbench

real    0m5.035s
user    0m8.220s
sys 0m0.640s

we should investigate where one could optimize...

[build failed] too many errors

$ go get github.com/go-python/gopy
# github.com/go-python/gopy/bind
/usr/src/go/src/github.com/go-python/gopy/bind/gencpy_struct.go:386: cannot use m (type *types.Func) as type *types.Package in argument to types.ObjectString
/usr/src/go/src/github.com/go-python/gopy/bind/gencpy_type.go:363: cannot use m (type *types.Func) as type *types.Package in argument to types.ObjectString
/usr/src/go/src/github.com/go-python/gopy/bind/gencpy_type.go:385: cannot use m (type *types.Func) as type *types.Package in argument to types.ObjectString
/usr/src/go/src/github.com/go-python/gopy/bind/gengo.go:245: cannot use arg.GoType() (type types.Type) as type *types.Package in argument to types.TypeString
/usr/src/go/src/github.com/go-python/gopy/bind/gengo.go:246: cannot use func literal (type func(*types.Package) string) as type types.Type in argument to types.TypeString:
    func(*types.Package) string does not implement types.Type (missing String method)
/usr/src/go/src/github.com/go-python/gopy/bind/gengo.go:791: cannot use m (type *types.Func) as type *types.Package in argument to types.ObjectString
/usr/src/go/src/github.com/go-python/gopy/bind/package.go:288: cannot use m (type *types.Func) as type *types.Package in argument to types.ObjectString
/usr/src/go/src/github.com/go-python/gopy/bind/symtab.go:173: cannot use s.GoType() (type types.Type) as type *types.Package in argument to types.TypeString
/usr/src/go/src/github.com/go-python/gopy/bind/symtab.go:174: cannot use func literal (type func(*types.Package) string) as type types.Type in argument to types.TypeString:
    func(*types.Package) string does not implement types.Type (missing String method)
/usr/src/go/src/github.com/go-python/gopy/bind/symtab.go:263: cannot use t (type types.Type) as type *types.Package in argument to types.TypeString
/usr/src/go/src/github.com/go-python/gopy/bind/symtab.go:263: too many errors


$ go version
go version go1.5 darwin/amd64

$ uname -a
Darwin gotlium.local 13.4.0 Darwin Kernel Version 13.4.0: Wed Mar 18 16:20:14 PDT 2015; root:xnu-2422.115.14~1/RELEASE_X86_64 x86_64

bind: decide on handling of builtins

right now, builtin types (float32, int, ...) are passed by value between go, cgo and cpython.

it worked ok so far, until we try to handle named types of these builtins.
e.g.:

type Float float32
func (f Float) Value() float32 { return float32(f) }

we could still handle them by value if it were not for the possibility (on the Go side) to attach methods to them, so, on the python side, we'd need a proper cpy_type_mypkg_FloatType with the equivalent methods)
(note: we could still have that but wrap the Float by value. but what about ref-counting?)

the most regular (and less surprising) option is to:

  • pass them by pointer
  • inject cgo_incref calls
  • create a cpy_type_mypkg_Float cpython type
  • implement the tp_as_number protocol (when sensible)

bind: unify struct and named-types handling

right now, the codegen path for types.Struct and types.Named is different.
but the only difference (IIRC) is that types.Struct may have fields (which we need to wrap via getters and setters.)

os.File, io.Reader and io.Writer pythonizations

structs containing *os.File or functions/methods returning *os.File (or equivalent interface) should expose a python object appearing as file-like and implementing the context protocol.
ditto for io.Reader and io.Writer.

gen: refactor gencpy code for py2/py3

eventually, gopy should support generation of python C-extensions for both CPython2 and CPython3 APIs.

sh> gopy gen -lang=py2|python2 my/pkg
sh> gopy gen -lang=py3|python3 my/pkg

this should also be available from the gopy bind command.

bind: support for embedding

The package

package inheritance

type A struct {
}

func (a A) Method() {
}

type B struct {
    A
}

fails with

$ go build && gopy bind --lang=py2 . && python test.py 
2015/08/31 13:54:17 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-602654280
# _/private/var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-602654280
./inheritance.c:482:26: error: use of undeclared identifier 'cpy_func_inheritance_B_Method'
2015/08/31 13:54:18 error dispatching command: exit status 2

Similarly,

package inheritance

type A struct {
    AField int
}

type B struct {
    A
}

will successfully bind, but the python code

from inheritance import *

b = B()
print b.AField

fails with the expected attribute error:

$ go build && gopy bind --lang=py2 . && python test.py 
2015/08/31 13:52:52 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-277918738
Meow
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    print b.AField
AttributeError: 'inheritance.B' object has no attribute 'AField'

bind: collect arrays and slices into type factory functions

right now, slices and arrays defined like so from go:

package hi
var (
 Array [2]int
 Slice []int
)

appear like so on python:

>>> import gopy
>>> hi = gopy.load("some/path/hi")
>>> dir(hi)
['GetArray', 'SetArray', 'GetSlice', 'SetSlice', '[2]int', '[]int']

one should collect the type(s) [X]int under a module-level function available like so:

# module hi
def array(size, type):
  return _go_array_types[(size,type)]

and useable like so:

import hi
arr = hi.array(2, int)()

instead of like so:

import hi
arr = getattr(hi, '[2]int')() 

ditto for slices.

bind: support for empty structs

right now, wrapping:

package structs

type S struct {}

results in:

./structs.c: In function โ€˜cpy_func_structs_S_initโ€™:
./structs.c:1152:60: error: expected expression before โ€˜)โ€™ token
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|", kwlist, )) {

bind: support for private methods

The package

package private_method

type T int

func (t T) PublicMethod() {
}

func (t T) privateMethod() {
}

fails with

$ gopy bind --lang=py2 .
2015/08/31 10:19:12 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-501072551
panic: gopy: could not find symbol for [*types.Signature] (&types.Signature{scope:(*types.Scope)(0x82067e410), recv:(*types.Var)(0x82067e460), params:(*types.Tuple)(nil), results:(*types.Tuple)(nil), variadic:false}) (privateMethod || (scratch/pytest/private_method.T).privateMethod)

goroutine 1 [running]:
github.com/go-python/gopy/bind.(*goGen).genTypeMethods(0x8206a35a8, 0x820677960)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/gengo.go:798 +0x44f
github.com/go-python/gopy/bind.(*goGen).genType(0x8206a35a8, 0x820677960)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/gengo.go:665 +0x2010
github.com/go-python/gopy/bind.(*goGen).gen(0x8206a35a8, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/gengo.go:153 +0x85c
github.com/go-python/gopy/bind.GenGo(0x88207a8140, 0x820648150, 0x82064c3c0, 0x82065efa0, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/bind.go:64 +0x194
main.genPkg(0x82064d140, 0x3f, 0x82065efa0, 0x39ae08, 0x2, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:65 +0x43a
main.gopyRunCmdBind(0x8206367e0, 0x8205c0370, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/cmd_bind.go:113 +0xd93
github.com/gonuts/commander.(*Command).Dispatch(0x8206367e0, 0x8205c0370, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:221 +0x7e2
github.com/gonuts/commander.(*Command).Dispatch(0x820636900, 0x8205c0350, 0x3, 0x3, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:187 +0x1f9
main.main()
    /Users/phil/code/go/src/github.com/go-python/gopy/main.go:38 +0x1fe```

distribution difference: python2.pc vs. python2.7.pc

Testing on an Amazon Linux development instance, I noticed it puts Python 2.7's package configuration in python2.7.pc, whereas Ubuntu calls it python2.pc. I was able to bind the hi example just by changing the python2 in gengo.go to python2.7. I'm guessing Amazon Linux inherits this quirk from its more-widely-used upstreams (CentOS/RHEL), but haven't checked that.

gopy could test for the existence of /usr/lib64/python2.7.pc or /usr/lib/python2.7.pc, and, if one of those is present, put python2.7 instead of python2 in the #cgo pkg-config line in the generated go file.

(It might help some new users if gopy suggested how to install Python headers and pkg-config if they appeared to be missing after a failed build. Some gopy users may be building their first extension.)

gopy: import+reimport same package crashes interpreter

with python-2.7:

>>> import gopy
>>> hi = gopy.load("github.com/go-python/gopy/_examples/hi")
[...]
>>> print hi
<module 'gopy.hi' from '/home/binet/dev/go/root/path/src/github.com/go-python/gopy/hi.so'>

>>> hi.Hello("you")
hello you from go

>>> hi = gopy.load("github.com/go-python/gopy/_examples/hi")
[...]
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff43ca4c0 in runtime.sigtrampgo (sig=17, info=0x7fffffffd3f0, ctx=0x7fffffffd2c0) at /home/binet/dev/go/root/go/src/runtime/signal_linux.go:93
93      setg(g.m.gsignal)
(gdb) bt
#0  0x00007ffff43ca4c0 in runtime.sigtrampgo (sig=17, info=0x7fffffffd3f0, ctx=0x7fffffffd2c0) at /home/binet/dev/go/root/go/src/runtime/signal_linux.go:93
#1  0x00007ffff43e853b in runtime.sigtramp () at /home/binet/dev/go/root/go/src/runtime/sys_linux_amd64.s:234
#2  0x00007ffff43e8540 in runtime.sigtramp () at /home/binet/dev/go/root/go/src/runtime/sys_linux_amd64.s:235
#3  0x0000000000000001 in ?? ()
#4  0x0000000000000000 in ?? ()

gopy: support for empty packages

right now, attempting to wrap an empty package, results in:

sh> gopy bind ./_examples/empty
./empty.go:18: imported and not used: "github.com/go-python/gopy/_examples/empty"

we should support this (as importing empty packages may be needed for their side-effects)

bind: support slices as method arguments

The package

package slice_arg

type T struct {
}

func (t T) Slice(s []float64) {
}

fails with

$ go build && gopy bind --lang=py2 .
2015/08/31 10:29:15 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-628775343
# _/private/var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-628775343
./slice_arg.go:164: cannot use s (type cgo_type_0x1114782197) as type []float64 in argument to (*slice_arg.T)(unsafe.Pointer(self)).Slice
2015/08/31 10:29:15 error dispatching command: exit status 2

The following two packages both successfully compile:

package slice_arg

type T struct {
}

func Slice(t T, s []float64) {
}
package slice_arg

type T struct {
}

func (t T) Slice(x float64) {                                            
}

go.structs with multiple constructors

gopy should generate the proper dispatch code for structs with multiple constructor functions

it's actually a bit more complicated than that.
consider:

type S struct {i int}
func NewS1() S { return S{i:1} }
func NewS2() S { return S{i:2} }

there is no way to distinguish between the 2 at the python level.

better just expose the ctors at the py-module level?

or attach them at the class-level like so?

class S(object):
  @staticmethod
  def NewS1(): ...

  @staticmethod
  def NewS2(): ...

(but then, collisions may happen)

support for slices and arrays

go.slices and go.arrays should be wrapped and their python counterpart should implement the sequence protocol.
slices and arrays should probably also implement the buffer protocol.

bind: support for (unexported) typed consts, vars and funcs

right now:

package consts
type kind int
const (
  Kind kind = 0
)

results in:

sh> gopy bind ./_examples/consts
./consts.go:144: cannot refer to unexported name consts.kind
./consts.go:150: cannot refer to unexported name consts.kind

ditto for (exported) vars of unexported type and (exported) funcs returning values of unexported types.

bind: support for go.interfaces

right now, the following package:

package iface

type Iface interface {
    F()
}

fails with:

sh> gopy bind ./_examples/iface
panic: unhandled named-type: [*types.TypeName]
&types.Named{obj:(*types.TypeName)(0xc8200b84b0), underlying:(*types.Interface)(0xc8200b8500), methods:[]*types.Func(nil)}


goroutine 1 [running]:
github.com/go-python/gopy/bind.(*symtab).addType(0xc820011400, 0x7f3629be9348, 0xc8200b84b0, 0x7f3629be9538, 0xc82000b470)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/bind/symtab.go:360 +0xdc4
github.com/go-python/gopy/bind.(*symtab).addSymbol(0xc820011400, 0x7f3629be9348, 0xc8200b84b0)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/bind/symtab.go:291 +0x9d8
github.com/go-python/gopy/bind.(*Package).process(0xc8200af560, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/bind/package.go:176 +0x12bf
github.com/go-python/gopy/bind.NewPackage(0xc8200b8410, 0xc8200bc0e0, 0x29, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/bind/package.go:42 +0x388
main.newPackageFrom(0xc8200300b0, 0x1, 0x1, 0xc82009cc80, 0xc8200b6000, 0xc8200300b0, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/gen.go:191 +0x24c
main.newPackage(0x7fff034ca8c8, 0x11, 0xc820012044, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/gen.go:164 +0x2f9
main.gopyRunCmdBind(0xc820016900, 0xc82000a380, 0x1, 0x1, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/cmd_bind.go:73 +0x4eb
github.com/gonuts/commander.(*Command).Dispatch(0xc820016900, 0xc82000a380, 0x1, 0x1, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/gonuts/commander/commands.go:221 +0x7e2
github.com/gonuts/commander.(*Command).Dispatch(0xc820016a20, 0xc82000a370, 0x2, 0x2, 0x0, 0x0)
    /home/binet/dev/go/root/path/src/github.com/gonuts/commander/commands.go:187 +0x1f9
main.main()
    /home/binet/dev/go/root/path/src/github.com/go-python/gopy/main.go:38 +0x1fe

Limit code scanning to package/elements to be exported

I've created an example (https://github.com/kellrott/gopy/tree/wrapper/_examples/wrapper) with two packages, wrapper and wrapper_python.
wrapper has several features that gopy doesn't support (pointers to structures, channels) and is imported by wrapper_python, which simplifies and hides the interaction with those elements.
When running the command to bind wrapper_python

gopy bind github.com/go-python/gopy/_examples/wrapper/python

I get the error:

panic: could not look-up "*github.com/go-python/gopy/_examples/wrapper.RealStruct"!


goroutine 1 [running]:
github.com/go-python/gopy/bind.(*symtab).addMapType(0x823df3ce0, 0x8205d6320, 0x8820774278, 0x8205d65f0, 0x8820774218, 0x8205d0660, 0x88, 0x823e5bf40, 0x4a, 0x823e5bef0, ...)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:497 +0xa35
github.com/go-python/gopy/bind.(*symtab).addType(0x823df3ce0, 0x8820774278, 0x8205d65f0, 0x8820774218, 0x8205d0660)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:440 +0x326
github.com/go-python/gopy/bind.(*symtab).addStructType(0x823df3ce0, 0x820647bd0, 0x8820774278, 0x823e5b7c0, 0x88207b8510, 0x8205cc8a0, 0x1108, 0x823e5be00, 0x45, 0x823f50a80, ...)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:575 +0x27a
github.com/go-python/gopy/bind.(*symtab).addType(0x823df3ce0, 0x8820774278, 0x823e5b7c0, 0x88207b8510, 0x8205cc8a0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:383 +0xfd6
github.com/go-python/gopy/bind.(*symtab).addPointerType(0x823df3ce0, 0x820647bd0, 0x8820774278, 0x823e5b7c0, 0x8820774248, 0x823e41fb0, 0x8, 0x823e5bdb0, 0x46, 0x823f50980, ...)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:653 +0x14c
github.com/go-python/gopy/bind.(*symtab).addType(0x823df3ce0, 0x8820774278, 0x823e5b7c0, 0x8820774248, 0x823e41fb0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:437 +0x5ed
github.com/go-python/gopy/bind.(*symtab).addStructType(0x823df3ce0, 0x820647bd0, 0x88207b8320, 0x823e5b680, 0x88207b8510, 0x823e573e0, 0x1108, 0x823df3dc0, 0x1c, 0x823cca480, ...)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:575 +0x27a
github.com/go-python/gopy/bind.(*symtab).addType(0x823df3ce0, 0x88207b8320, 0x823e5b680, 0x88207b8510, 0x823e573e0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:383 +0xfd6
github.com/go-python/gopy/bind.(*symtab).addSymbol(0x823df3ce0, 0x88207b8320, 0x823e5b680)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/symtab.go:329 +0xa23
github.com/go-python/gopy/bind.(*Package).process(0x823db3a40, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/package.go:179 +0x26dd
github.com/go-python/gopy/bind.NewPackage(0x820647bd0, 0x820a24460, 0x32, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/bind/package.go:44 +0x390
main.newPackageFrom(0x8206440d0, 0x1, 0x1, 0x820676dc0, 0x820690000, 0x8206440d0, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/gen.go:209 +0x3bf
main.newPackage(0x7fff5fbffca4, 0x32, 0x8205cc064, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/gen.go:179 +0x638
main.gopyRunCmdBind(0x82065ca20, 0x82063c170, 0x1, 0x1, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/cmd_bind.go:73 +0x4eb
github.com/gonuts/commander.(*Command).Dispatch(0x82065ca20, 0x82063c170, 0x1, 0x1, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/gonuts/commander/commands.go:221 +0x7e2
github.com/gonuts/commander.(*Command).Dispatch(0x82065cb40, 0x82063c160, 0x2, 0x2, 0x0, 0x0)
    /Users/ellrott/workspaces/golang/src/github.com/gonuts/commander/commands.go:187 +0x1f9
main.main()
    /Users/ellrott/workspaces/golang/src/github.com/go-python/gopy/main.go:38 +0x1fe

There shouldn't be any need to create symbols for wrapper.RealStruct, it is never used in any of the wrapper_python function signature or public structure elements. It is a private element in wrapper_python.WrapperStruct, but that shouldn't be accessible in the python environment.

bind: use golang.org/x/mobile/bind/seq for cross-language call

gopy currently (mostly) sends pointers to go values back and forth between cgo and go.
on the cpython side, such types are (usually) defined like so:

typedef void *cgo_type_pkg_MyType;

struct cpy_type_pkg_MyType {
  PyObject_HEAD
  cgo_type_pkg_MyType cgopy; /* pointer to pkg.MyType */
};

under the rules currently defined at golang/go#12416, this will no longer work as we store a pointer to go memory, possibly containing itself pointers to go memory.

so we'll probably have to bite the bullet and move to the (de)serialization protocol of golang.org/x/mobile/bind/seq.

gopy: python module facade

consider creating a gopy python module facade to auto-(generate+compile+import) any go package from the python prompt (or python script)
or inject a python import hook?

e.g. (tentative api):

import gopy
hi = getattr(gopy, "github.com/go-python/gopy/_examples/hi")
hi = gopy.Import("github.com/go-python/gopy/_examples/hi")

bind: support for nested slices

The package

package nested_slice

func NestedSlice(s [][]float64) {
}

fails with

$ go build && gopy bind --lang=py2 .
panic: could not look-up "[]float64"!


goroutine 1 [running]:
github.com/go-python/gopy/bind.(*symtab).addSliceType(0x8205c5100, 0x820617ea0, 0x882076cad8, 0x820666000, 0x882076caa8, 0x8205c6d80, 0x808, 0x8205c5160, 0x18, 0x8205c6f50, ...)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:483 +0xacc
github.com/go-python/gopy/bind.(*symtab).addType(0x8205c5100, 0x882076cad8, 0x820666000, 0x882076caa8, 0x8205c6d80)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:366 +0x2aa
github.com/go-python/gopy/bind.(*symtab).processTuple(0x8205c5100, 0x8205c4de0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:337 +0x149
github.com/go-python/gopy/bind.(*symtab).addSymbol(0x8205c5100, 0x882076c408, 0x820617f40)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:317 +0xceb
github.com/go-python/gopy/bind.(*Package).process(0x82063edc0, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/package.go:179 +0x26a4
github.com/go-python/gopy/bind.NewPackage(0x820617ea0, 0x820657880, 0x19, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/package.go:44 +0x390
main.newPackageFrom(0x8205de0a8, 0x1, 0x1, 0x82063ec80, 0x820658000, 0x8205de0a8, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:197 +0x3bf
main.newPackage(0x7fff5fbffa5d, 0x1, 0x8205c0144, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:167 +0x638
main.gopyRunCmdBind(0x820628a20, 0x8205c0330, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/cmd_bind.go:73 +0x4eb
github.com/gonuts/commander.(*Command).Dispatch(0x820628a20, 0x8205c0330, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:221 +0x7e2
github.com/gonuts/commander.(*Command).Dispatch(0x820628b40, 0x8205c0310, 0x3, 0x3, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:187 +0x1f9
main.main()
    /Users/phil/code/go/src/github.com/go-python/gopy/main.go:38 +0x1fe

handling of packages using other packages' types or values

consider:

// pkg1/pk1.go
package pkg1

const C = 42
var V = 42
type T struct {}

and:

// pkg2/pkg2.go
package pkg2

import ( 
    "github.com/some/pkg1"
)

func NewT() pkg1.T {...}

what should gopy do?

  • pull in the whole pkg1 package and wrap it as part of pkg2.so ?
  • wrap pkg2.NewT and return a PyObject/PyDict? an opaque PyCObject ?
  • wrap pkg2.NewT and return a PyCapsule ?
  • bail out ?
  • something else ?

https://docs.python.org/2/c-api/capsule.html#capsules

bind: support for typed constants and named vars

right now:

package consts
type Kind int
const (
  Kind1 Kind = 0
)

results in:

sh> gopy bind ../_examples/consts
./consts.go:172: cannot use consts.Kind1 (type consts.Kind) as type cgo_type_consts_Kind in return argument

dittor for vars.

interplay of python.gc and go.gc

both python and go have a GC.
leverage gomobile's Ref code to make sure no value disappear under our feet when it goes through a language boundary.

consider using gomobile seq serialization code to also make sure go GC won't move pointers around.
see: https://golang.org/s/gobind

bind: support funcs taking pointers

right now:

package pointers
type S struct {
    Value int
}

// Inc increments the value of s
func Inc(s *S) {
    s.Value++
}

results in:

>>> import pointers as p
>>> s = p.S(2)
>>> p.Inc(s)
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x2 pc=0x7f1cc7c47fe7]

goroutine 17 [running, locked to thread]:
github.com/go-python/gopy/_examples/pointers.Inc(0x2)
    github.com/go-python/gopy/_examples/pointers/pointers.go:18 +0x7a
main.cgo_func_pointers_Inc(0xc82000a340)
    tmp/gopy-586713227/pointers.go:151 +0x26

goroutine 18 [syscall, locked to thread]:
runtime.goexit()
    go/src/runtime/asm_amd64.s:1696 +0x1
Aborted (core dumped)

that's because of the following cgo code:

//export cgo_func_pointers_Inc
// cgo_func_pointers_Inc wraps pointers.Inc
func cgo_func_pointers_Inc(s cgo_type_pointers_S) () {
    pointers.Inc(*(**pointers.S)(unsafe.Pointer(s)))
}

which should, instead, read:

//export cgo_func_pointers_Inc
// cgo_func_pointers_Inc wraps pointers.Inc
func cgo_func_pointers_Inc(s cgo_type_pointers_S) () {
    pointers.Inc((*pointers.S)(unsafe.Pointer(s)))
}

check number and type of args

gopy should generate code to check for the correct number of arguments for functions and methods.
as well as their input types.

bind: support for private fields

The following package

package private

type Test struct {
    Public int
    private int
}

fails with

$ gopy bind --lang=py2 .
2015/08/31 10:15:15 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-571736582
# _/private/var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-571736582
./private.c:224:7: warning: implicit declaration of function 'cpy_func_private_Test_setter_2' is invalid in C99 [-Wimplicit-function-declaration]
# _/private/var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-571736582
Undefined symbols for architecture x86_64:
  "_cpy_func_private_Test_setter_2", referenced from:
      _cpy_func_private_Test_init in private.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
2015/08/31 10:15:17 error dispatching command: exit status 2

wrap top-level go.consts

and implement via a dedicated pyobject with getter but no setter.
one may loose precision... (use python's math/big equivalent?)

bind: support for variadic arguments

The package

package variadic

func Variadic(s ...float64) {
}

fails with

go build && gopy bind --lang=py2 .
2015/08/31 10:36:03 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-208401189
# _/private/var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-208401189
./variadic.go:159: cannot use *(*[]float64)(unsafe.Pointer(s)) (type []float64) as type float64 in argument to variadic.Variadic
2015/08/31 10:36:03 error dispatching command: exit status 2

bind: support for all builtin types

Currently rune, uintptr, and unsafe.Pointer are not supported.

The package

package types
var X rune

fails with

$ go build && gopy bind --lang=py2 .
2015/08/31 21:18:05 work: /var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-283258537
# _/private/var/folders/j0/l297p36x68dfmcrh07jptj200000gn/T/gopy-283258537
./types.c:150:2: error: use of undeclared identifier 'GoRune'
./types.c:152:2: error: use of undeclared identifier 'c_gopy_ret'
./types.c:154:29: error: use of undeclared identifier 'cgopy_cnv_c2py_rune'
./types.c:161:2: error: use of undeclared identifier 'GoRune'
./types.c:163:36: error: use of undeclared identifier 'cgopy_cnv_py2c_rune'
./types.c:168:23: error: use of undeclared identifier 'c_X'
2015/08/31 21:18:06 error dispatching command: exit status 2

The package

package types
var X uintptr

fails with

$ go build && gopy bind --lang=py2 .
panic: builtin type not already known [uintptr]!

goroutine 1 [running]:
github.com/go-python/gopy/bind.(*symtab).addType(0x8205cf000, 0x8820776a40, 0x820621ef0, 0x8820776318, 0x53dc00)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:363 +0x7c9
github.com/go-python/gopy/bind.(*symtab).addSymbol(0x8205cf000, 0x8820776a40, 0x820621ef0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:308 +0x456
github.com/go-python/gopy/bind.(*Package).process(0x820648dc0, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/package.go:179 +0x26dd
github.com/go-python/gopy/bind.NewPackage(0x820621e50, 0x820661880, 0x14, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/package.go:44 +0x390
main.newPackageFrom(0x8205e80a0, 0x1, 0x1, 0x820648c80, 0x820662000, 0x8205e80a0, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:209 +0x3bf
main.newPackage(0x7fff5fbffa5d, 0x1, 0x8205d2064, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:179 +0x638
main.gopyRunCmdBind(0x8206327e0, 0x8205ca2f0, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/cmd_bind.go:73 +0x4eb
github.com/gonuts/commander.(*Command).Dispatch(0x8206327e0, 0x8205ca2f0, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:221 +0x7e2
github.com/gonuts/commander.(*Command).Dispatch(0x820632900, 0x8205ca2d0, 0x3, 0x3, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:187 +0x1f9
main.main()
    /Users/phil/code/go/src/github.com/go-python/gopy/main.go:38 +0x1fe

The package

package types
import "unsafe"
var X unsafe.Pointer

fails with

$ go build && gopy bind --lang=py2 .
panic: builtin type not already known [unsafe.Pointer]!

goroutine 1 [running]:
github.com/go-python/gopy/bind.(*symtab).addType(0x8205cf180, 0x8820776b70, 0x820621ef0, 0x8820776318, 0x53dcc0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:363 +0x7c9
github.com/go-python/gopy/bind.(*symtab).addSymbol(0x8205cf180, 0x8820776b70, 0x820621ef0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/symtab.go:308 +0x456
github.com/go-python/gopy/bind.(*Package).process(0x820648e60, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/package.go:179 +0x26dd
github.com/go-python/gopy/bind.NewPackage(0x820621e50, 0x820661880, 0x14, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/bind/package.go:44 +0x390
main.newPackageFrom(0x8205e80b0, 0x1, 0x1, 0x820648d20, 0x820662000, 0x8205e80b0, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:209 +0x3bf
main.newPackage(0x7fff5fbffa5d, 0x1, 0x8205d2064, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/gen.go:179 +0x638
main.gopyRunCmdBind(0x8206326c0, 0x8205ca2f0, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/go-python/gopy/cmd_bind.go:73 +0x4eb
github.com/gonuts/commander.(*Command).Dispatch(0x8206326c0, 0x8205ca2f0, 0x1, 0x1, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:221 +0x7e2
github.com/gonuts/commander.(*Command).Dispatch(0x8206327e0, 0x8205ca2d0, 0x3, 0x3, 0x0, 0x0)
    /Users/phil/code/go/src/github.com/gonuts/commander/commands.go:187 +0x1f9
main.main()
    /Users/phil/code/go/src/github.com/go-python/gopy/main.go:38 +0x1fe

Probably the best thing to hand a Python program that asks for an unsafe.Pointer is a ctypes.c_void_p.

gopy: support for cgo-based packages

right now, a package importing "C" can not be (directly) wrapped:

sh> gopy bind ./_examples/cpkg
2015/08/10 09:26:25 _examples/cpkg/cpkg.go:13:8: could not import C (the loader doesn't cgo-process ad hoc packages like "github.com/go-python/gopy/_examples/cpkg"; see Go issue 11627)
2015/08/10 09:26:25 _examples/cpkg/cpkg.go:25:10: undeclared name: C
2015/08/10 09:26:25 _examples/cpkg/cpkg.go:26:8: undeclared name: C
2015/08/10 09:26:25 _examples/cpkg/cpkg.go:27:2: undeclared name: C
2015/08/10 09:26:25 couldn't load packages due to errors: github.com/go-python/gopy/_examples/cpkg
2015/08/10 09:26:25 error dispatching command: gopy-bind: go/build.Import failed with path="./_examples/cpkg": couldn't load packages due to errors: github.com/go-python/gopy/_examples/cpkg

this is because of golang/go#11627.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.