Giter Site home page Giter Site logo

go-python's Introduction

go-python

sbinet/go-python only supports CPython2. CPython2 isn't supported anymore by python.org. Thus, sbinet/go-python is now archived. A possible alternative may be to use and contribute to go-python/cpy3 instead.

Build Status Build status GoDocs

Naive go bindings towards the C-API of CPython-2.

this package provides a go package named "python" under which most of the PyXYZ functions and macros of the public C-API of CPython have been exposed.

theoretically, you should be able to just look at:

http://docs.python.org/c-api/index.html

and know what to type in your go program.

this package also provides an executable "go-python" which just loads "python" and then call python.Py_Main(os.Args). the rational being that under such an executable, go based extensions for C-Python would be easier to implement (as this usually means calling into go from C through some rather convoluted functions hops)

Install

With Go 1 and the go tool, cgo packages can't pass anymore additional CGO_CFLAGS from external programs (except pkg-config) to the "fake" #cgo preprocessor directive.

go-python now uses pkg-config to get the correct location of headers and libraries. Unfortunately, the naming convention for the pkg-config package is not standardised across distributions and OSes, so you may have to edit the cgoflags.go file accordingly.

 $ go get github.com/sbinet/go-python

If go get + pkg-config failed:

 $ cd go-python
 $ edit cgoflags.go
 $ make VERBOSE=1

Note: you'll need the proper header and python development environment. On Debian, you'll need to install the python-all-dev package

Documentation

Is available on godocs:

https://godocs.io/github.com/sbinet/go-python

Example:

package main

import "fmt"
import "github.com/sbinet/go-python"

func init() {
   err := python.Initialize()
   if err != nil {
          panic(err.Error())
   } 
}

func main() {
 	 gostr := "foo" 
	 pystr := python.PyString_FromString(gostr)
	 str := python.PyString_AsString(pystr)
	 fmt.Println("hello [", str, "]")
}
$ go run ./main.go
hello [ foo ]

TODO:

  • fix handling of integers (I did a poor job at making sure everything was ok)

  • add CPython unit-tests

  • do not expose C.FILE pointer and replace it with os.File in "go-python" API

  • provide an easy way to extend go-python with go based extensions

  • think about the need (or not) to translate CPython exceptions into go panic/recover mechanism

  • use SWIG to automatically wrap the whole CPython api ?

go-python's People

Contributors

aliafshar avatar dennwc avatar eliothedeman avatar gward avatar hush-hush avatar huzilin avatar icholy avatar masci avatar mstetson avatar remh avatar sbinet avatar tfogal 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  avatar

go-python's Issues

go run error?

fatal error: unexpected signal during runtime execution
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x7f17cdca447b]

runtime stack:
runtime.throw(0x74c3c2, 0x2a)
/usr/local/go/src/runtime/panic.go:616 +0x81
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:372 +0x28e

goroutine 506 [syscall]:
runtime.cgocall(0x68bad0, 0xc420384e68, 0x4)
/usr/local/go/src/runtime/cgocall.go:128 +0x64 fp=0xc420384e38 sp=0xc420384e00 pc=0x40eb44
github.com/sbinet/go-python._Cfunc_PyImport_ImportModule(0x7f17bc0008c0, 0x0)
_cgo_gotypes.go:3023 +0x4a fp=0xc420384e68 sp=0xc420384e38 pc=0x4f9dba
github.com/sbinet/go-python.PyImport_ImportModule(0x73fc40, 0x4, 0x0)

Make returns error

running make returns the following error:

CGO_LDFLAGS="-L/usr/lib/python2.7 -lpython2.7" CGO_CFLAGS="-I/usr/include/python2.7 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security" go install -compiler="gc" .
go install: no install location for _/home/smith/go/pkg/github.com/sbinet/go-python
make: *** [install] Error 1

My GOPATH is /home/smith/go.

Is there a way to call function with key-word parameters?

Tried a few ways. Even the following doesn't seem to work.

    // arguments
    _a := python.PyTuple_New(1)
    python.PyTuple_SET_ITEM(_a, 0, python.PyString_FromString(`test.mp3`))

    // keyword arguments
    _kw := python.PyDict_New()
    python.PyDict_SetItem(_kw, python.PyString_FromString(`v2_version`), python.PyInt_FromLong(3))

    // pack arguments
    _args := python.PyTuple_New(2)
    python.PyTuple_SET_ITEM(_args, 0, _a)
    python.PyTuple_SET_ITEM(_args, 1, _kw)

    // ID3 is a callable
    id3 := ID3.CallObject(_args)
    if id3 == nil {
        panic("failed")
    }

Issue while invoking a python code which has reference to sys.argv

We are facing an issue in our project while using go-python package.
It seems something related to python version and compatibility with go-python package. (python version is 2.7.10)

Issue Description

To simulate the issue I have python written as below

#!/bin/python

import sys

def PrintSysArgv():
    print (sys.argv)

if __name__ == "__main__":
    PrintSysArgv()

This python if I run from python CLI works fine as shown below

>python test.py
['test.py']
>

Now I have go program to invoke the same function PrintSysArgv as below

package main

import (
    "<package>/gopy"
    "fmt"
)

var funcNames = [...]string{
    "PrintSysArgv",
}

var pyFuncs map[string]*gopy.PyFunction

func main() {
    pyFuncs, err := gopy.Import("mymodule.test", funcNames[:]...)
    if err != nil {
        panic("Error importing python module")
    }

    _, err = pyFuncs["PrintSysArgv"].Call()
    if err != nil {
        panic(fmt.Sprintf("Error executing python function. error: %v", err))
    }
    fmt.Println("Done")
}

Below is the snippet of gopy wrapper I am using in above go source

package gopy

import (
        "errors"
        "fmt"
        "github.com/sbinet/go-python"
        "reflect"
)

type PyFunction struct {
        *python.PyObject
}

func (f *PyFunction) Call(args ...interface{}) (r *python.PyObject, err error) {
        var pyargs *python.PyObject

        if pyargs, err = ToPyObject(reflect.ValueOf(args)); err != nil {
                return
        }

        name := python.PyString_AsString(f.GetAttrString("__name__"))
        if r = f.CallObject(pyargs); r == nil {
                err = errors.New(fmt.Sprintf("%s(): function failed at python side", name))
        }
        if pyobj := python.PyErr_Occurred(); pyobj != nil {
                err = errors.New(fmt.Sprintf("%s(): exception happened in python side", name))
                python.PyErr_Clear()
        }
        return
}

