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](https://github.com/goki/gi) 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).
* 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.
Currently using [pybindgen](https://pybindgen.readthedocs.io/en/latest/tutorial/) to generate the low-level c-to-python bindings, but support for [cffi](https://cffi.readthedocs.io/en/latest/) 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.
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):
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.
(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).
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.
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.
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).
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:
```bash
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.
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):
```sh
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.