go-python/cpy3

Getting Error: "could not determine kind of name for C.PyEval_ReInitThreads"

Voben opened this issue · 15 comments

Voben commented

I am trying to use the PyRun_SimpleString function for a print hello world however I am getting the error below:

../../go/pkg/mod/github.com/go-python/cpy3@v0.2.0/thread.go:53:2: could not determine kind of name for C.PyEval_ReInitThreads

This is the code that I am running.

package main

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

func main() {

defer python3.Py_Finalize()
python3.Py_Initialize()
python3.PyRun_SimpleString("print('hello world')")

}

I am using Python 3.7.15 and have a python3,pc file.

what Python version are you using? This library currently only works with Python 3.7. This error usually happens when trying to use a newer version of Python.

It is possible to use newer version of Python if you remove some functions from go-python/cpy3 / datadog/go-python3 (bindings to stuff that has been removed from Python's C-API in newer version). For example, Python 3.8 works if you remove the bindings for PyEval_ReInitThreads, like I did here. More stuff might need to get removed for Python 3.9 and newer.

Voben commented

So when I run 'python --version' in the terminal, it outputs 'Python 3.7.15.' Do I need to be on an earlier version?

How would I delete the bindings. Should I download the zip of that commit or should I edit the import?

what does pkg-config --modversion python3 say?

Voben commented

It returns 3.8 even though version is set to 3.7 and includedir to the python3.7m folder/directory that contains the Python.h file.

not sure why that is but you can likely get it to work by:

  • create a folder with a copy of the correct python3.pc file
  • explicitly set env var PKG_CONFIG_PATH to this path (i.e. export PKG_CONFIG_PATH=/path/to/my-dir

make sure the env var is set when you install this Go module and when you run go build.
(also there's a chance that you might already have a "bad" binary in your Go cache from the previous installation attempt, here go clean -cache and go clean -modcache should help).

btw what's your OS + OS version and how did you install Python 3.7?

Voben commented

So I edited the PKG_CONFIG_PATH var, I hadn't specified the pkg-config folder but just the directory it is in. Running pkg-config --modversion python3 now returns 3.7 as intended. After running the go clean -cache and go clean -modcache commands go build returns this error instead (which I have encountered before but thought I had solved by specifiying the includedir in the python3.pc file):

../../go/pkg/mod/github.com/go-python/cpy3@v0.2.0/boolean.go:11:10: fatal error: Python.h: No such file or directory

And I'm running it on a WSL Ubuntu 20.04 and I believe I had installed Python using the command sudo apt install python3.7.

I just tried on a vanilla Ubuntu 20.04 container and this worked for me (can't think of anything that shouldn't also be working on WSL):

docker run --name ub1 --hostname ub1 -ti ubuntu:20.04

and in the Ubuntu 20.04 bash shell run (all as root):

apt update
apt install wget vim
apt install git #for go get/install
apt install build-essential #gcc for cgo
apt install pkg-config #for cgo to find python includes
apt install software-properties-common #for add-apt-repository


# install latest Go (distro packages are outdated)
cd $HOME
mkdir Downloads
cd Download
wget https://go.dev/dl/go1.19.3.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.19.3.linux-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/bin/go

# install py 3.7 from ppa (as no distro packages for Py 3.7)
add-apt-repository ppa:deadsnakes/ppa
apt install python3.7 python3.7-dev

# we explicitly need a "python3.pc" (not "python-3.7m.pc" or so)!
cp /usr/lib/x86_64-linux-gnu/pkgconfig/python-3.7m.pc /usr/lib/x86_64-linux-gnu/pkgconfig/python3.pc
# at this point a "pkg-config --list-all" should now show a record exactly named "python3"

# create a Go test program that uses go-python/cpy3:
cd $HOME
mkdir hello
cd hello
go mod init hello
vi main.go

contents of main go:

package main

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

func main() {

        defer python3.Py_Finalize()
        python3.Py_Initialize()
        python3.PyRun_SimpleString("print('hello from python in go')")

}

and back in the Ubuntu shell:

#this adds the go-python/cpy3 dep to go.mod and downloads it
go mod tidy

Now run the program:

go run .

Result:

$ root@ub1:~/hello# go run .
hello from python in go

one more note: Instead of installing from the ppa deadsnakes repo you could also build Python 3.7 from source. Here's an example on Debian, it should be very similar on Ubuntu:
#18 (comment)

Voben commented

Quick question, is there an advantage to building Python 3.7 from source rather than using deadsnakes?

technically probably not much difference. (More control and you don’t have to trust a third party package repo).

Voben commented

I'm setting up the docker container as you did, to as closely as possible trace your steps, and with the command cp /usr/lib/x86_64-linux-gnu/pkgconfig/python-3.7m.pc /usr/lib/x86_64-linux-gnu/pkgconfig/python3.pc, I am getting the error cp: cannot stat '/usr/lib/x86_64-linux-gnu/pkgconfig/python3.7m.pc': No such file or directory.

did you install python3.7-dev ?

Voben commented

I found the issue, it was a stupid mistake in the directory that I missed. Continued with the rest of the commands and it worked!

Thank you so much for your help and time, I appreciate it so much!

glad it works :)