Trying Pypy ...

Hi all,
I was experimenting with Pypy the other day and surprised that both Cocos2D and Pyglet seem to work with it now.

I had a go building a panda3d WHL with Pypy - it did build, but was a CPython WHL. Any idea what I’d need to do to try and build using pypy ?

I’m fairly certain that there will be things that don’t work, but then I can report those as bugs back to pypy.

Cheers
S

Panda3D uses a homegrown tool called Interrogate to generate the Python bindings using the Python C extension API. From my understanding, this API causes problems for PyPy, and cffi should be used instead. Interrogate supports multiple output modes, so a cffi output could be added to Interrogate.

That being said, your actual question is on the WHL, not the bindings. Did you execute makepanda with PyPy?

I did run makepanda under pypy, it seemed to generate a standard whl.

Interogate generating CFFI code is definitely the best way to go, apart from compatibility, this will be faster in Pypy.

I was just curious to see if Pypys CPython compatibility is good enough to run Panda3D as is.

Looks like makewheel assumes CPython if the version is less than 3.0: github.com/panda3d/panda3d/blob … eel.py#L35

Are you using a Python 2 or a Python 3 version of PyPy? Also, have you tried renaming the wheel to us a PyPy tag? The wheel may just be named incorrectly.

Hi,
Apologies for the delay, have been away and wanted to take the time to write a useful reply.

I grabbed pypy 3.5 nightly using a script [1] + used it to build the WHL:

$ python makepanda/makepanda.py --everything --wheel --no-egl --no-gles --no-gles2 --no-opencv --threads=8

The first thing was working out what to rename the whl to - here is how to list the platforms

$ python -c "import pip; print('\n'.join(['-'.join(platform) for platform in pip.pep425tags.get_supported()]))" | sort
pp3510-none-any
pp3510-none-linux_x86_64
pp3510-none-manylinux1_x86_64
pp3510-pypy3_510-linux_x86_64
pp3510-pypy3_510-manylinux1_x86_64
pp3-none-any
py350-none-any
py3510-none-any
py351-none-any
py352-none-any
py353-none-any
py354-none-any
py355-none-any
py356-none-any
py357-none-any
py358-none-any
py359-none-any
py3-none-any
py3-none-linux_x86_64
py3-none-manylinux1_x86_64

I made a copy (not fully knowing if the name was a good one) and installed:

$ cp panda3d-1.10.0-cp35-cp35m-linux_x86_64.whl panda3d-1.10.0-pp3510-pypy3_510-linux_x86_64.whl 
$ pip install ./panda3d-1.10.0-pp3510-pypy3_510-linux_x86_64.whl 
Processing ./panda3d-1.10.0-pp3510-pypy3_510-linux_x86_64.whl
Installing collected packages: panda3d
Successfully installed panda3d-1.10.0
$ python -c "from panda3d.core import *"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: /home/stu/.virtualenvs/pypy-nightly-py3.5/site-packages/panda3d/libp3interrogatedb.so.1.10: undefined symbol: PyExc_ImportError

This looks is not implemented in pypy yet, so I added a bug there [2].

Some other notes:

The WHL needs to be built with pypy, because the libraries inside are named after the platform building them e.g. “ai.pypy3-510-x86_64-linux-gnu.so”.

If the panda3d “built” directory had a subdirectory with the platform name it would make it easier when switching between different pythons (e.g. in virtualenvs).

[1] gist.github.com/stuaxo/5d4c0363 … d424abbba/
[2] bitbucket.org/pypy/pypy/issues/ … mporterror

TLDR

It was still finding the CPython include directory, fixing that hits some unimplemented bits in Pypy, see the bug there.

More info -

Trying to set the includedir to pypys found some bits makepanda could improve -

$ pypy3 makepanda/makepanda.py --everything --wheel --no-egl --no-gles --no-gles2 --no-opencv --threads=8 --python-incdir ~/.virtualenvs/pypy-nightly-py3.5/include --python-libdir ~/.virtualenvs/pypy-nightly-py3.5/libs
...
Couldn't find header file python3.5/Python.h

This is because cpython has keeps Python.h in include/python35m while Pypy keeps it in include.

makepanda should probably use python-config to find the include directory and not assume the subdirectory.

A bug in pypy that stops python-config working … hopefully this will be fixed though.

sysconfig.get_config_var('INCLUDEPY')

outputs the directory containing Python.h in both pythons.

It looks like some of the optimizations in py_panda.* makes some assumptions about some Python structures that don’t work with PyPy. Perhaps we could use #ifdef to detect whether PyPy is used and fall back to a different approach for PyPy.

We did use python-config in the past, but abandoned it when it caused serious problems for the Panda build. One of the problems was that it included flags like -DNDEBUG that we absolutely didn’t want to inherit from the Python build.

As for the ABI tag, makewheel.py uses get_config_var(‘SOABI’) to determine the proper ABI tag. What is this set to for your PyPy installation?