var pyinit = false

func Init() (err error) {
        if !pyinit {
                if err = python.Initialize(); err == nil {
                        pyinit = true
                }
        }
        return
}

func Import(module string, functions ...string) (funcs map[string]*PyFunction, err error) {
        if err = Init(); err != nil {
                return
        }

        if pymod := python.PyImport_ImportModuleNoBlock(module); pymod == nil {
                err = errors.New(fmt.Sprintf("gopy:%s: module import failed", module))
        } else {
                funcs = make(map[string]*PyFunction)
                for _, name := range functions {
                        if pyfunc := pymod.GetAttrString(name); pyfunc == nil {
                                err = errors.New(fmt.Sprintf("gopy:%s:%s: function not found", module, name))
                                return
                        } else {
                                funcs[name] = &PyFunction{pyfunc}
                        }
                }
        }
        return
}

The out of the execution of go program fails python side as shown below

go run test.go
panic: Error executing python function. error: PrintSysArgv(): exception happened in python side

goroutine 1 [running]:
main.main()
    /root/go/bin/test.go:22 +0x291

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
exit status 2

Just a wierd thought that go-python uses a trimmed version of python which is not able to take care of "sys.argv" as such.

Can you please look into the same and suggest us accordingly.

If needed / suggested I can raise the same in wiki...

Thanks and Regards,
Shubhendu

Quick spelling update

As a friendly suggestion, it might be worth updating the first word in the README.md file from naive to native .

Exposing C pointer inside python.PyObject outside the package

Hi,

First let me explain my usage of go-python.

We are calling Python functions/classes from Go. For that go-python is great !
But we also would like to extend python with the features from our Go project, so core features are usable in Python.

For now we have some C that exposes our Go code to Python. This C code basically do what go-python does internally (calling the CPython API, translating a few types, ...). At first it was okay, but the number of Go features exposed to Python is growing pretty fast.

We have written a certain amount of helpers around go-python that we would like to use in our C binding. The problem is that we need to return to C the internal C pointer inside the Go type PyObject (this one https://github.com/sbinet/go-python/blob/master/object.go#L15). And their is no way to access it outside the package.
Therefore this issue to expose it (or create a getter to it). This would allow us to do everything in Go and limit our C code to the minimal.

I also saw that go-python offers Py_InitModule method. If we could create our python module from Go, delegating the C part to go-python, it would solve our problem. But from what I read from the code, we must give pointers to C function in PyMethodDef (https://github.com/sbinet/go-python/blob/master/heap.go#L27). Right ?

This comment let me think that this feature may not be ready yet: https://github.com/sbinet/go-python/blob/master/heap.go#L16
Is it the case ?

In any case thank you for the answer.

Creating PyObject* in external code

Just getting started with this wrapper. Great so far, thank you!

I have a need to create NumPy arrays from some Go code. I started this externally to the project, but I quickly ran up against the issue that NumPy creates PyObject* that should be treated in the go-python way, but I can't get these into go-python.

The 'togo' function is not public. However, even making it public does not help much, due to Go typing issues: *_Ctype_PyObject != *python._Ctype_PyObject (in English, *C.PyObject in another package is a distinct type from *C.PyObject from within the package).

To workaround this, I've been using the following patch that simple exports a modified 'togo'.

Any chance we could get something like this in the shipped version?

diff --git a/object.go b/object.go
index 2ea548d..c80a06d 100644
--- a/object.go
+++ b/object.go
@@ -30,6 +30,12 @@ func togo(obj *C.PyObject) *PyObject {
        }
        return &PyObject{ptr: obj}
 }
+func ToGo(obj unsafe.Pointer) *PyObject {
+       if obj == nil {
+               return nil
+       }
+       return &PyObject{ptr: ((*C.PyObject)(obj))}
+}

 func int2bool(i C.int) bool {
        switch i {

Running example error

My go environment on Linux is

root@ubuntu:/usr/local/go/src# go env
GOARCH="amd64"
GOBIN="/usr/local/go/bin/"
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/opt/go"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
GO386="sse2"
CC="gcc"
CXX="g++"
CGO_ENABLED="0"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m32 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build387092920=/tmp/go-build -gno-record-gcc-switches"

when I execute

go run test.go

It return error below

go build github.com/sbinet/go-python: build constraints exclude all Go files in /opt/go/src/github.com/sbinet/go-python

PyObject_CallFunction and PyObject_CallMethod - not implemented

// PyObject* PyObject_CallFunction(PyObject *callable, char *format, ...)
// Return value: New reference.
// Call a callable Python object callable, with a variable number of C arguments. The C arguments are described using a Py_BuildValue() style format string. The format may be NULL, indicating that no arguments are provided. Returns the result of the call on success, or NULL on failure. This is the equivalent of the Python expression apply(callable, args) or callable(*args). Note that if you only pass PyObject * args, PyObject_CallFunctionObjArgs() is a faster alternative.
func (self *PyObject) CallFunction(format string, args ...interface{}) *PyObject {
    //FIXME
    panic("not implemented")
    return nil
}

// PyObject* PyObject_CallMethod(PyObject *o, char *method, char *format, ...)
// Return value: New reference.
// Call the method named method of object o with a variable number of C arguments. The C arguments are described by a Py_BuildValue() format string that should produce a tuple. The format may be NULL, indicating that no arguments are provided. Returns the result of the call on success, or NULL on failure. This is the equivalent of the Python expression o.method(args). Note that if you only pass PyObject * args, PyObject_CallMethodObjArgs() is a faster alternative.
func (self *PyObject) CallMethod(format string, args ...interface{}) *PyObject {
    //FIXME
    panic("not implemented")
    return nil
}

Implement Py_BuildValue

Py_BuildValue is not implemented.

func Py_BuildValue(format string, args ...interface{}) *PyObject {
	return nil
}

Example:
f(7,8,9) =

values := python.PyTuple_New(3)
python.PyTuple_SET_ITEM(values, 0, python.PyInt_FromLong(7))
python.PyTuple_SET_ITEM(values, 1, python.PyInt_FromLong(8))
python.PyTuple_SET_ITEM(values, 2, python.PyInt_FromLong(9))
f.CallObject(values)

should be possible with

values := python.Py_BuildValue("(i,i,i)", 7, 8, 9)
f.CallObject(values)

Question: how to set the embedded Python to virtualenv Python ?

Hi,
I'm trying to write a Go executable that is able to pick up whichever Python version (hence libraries) it's running on. For example, in macOS the default system Python is 2.7.14, but could be executed within Python 3.6.5 virtualenv. As you know, working with virtualenv it's quite nice too, because the libraries installed within the env won't have to be globally installed.

I have tried to prefix the PYTHON_HOME env variable with the VIRTUAL_ENV (Python bin) before python.Initialize(). However this seems to result in still picking the system Python 2.7.14. I can see the PATH env variable started with the correct VIRTUAL_ENV path, but the embedded Python once again is still picking up the system Python.

One of the suggested workarounds on StackOverflow: 7492855 with (Python C API) was to set the program name via Py_SetProgramName. Although I don't seem to be able to find this function on go-python.

Anything suggestions ? or, perhaps I'm missing something quite obvious.

Thanks and regards,
Wan.

Local installation problem

Hi,

this project is based on Python 2.7 version but I need it for Python 2.7.5. So I changed the cgo file to Python 2.7.5 version by downloading the project locally in my computer. So, I can't use the command go get ... to install it. I need to install it locally in my computer use the make file. Now, I am getting this error:

go get -compiler="gc" .
go install: no install location for directory /Users/../../go-python-master outside GOPATH
make: *** [install] Error 1

I tried to set the GOPATH with: export GOPATH=${PWD} but in vain. Could you tell the right way to install it locally.

go-python does not execute a python module anymore if that module once raises an exception

Having an issue where, we invoke a python code using go-python. If the python code raises some exception once, then onwards any call to that python module returns immediately from CallObject() with blank return value.

Sample code to invoke python looks as below

var pyinit = false
func Init() (err error) {
    if !pyinit {
        if err = python.Initialize(); err == nil {
            pyinit = true
        }
    }
    return
}

type PyFunction struct {
    *python.PyObject
}

var mutex sync.Mutex
func Import(module string, functions ...string) (funcs map[string]*PyFunction, err error) {
    if err = Init(); err != nil {
        return
    }

    if pymod := python.PyImport_ImportModuleNoBlock(module); pymod == nil {
        err = errors.New(fmt.Sprintf("gopy:%s: module import failed", module))
    } else {
        funcs = make(map[string]*PyFunction)
        for _, name := range functions {
            if pyfunc := pymod.GetAttrString(name); pyfunc == nil {
                err = errors.New(fmt.Sprintf("gopy:%s:%s: function not found", module, name))
                return
            } else {
                funcs[name] = &PyFunction{pyfunc}
            }
        }
    }
    return
}

func (f *PyFunction) Call(args ...interface{}) {
    var pyargs *python.PyObject

    if pyargs, err = ToPyObject(reflect.ValueOf(args)); err != nil {
        return
    }
    mutex.Lock()
    defer mutex.Unlock()
    name := python.PyString_AsString(f.GetAttrString("__name__"))
    if r = f.CallObject(pyargs); r == nil {
        err = errors.New(fmt.Sprintf("%s(): function failed at python side", name))
    }
 }

var funcNames = [...]string{
    "MyFunc",
}

var pyFuncs map[string]*PyFunction
func main() {
        pyFuncs, err := gopy.Import("mypackage", funcNames[:]...)
        if err != nil {
        panic(err)
    }
       for {
           if pyFuncs["MyFunc"].Call(); err !=nil {
               // handle the error
           }
      }
}

In above scenario say the python function mypackage.MyFunc raises an exception in some scenario. Then onwards, it never enters the python code at all and keeps showing the error "function failed at python side".

Not sure if we should re-load the python interpreter from go code once exception or something else.
Kindly suggest.

Regards,
Shubhendu

undefined reference

Hi,

When i tried make, i got many python errors. I confirmed the python is correctly installed....any idea on this? Thanks a lot!

gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK/b001=/tmp/go-build -gno-record-gcc-switches -o $WORK/b001/cgo.o $WORK/b001/_cgo_main.o $WORK/b001/_x001.o $WORK/b001/_x002.o $WORK/b001/_x003.o $WORK/b001/_x004.o $WORK/b001/_x005.o $WORK/b001/_x006.o $WORK/b001/_x007.o $WORK/b001/_x008.o $WORK/b001/_x009.o $WORK/b001/_x010.o $WORK/b001/_x011.o $WORK/b001/_x012.o $WORK/b001/_x013.o $WORK/b001/_x014.o $WORK/b001/_x015.o $WORK/b001/_x016.o $WORK/b001/_x017.o $WORK/b001/_x018.o $WORK/b001/_x019.o $WORK/b001/_x020.o $WORK/b001/_x021.o -g -O2 -L/usr/local/lib -lpython2.7

go-python-master

/usr/local/lib/libpython2.7.a(complexobject.o): In function _Py_c_abs': /usr/src/Python-2.7.15/Objects/complexobject.c:214: undefined reference to hypot'
/usr/local/lib/libpython2.7.a(complexobject.o): In function complex_remainder': /usr/src/Python-2.7.15/Objects/complexobject.c:616: undefined reference to floor'
/usr/local/lib/libpython2.7.a(complexobject.o): In function complex_divmod': /usr/src/Python-2.7.15/Objects/complexobject.c:642: undefined reference to floor'
/usr/local/lib/libpython2.7.a(complexobject.o): In function _Py_c_pow': /usr/src/Python-2.7.15/Objects/complexobject.c:143: undefined reference to hypot'
/usr/src/Python-2.7.15/Objects/complexobject.c:144: undefined reference to pow' /usr/src/Python-2.7.15/Objects/complexobject.c:145: undefined reference to atan2'
/usr/src/Python-2.7.15/Objects/complexobject.c:147: undefined reference to sincos' /usr/src/Python-2.7.15/Objects/complexobject.c:148: undefined reference to exp'
/usr/src/Python-2.7.15/Objects/complexobject.c:149: undefined reference to log' /usr/src/Python-2.7.15/Objects/complexobject.c:143: undefined reference to hypot'
/usr/src/Python-2.7.15/Objects/complexobject.c:144: undefined reference to pow' /usr/src/Python-2.7.15/Objects/complexobject.c:145: undefined reference to atan2'
/usr/src/Python-2.7.15/Objects/complexobject.c:146: undefined reference to sincos' /usr/local/lib/libpython2.7.a(complexobject.o): In function _Py_c_abs':
/usr/src/Python-2.7.15/Objects/complexobject.c:214: undefined reference to hypot' /usr/local/lib/libpython2.7.a(floatobject.o): In function float_is_integer':
/usr/src/Python-2.7.15/Objects/floatobject.c:995: undefined reference to `floor'

Test kwargs erro on macos

Hi,i am runing the test case kw-args/main.go in my macos10.9, and it panic
"importing kwargs...
2016/04/16 01:32:29 could not import 'kwargs'
exit status 1
"
can you give me some adices,thanks!

asking about pkg-config problem

I go get in window. It's come up with

$ go get github.com/sbinet/go-python
# pkg-config --cflags python-2.7
Package python-2.7 was not found in the pkg-config search path.
Perhaps you should add the directory containing `python-2.7.pc'
to the PKG_CONFIG_PATH environment variable
No package 'python-2.7' found
pkg-config: exit status 1

This not happen for me in OSX
Now I cant even find .pc files in any directories. So I don't know what to add in PKG_CONFIG_PATH

Sorry for asking stupid question
I'm pretty new in window, python, pkg-config

windows pkg-config problem

I want to use it in windows, but when I run the below command,it performs err

C:\Users\Administrator> go get github.com/sbinet/go-python
# pkg-config --cflags python
pkg-config: exec: "pkg-config": executable file not found in %PATH%

How I can I solve this problem?
Need help!!

Question: on the TODO item - "fix handling of integers"

Hello,
I am planning to use the go-python package in one of my demo project.
However I am a bit curious on this TODO item - "fix handling of integers (I did a poor job at making sure everything was ok)"
Not sure how this is going to affect the project. Could you please give some more details on this TODO item? ie, Whats missing and what you would like to add?
Would like to contribute into this, if I can :)

passing in NULL to go-python function?

I'm trying to use PyList_SetSlice and according to the documentation, we can set itemlist to NULL. How would I do this? I tried C.NULL, nil, and even 0 but nothing seems to work.

Double free if passing args to Py_Main

$ go build -o go-python.buggy ./cmd/go-python/main.go 
[0 tv@brute ~/go/src/github.com/sbinet/go-python]$ ./go-python.buggy -c 'print 1+1'
2
*** Error in `./go-python.buggy': double free or corruption (out): 0x00007f15b5060ff0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x80996)[0x7f15b4860996]
./go-python.buggy[0x4307e1]
======= Memory map: ========
00400000-005cb000 r-xp 00000000 00:10 1714079                            /home/tv/go/src/github.com/sbinet/go-python/go-python.buggy
007ca000-007cb000 r--p 001ca000 00:10 1714079                            /home/tv/go/src/github.com/sbinet/go-python/go-python.buggy
007cb000-007d5000 rw-p 001cb000 00:10 1714079                            /home/tv/go/src/github.com/sbinet/go-python/go-python.buggy
007d5000-007f1000 rw-p 00000000 00:00 0 
02390000-0248c000 rw-p 00000000 00:00 0                                  [heap]
c000000000-c000002000 rw-p 00000000 00:00 0 
c207ff0000-c208100000 rw-p 00000000 00:00 0 
7f15ac000000-7f15ac021000 rw-p 00000000 00:00 0 
7f15ac021000-7f15b0000000 ---p 00000000 00:00 0 
7f15b1b8c000-7f15b1ba1000 r-xp 00000000 00:10 19145                      /lib/x86_64-linux-gnu/libgcc_s.so.1
7f15b1ba1000-7f15b1da0000 ---p 00015000 00:10 19145                      /lib/x86_64-linux-gnu/libgcc_s.so.1
7f15b1da0000-7f15b1da1000 r--p 00014000 00:10 19145                      /lib/x86_64-linux-gnu/libgcc_s.so.1
7f15b1da1000-7f15b1da2000 rw-p 00015000 00:10 19145                      /lib/x86_64-linux-gnu/libgcc_s.so.1
7f15b1da2000-7f15b2484000 r--p 00000000 00:10 31725                      /usr/lib/locale/locale-archive
7f15b2484000-7f15b25b9000 rw-p 00000000 00:00 0 
7f15b25b9000-7f15b25ba000 ---p 00000000 00:00 0 
7f15b25ba000-7f15b2dba000 rw-p 00000000 00:00 0                          [stack:24223]
7f15b2dba000-7f15b2dbb000 ---p 00000000 00:00 0 
7f15b2dbb000-7f15b36bb000 rw-p 00000000 00:00 0 
7f15b36bb000-7f15b36bc000 ---p 00000000 00:00 0 
7f15b36bc000-7f15b3ebc000 rw-p 00000000 00:00 0                          [stack:24221]
7f15b3ebc000-7f15b3fbf000 r-xp 00000000 00:10 19159                      /lib/x86_64-linux-gnu/libm-2.17.so
7f15b3fbf000-7f15b41be000 ---p 00103000 00:10 19159                      /lib/x86_64-linux-gnu/libm-2.17.so
7f15b41be000-7f15b41bf000 r--p 00102000 00:10 19159                      /lib/x86_64-linux-gnu/libm-2.17.so
7f15b41bf000-7f15b41c0000 rw-p 00103000 00:10 19159                      /lib/x86_64-linux-gnu/libm-2.17.so
7f15b41c0000-7f15b41c2000 r-xp 00000000 00:10 19211                      /lib/x86_64-linux-gnu/libutil-2.17.so
7f15b41c2000-7f15b43c1000 ---p 00002000 00:10 19211                      /lib/x86_64-linux-gnu/libutil-2.17.so
7f15b43c1000-7f15b43c2000 r--p 00001000 00:10 19211                      /lib/x86_64-linux-gnu/libutil-2.17.so
7f15b43c2000-7f15b43c3000 rw-p 00002000 00:10 19211                      /lib/x86_64-linux-gnu/libutil-2.17.so
7f15b43c3000-7f15b43c6000 r-xp 00000000 00:10 19140                      /lib/x86_64-linux-gnu/libdl-2.17.so
7f15b43c6000-7f15b45c5000 ---p 00003000 00:10 19140                      /lib/x86_64-linux-gnu/libdl-2.17.so
7f15b45c5000-7f15b45c6000 r--p 00002000 00:10 19140                      /lib/x86_64-linux-gnu/libdl-2.17.so
7f15b45c6000-7f15b45c7000 rw-p 00003000 00:10 19140                      /lib/x86_64-linux-gnu/libdl-2.17.so
7f15b45c7000-7f15b45df000 r-xp 00000000 00:10 19215                      /lib/x86_64-linux-gnu/libz.so.1.2.8
7f15b45df000-7f15b47de000 ---p 00018000 00:10 19215                      /lib/x86_64-linux-gnu/libz.so.1.2.8
7f15b47de000-7f15b47df000 r--p 00017000 00:10 19215                      /lib/x86_64-linux-gnu/libz.so.1.2.8
7f15b47df000-7f15b47e0000 rw-p 00018000 00:10 19215                      /lib/x86_64-linux-gnu/libz.so.1.2.8
7f15b47e0000-7f15b499d000 r-xp 00000000 00:10 19131                      /lib/x86_64-linux-gnu/libc-2.17.so
7f15b499d000-7f15b4b9d000 ---p 001bd000 00:10 19131                      /lib/x86_64-linux-gnu/libc-2.17.so
7f15b4b9d000-7f15b4ba1000 r--p 001bd000 00:10 19131                      /lib/x86_64-linux-gnu/libc-2.17.so
7f15b4ba1000-7f15b4ba3000 rw-p 001c1000 00:10 19131                      /lib/x86_64-linux-gnu/libc-2.17.so
7f15b4ba3000-7f15b4ba8000 rw-p 00000000 00:00 0 
7f15b4ba8000-7f15b4bbf000 r-xp 00000000 00:10 19192                      /lib/x86_64-linux-gnu/libpthread-2.17.so
7f15b4bbf000-7f15b4dbf000 ---p 00017000 00:10 19192                      /lib/x86_64-linux-gnu/libpthread-2.17.so
7f15b4dbf000-7f15b4dc0000 r--p 00017000 00:10 19192                      /lib/x86_64-linux-gnu/libpthread-2.17.so
7f15b4dc0000-7f15b4dc1000 rw-p 00018000 00:10 19192                      /lib/x86_64-linux-gnu/libpthread-2.17.so
7f15b4dc1000-7f15b4dc5000 rw-p 00000000 00:00 0 
7f15b4dc5000-7f15b50a1000 r-xp 00000000 00:10 44746                      /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0
7f15b50a1000-7f15b52a0000 ---p 002dc000 00:10 44746                      /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0
7f15b52a0000-7f15b52a2000 r--p 002db000 00:10 44746                      /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0
7f15b52a2000-7f15b5317000 rw-p 002dd000 00:10 44746                      /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0
7f15b5317000-7f15b5329000 rw-p 00000000 00:00 0 
7f15b5329000-7f15b534c000 r-xp 00000000 00:10 19118                      /lib/x86_64-linux-gnu/ld-2.17.so
7f15b536c000-7f15b5531000 rw-p 00000000 00:00 0                          [stack:24222]
7f15b5537000-7f15b554b000 rw-p 00000000 00:00 0 
7f15b554b000-7f15b554c000 r--p 00022000 00:10 19118                      /lib/x86_64-linux-gnu/ld-2.17.so
7f15b554c000-7f15b554e000 rw-p 00023000 00:10 19118                      /lib/x86_64-linux-gnu/ld-2.17.so
7fff7f5e9000-7fff7f60a000 rw-p 00000000 00:00 0                          [stack]
7fff7f6dd000-7fff7f6df000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
SIGABRT: abort
PC=0x7f15b4816f77
signal arrived during cgo execution

runtime.cgocall(0x40c140, 0x7f15b536de70)
    /home/tv/src/go/src/pkg/runtime/cgocall.c:148 +0x116 fp=0x7f15b536de58
github.com/sbinet/go-python._Cfunc_free(0x7f15b5060ff0)
    /home/tv/tmp/go-build799516118/github.com/sbinet/go-python/_obj/_cgo_defun.c:2872 +0x31 fp=0x7f15b536de70
github.com/sbinet/go-python.func·001()
    /home/tv/go/src/github.com/sbinet/go-python/veryhigh.go:25 +0x70 fp=0x7f15b536de98
github.com/sbinet/go-python.Py_Main(0xc20800c000, 0x3, 0x3, 0x0)
    /home/tv/go/src/github.com/sbinet/go-python/veryhigh.go:29 +0x166 fp=0x7f15b536df20
main.main()
    /home/tv/go/src/github.com/sbinet/go-python/cmd/go-python/main.go:17 +0x44 fp=0x7f15b536df48
runtime.main()
    /home/tv/src/go/src/pkg/runtime/proc.c:231 +0x11a fp=0x7f15b536dfa0
runtime.goexit()
    /home/tv/src/go/src/pkg/runtime/proc.c:1438 fp=0x7f15b536dfa8
created by _rt0_go
    /home/tv/src/go/src/pkg/runtime/asm_amd64.s:97 +0x120

goroutine 17 [syscall]:
runtime.goexit()
    /home/tv/src/go/src/pkg/runtime/proc.c:1438

rax     0x0
rbx     0x0
rcx     0xffffffffffffffff
rdx     0x6
rdi     0x5e9c
rsi     0x5e9c
rbp     0x7fff7f6083e0
rsp     0x7fff7f6079a8
r8      0x0
r9      0x11
r10     0x8
r11     0x206
r12     0x4
r13     0x7
r14     0x7
r15     0x7fff7f607b50
rip     0x7f15b4816f77
rflags  0x206
cs      0x33
fs      0x0
gs      0x0
$ git stash pop -q
$ git diff
diff --git i/veryhigh.go w/veryhigh.go
index 96bf183..aa96c53 100644
--- i/veryhigh.go
+++ w/veryhigh.go
@@ -20,11 +20,6 @@ func Py_Main(args []string) int {
        for idx, arg := range args {
                argv[idx] = C.CString(arg)
        }
-       defer func() {
-               for idx, _ := range argv {
-                       C.free(unsafe.Pointer(argv[idx]))
-               }
-       }()
        return int(C.Py_Main(argc, &argv[0]))
 }

$ go build -o go-python.good ./cmd/go-python/main.go 
$ ./go-python.good -c 'print 1+1'
2
$ 

PyFloat_FromDouble should take a float64

// PyObject* PyFloat_FromDouble(double v)
// Return value: New reference.
// Create a PyFloatObject object from v, or NULL on failure.
func PyFloat_FromDouble(v float32) *PyObject {
return togo(C.PyFloat_FromDouble(C.double(v)))
}

PyErr_Fetch always causes a nil pointer exception

the code

func PyErr_Fetch() (exc, val, tb *PyObject) {
    C.PyErr_Fetch(&exc.ptr, &val.ptr, &tb.ptr)
    return
}

will always cause a nil pointer exception because of the deref of the pointer return values. is this intentional?

Python calls go function

In go source:
//------------------------------
type mdapi struct {
}
func (p *mdapi)add(){}
//------------------------------
how to call add function in python code ?

use ffi to handle C-varargs

The CPython API is using varargs a lot.

e.g.:
https://docs.python.org/2/c-api/arg.html

int PyArg_ParseTuple(PyObject *args, const char *format, ...);
int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *kw, const char *format, char *keywords[], ...);

consider using FFI (or github.com/gonuts/ffi) to marshal back and forth between C-varargs and Go-varargs-interface{} like is done in gopy:
https://github.com/qur/gopy/blob/master/lib/utils.c#L25
https://github.com/qur/gopy/blob/master/lib/arg.go#L89

Doesn't build with gccgo

I did a "go get" of the project but this failed to compile for all the reasons that are documented in the README.md. So having got the Git clone, I did the simple make install and that worked fine (albeit with a number of warnings): go-python.a appears in the appropriate place. However using:

make GO_COMPILER=gccgo install

I get the

(cd cmd/go-python && CGO_LDFLAGS="-L/usr/lib/python2.7 -lpython2.7" CGO_CFLAGS="-I/usr/include/python2.7 -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security " go install -compiler=gccgo .)

github.com/sbinet/go-python/cmd/go-python

./main.go:5:29: error: import file ‘github.com/sbinet/go-python’ not found
"github.com/sbinet/go-python"
^
./main.go:10:9: error: reference to undefined name ‘python’
err := python.Initialize()
^
./main.go:17:8: error: reference to undefined name ‘python’
rc := python.Py_Main(os.Args)
^
make: *** [install] Error 2

Almost certainly user error, but…

Thanks.

PS any move to Python 3 planned, Python 2 is so last millenium ;-)

Deployment docs

Great library! Do you happen to have documentation/suggestions for the optimal way to deploy a library using go-python to users? Thanks!

many undefined and error when compile

# github.com/sbinet/go-python
/usr/local/lib/libpython2.7.a(posixmodule.o): In function `posix_tmpnam':
/root/Python-2.7.13/./Modules/posixmodule.c:7614: warning: the use of `tmpnam_r' is dangerous, better use `mkstemp'
/usr/local/lib/libpython2.7.a(posixmodule.o): In function `posix_tempnam':
/root/Python-2.7.13/./Modules/posixmodule.c:7561: warning: the use of `tempnam' is dangerous, better use `mkstemp'
/usr/local/lib/libpython2.7.a(complexobject.o): In function `_Py_c_abs':
/root/Python-2.7.13/Objects/complexobject.c:214: undefined reference to `hypot'
/usr/local/lib/libpython2.7.a(complexobject.o): In function `_Py_c_pow':
/root/Python-2.7.13/Objects/complexobject.c:143: undefined reference to `hypot'
/root/Python-2.7.13/Objects/complexobject.c:144: undefined reference to `pow'
/root/Python-2.7.13/Objects/complexobject.c:145: undefined reference to `atan2'
/root/Python-2.7.13/Objects/complexobject.c:149: undefined reference to `sincos'
/root/Python-2.7.13/Objects/complexobject.c:148: undefined reference to `exp'
/root/Python-2.7.13/Objects/complexobject.c:149: undefined reference to `log'
/usr/local/lib/libpython2.7.a(complexobject.o): In function `complex_remainder':
/root/Python-2.7.13/Objects/complexobject.c:616: undefined reference to `floor'
/usr/local/lib/libpython2.7.a(complexobject.o): In function `complex_divmod':
/root/Python-2.7.13/Objects/complexobject.c:642: undefined reference to `floor'
/usr/local/lib/libpython2.7.a(floatobject.o): In function `float_is_integer':
/root/Python-2.7.13/Objects/floatobject.c:996: undefined reference to `floor'
/usr/local/lib/libpython2.7.a(floatobject.o): In function `float_as_integer_ratio':
/root/Python-2.7.13/Objects/floatobject.c:1748: undefined reference to `floor'
/usr/local/lib/libpython2.7.a(floatobject.o): In function `float_divmod':
/root/Python-2.7.13/Objects/floatobject.c:786: undefined reference to `floor'
/root/Python-2.7.13/Objects/floatobject.c:760: undefined reference to `fmod'
/usr/local/lib/libpython2.7.a(floatobject.o): In function `float_rem':
/root/Python-2.7.13/Objects/floatobject.c:728: undefined reference to `fmod'
/usr/local/lib/libpython2.7.a(floatobject.o): In function `_Py_double_round':
/root/Python-2.7.13/Objects/floatobject.c:1103: undefined reference to `round'
/root/Python-2.7.13/Objects/floatobject.c:1142: undefined reference to `floor'
/root/Python-2.7.13/Objects/floatobject.c:1156: undefined reference to `fmod'
/usr/local/lib/libpython2.7.a(floatobject.o): In function `float_pow':
/root/Python-2.7.13/Objects/floatobject.c:888: undefined reference to `floor'
/root/Python-2.7.13/Objects/floatobject.c:898: undefined reference to `fmod'
/root/Python-2.7.13/Objects/floatobject.c:863: undefined reference to `fmod'
/root/Python-2.7.13/Objects/floatobject.c:873: undefined reference to `fmod'
/root/Python-2.7.13/Objects/floatobject.c:922: undefined reference to `pow'
/usr/local/lib/libpython2.7.a(longobject.o): In function `PyLong_FromString':
/root/Python-2.7.13/Objects/longobject.c:1869: undefined reference to `log'
/usr/local/lib/libpython2.7.a(dynload_shlib.o): In function `_PyImport_GetDynLoadFunc':
/root/Python-2.7.13/Python/dynload_shlib.c:94: undefined reference to `dlsym'
/root/Python-2.7.13/Python/dynload_shlib.c:130: undefined reference to `dlopen'
/root/Python-2.7.13/Python/dynload_shlib.c:141: undefined reference to `dlsym'
/root/Python-2.7.13/Python/dynload_shlib.c:133: undefined reference to `dlerror'
/usr/local/lib/libpython2.7.a(signalmodule.o): In function `timeval_from_double':
/root/Python-2.7.13/./Modules/signalmodule.c:112: undefined reference to `floor'
/root/Python-2.7.13/./Modules/signalmodule.c:112: undefined reference to `floor'
/root/Python-2.7.13/./Modules/signalmodule.c:113: undefined reference to `fmod'
/root/Python-2.7.13/./Modules/signalmodule.c:113: undefined reference to `fmod'
/usr/local/lib/libpython2.7.a(posixmodule.o): In function `posix_forkpty':
posixmodule.c:(.text+0x273f): undefined reference to `forkpty'
/usr/local/lib/libpython2.7.a(posixmodule.o): In function `posix_openpty':
posixmodule.c:(.text+0x42f6): undefined reference to `openpty'
collect2: ld returned 1 exit status

when i run make install, it failed
is that my python version wrong, please help me?

base info:
centos6.2 x64
python-2.7.13
go version go1.7.4 linux/amd64

MemoryError

Hi

We are experiencing a MemoryError while running a function in Python from your go library. Increasing the amount of memory works fine to solve this issue when the Python is run directly. When run through this library we receive the MemoryError no matter how much we make available to the process. Is there some configuration which dictates the amount of memory Go is allocating for the Python process? If so can we change it?

Thanks for your help

python function retuan tuple type how to receive in my golang script

python

def callProcedure(prdocedureName,unixDate):
    os.environ['NLS_LANG'] = "American_America.AL32UTF8"
    try:
        conn = cx_Oracle.connect("tjlrm", "tjlrm", "172.168.171.200/xe")
        cursor = conn.cursor()
        asofdate = datetime.datetime.strptime(time.strftime("%Y-%m-%d", time.localtime(unixDate)), '%Y-%m-%d')
        param4 = cursor.var(cx_Oracle.BOOLEAN)  # plsql出参

        param5 = cursor.var(cx_Oracle.STRING)  # plsql出参

        # 调用存储过程
        cursor.callproc(prdocedureName, [asofdate,param4,param5])  # ['Nick', 'Nick, Good Morning!']

        return True,param4,param5.getvalue()
    except Exception as e:
        print("错误",e)
        return False,False,e.__str__()
    finally:
    # 资源关闭
        cursor.close()
        conn.close()```

how to get  `return True,param4,param5.getvalue()` Tuple  in my golang script? 

Function Calls Limited to 8 Arguments?

I run into this problem when trying to call Python functions that require more than 8 arguments:

panic: gopy: maximum number of varargs (8) exceeded (17)

Is there any particular reason for this? Would I just need to change _gopy_PyObject_CallFunction, _gopy_PyObject_CallMethod in go-python.c and L14 in go-python.h to get around this issue?

Issue about memory release

hello!
Recently I am using your api to call python methods. But I found a problem that has not been resolved, when I finished calling python's method. The memory did not come down. I'm not sure Whether my method is correct or not. The code is like belows:
`
func (this *TAiCall) SendSgfToPn(inMsg string, inBoardSize byte, outCArr *C.CArray) {

if outCArr == nil {
	return
}

var (
	res   *python.PyObject
	sgf   string
	value C.float
	index int = 0
	cc    *python.PyObject 
)

sgf = inMsg

if inBoardSize == 19 {
	if TensorPn19Call == nil {
		return
	}
	bArgs := python.PyTuple_New(1)
	cc = PyStr(sgf)
	python.PyTuple_SetItem(bArgs, 0, cc)
	res = TensorPn19Call.Call(bArgs, python.Py_None)
	
	if res == nil {
		return
	}

}

if inBoardSize == 13 {
	if TensorPn13Call == nil {
		return
	}
	bArgs := python.PyTuple_New(1)
	cc = PyStr(sgf)
	python.PyTuple_SetItem(bArgs, 0, cc)
	res = TensorPn13Call.Call(bArgs, python.Py_None)
	
	if res == nil {
		return
	}

}

size := python.PyList_Size(res)

for i := 0; i < size; i++ {
	res2 := python.PyList_GetItem(res, i)
	insize := python.PyList_Size(res2)
	for j := 0; j < insize; j++ {
		finaldata := python.PyList_GetItem(res2, j)
		value = C.float(python.PyFloat_AsDouble(finaldata))
		C.SetCArrayValue(outCArr, C.int(index), unsafe.Pointer(&value), C._Float)
		index++
		finaldata.Clear()
	}
	res2.Clear()
              
}

res.Clear()

return

}
`
And Memory Supervision is like this:
result

From the picture, we can see the memory increases madly. Can the Clear Method release the memory that the List occupied or is there another method to realize the GC?

Why not just use pkg-config?

Hi. I'm left a bit confused about the installation instructions; why go through all that trouble? It seems to work fine for me after this simple patch:

[0 tv@brute ~/go/src/github.com/sbinet/go-python]$ git diff
diff --git i/python.go w/python.go
index c0b9440..3373cf3 100644
--- i/python.go
+++ w/python.go
@@ -1,6 +1,7 @@
 // simplistic wrapper around the python C-API
 package python

+// #cgo pkg-config: python
 //#include "Python.h"
 //#include <stdlib.h>
 //#include <string.h>

Go get errors

$ go get github.com/sbinet/go-python

github.com/sbinet/go-python

could not determine kind of name for C._gopy_PyDict_CheckExact
could not determine kind of name for C.PyDict_GetItem
could not determine kind of name for C.PyDict_GetItemString
could not determine kind of name for C.PyDict_Values
could not determine kind of name for C.PyDict_MergeFromSeq2
could not determine kind of name for C.PyDict_New
could not determine kind of name for C.PyDict_Clear
could not determine kind of name for C.PyDict_Keys
could not determine kind of name for C.PyDict_Size
could not determine kind of name for C.PyDict_Next
could not determine kind of name for C.PyDict_Update
could not determine kind of name for C._gopy_PyDict_Check
could not determine kind of name for C.PyDictProxy_New
could not determine kind of name for C.PyDict_DelItem
could not determine kind of name for C.PyDict_Items
could not determine kind of name for C.PyDict_Contains

panic error by import turbodbc lib

System info:
MacOs Sierra
10.12.6

Error could not inport turbodbc

package main

import (
	"fmt"

	python "github.com/sbinet/go-python"
)

func init() {
	err := python.Initialize()
	if err != nil {
		panic(err.Error())
	}
}

func main() {
	turboExasol := python.PyImport_ImportModule("turbodbc")
	if turboExasol != nil {
		panic("could not inport turbodbc")
	}
	fmt.Printf("%v", turboExasol)
	connection := turboExasol.GetAttrString(`dsn=exasolution-io352fw_64`)
	if connection != nil {
		panic("could not get turbodbc(dsn=exasolution-io352fw_64)")
	}
	fmt.Printf(" %v", connection)
}

Issues about calling A python's method which return a wrong result

hello:
Recently,I came across an issue. when I try to call a python's method which was supposed to return a list whose elements were also list,like this [[1.23, 4.56]], but it return [].
My code shows below:
Golang:

var TensorCall *python.PyObject
func test() {
	sysModule := python.PyImport_ImportModule("sys")
	path := sysModule.GetAttrString("path")
	python.PyList_Insert(path, 0, PyStr(dir)) // python file's location
	m := python.PyImport_ImportModule(name)   //python file's name
	TensorCall = m.GetAttrString("tensorgo")  // method name in python file
	bArgs := python.PyTuple_New(2)
	python.PyTuple_SetItem(bArgs, 0, PyStr("arg1")) // arg, you can ignore
	python.PyTuple_SetItem(bArgs, 1, PyStr("arg2")) // arg, you can ignore
	res := TensorCall.Call(bArgs, python.Py_None)
	size := python.PyList_Size(res) - 1
	fmt.Println(python.PyList_Check(res))
	fmt.Println("size:", size)
}

python:

def tensorgo(s,sgf):
    return [[1.23, 4.56]]

Run the Golang Server, and call the func test(), output is:

true
size:0

I'm not sure whether my procedure is wrong or not. If you have any idea, please tell me. Thanks!

could not import 'kwargs'

excuse me
I'm run the example of kw-args and modify-values under the tests but error:
importing kwargs...
2017/10/14 05:47:31 could not import 'kwargs'
exit status 1

the other is the same

i'm ubuntu 16.04, Python 2.7.12, go 1.6

GoRoutines

This isn't goroutine safe is it?

Are you planning to add go-routine safe features if it is doable?

Thank you.

My preliminary tests crashed when I tried to access multiple URLs using go routines.

Installation instructions, python-all-dev

Hi there,

I successfully installed go-python on Debian (Unstable) after several tries, and want to mention that installing go-python per your instructions on the frontpage requires installing python-all-dev in order for make to work.

Best Regards,
Patrick

fdopen doesn't work on Windows

Write now in object.go it uses file.Fd and C.fdopen. Unfortunately, fdopen doesn't work on windows.

It seems to work for me if I exchange it with

// ...
name := C.CString(file.Name())
defer C.free(unsafe.Pointer(name))
C.fopen(name, cmode)
// ...

But I'm not confident it will always work. I'm not sure if anything can be done, AFAIK the WIndows equivalent to fdopen is pretty gnarly.

Linux RSS infintely increasing though go heap is empty

Hi,

I'm not sure what exactly is happening here but the resident memory occupied by the golang process never seems to get free though there is nothing in the heap. Here is a sample code:

package main

import python "github.com/sbinet/go-python"

func main() {
    initPython()

    for {
        //Infinite loop, make some data and create python dict
        message := createMessage()
        messageDict := getPyDict(message)
        messageDict.Clear()
    }
}

func createMessage() map[string]interface{} {
    payload := make(map[string]interface{})
    payload["key_1"] = "value_1"
    payload["key_2"] = "value_2"
    payload["key_3"] = "value_3"
    return payload
}

func getPyDict(message map[string]interface{}) *python.PyObject {
    messageDict := python.PyDict_New()
    for key, value := range message {
        pyKey := python.PyString_FromString(key)
        pyValue := python.PyString_FromString(value.(string))
        python.PyDict_SetItem(messageDict, pyKey, pyValue)
    }

    return messageDict
} 

func initPython() {
    //Init Python
    if err := python.Initialize(); err != nil {
          panic(err)
    }
}

The above script takes 1GB of RSS within a minute and the memory usage keeps increasing and doesn't seem to go down (golang heap is 0MB). Here are my local box details:

uname -a

Linux AE-LP-059 4.2.0-25-generic #30-Ubuntu SMP Mon Jan 18 12:31:50 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

go version

go version go1.6 linux/amd64

go env

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/mpoornima/Work/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"

Compiling kw-args in tests

Hi,

I am trying to run the kw-args code in the tests folder. I ran
go build
which created the kw-args file. When I run
./kw-args
I get the error
could not import 'kwargs'
Is there anything else I need to do for PyImport_ImportModule to import kwargs properly?

EDIT: I also tried #39 solution but that didn't work for me either

what does the cgoflags.go do?

Recently, I wrote a go program to call python 3.X code.I hava to declare the flowing code

//#cgo CFLAGS : -I./ -I/usr/include/python3.6
//#cgo LDFLAGS: -L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/usr/lib -lpython3.6m -lpthread -ldl  -lutil -lm
//#include "Python.h"
import "C"

And when I review your code, I do not know how you link to python.h and I can not find more answer when google.I think cgoflags.go is the keypoint, can you help me?

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.