aggdraw
aggdraw copied to clipboard
PyPy3.8 support
We can successfully install aggdraw on pypy3.7 (v7.3.7) and on CPython 3.8, but not pypy3.8 (v7.3.7). Does this output mean anything to anyone?
Preparing metadata (setup.py) ... done
Building wheels for collected packages: aggdraw
Building wheel for aggdraw (setup.py) ... error
ERROR: Command errored out with exit status 1:
command: /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d /tmp/pip-wheel-jk4w5it5
cwd: /tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/
Complete output (41 lines):
Trying freetype-config to find freetype library...
Using ctypes to find freetype library...
=== freetype found: '/usr'
running bdist_wheel
running build
running build_ext
building 'aggdraw' extension
creating build
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/agg2
creating build/temp.linux-x86_64-3.8/agg2/src
creating build/temp.linux-x86_64-3.8/agg2/font_freetype
gcc -pthread -DNDEBUG -O2 -fPIC -DVERSION=1.3.12 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/usr/include -I/usr/include/freetype -I/usr/include/freetype2 -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/include/pypy3.8 -c aggdraw.cxx -o build/temp.linux-x86_64-3.8/aggdraw.o
In file included from agg2/include/agg_conv_transform.h:23,
from aggdraw.cxx:81:
agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::transform(double*, double*) const’:
agg2/include/agg_trans_affine.h:254:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
254 | register double tx = *x;
| ^~
agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::inverse_transform(double*, double*) const’:
agg2/include/agg_trans_affine.h:262:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
262 | register double d = determinant();
| ^
agg2/include/agg_trans_affine.h:263:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
263 | register double a = (*x - m4) * d;
| ^
agg2/include/agg_trans_affine.h:264:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
264 | register double b = (*y - m5) * d;
| ^
aggdraw.cxx: At global scope:
aggdraw.cxx:269:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
269 | };
| ^
| |
| printfunc {aka int (*)(_object*, FILE*, int)}
aggdraw.cxx:310:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
310 | };
| ^
| |
| printfunc {aka int (*)(_object*, FILE*, int)}
error: command 'gcc' failed with exit status 1
----------------------------------------
ERROR: Failed building wheel for aggdraw
Running setup.py clean for aggdraw
Failed to build aggdraw
Installing collected packages: aggdraw
Running setup.py install for aggdraw ... error
ERROR: Command errored out with exit status 1:
command: /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-7kzeod5l/install-record.txt --single-version-externally-managed --compile --install-headers /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include/site/python3.8/aggdraw
cwd: /tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/
Complete output (41 lines):
Trying freetype-config to find freetype library...
Using ctypes to find freetype library...
=== freetype found: '/usr'
running install
running build
running build_ext
building 'aggdraw' extension
creating build
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/agg2
creating build/temp.linux-x86_64-3.8/agg2/src
creating build/temp.linux-x86_64-3.8/agg2/font_freetype
gcc -pthread -DNDEBUG -O2 -fPIC -DVERSION=1.3.12 -DHAVE_FREETYPE2 -Iagg2/include -Iagg2/font_freetype -I/usr/include -I/usr/include/freetype -I/usr/include/freetype2 -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include -I/home/barnesc/.pyenv/versions/pypy3.8-7.3.7/include/pypy3.8 -c aggdraw.cxx -o build/temp.linux-x86_64-3.8/aggdraw.o
In file included from agg2/include/agg_conv_transform.h:23,
from aggdraw.cxx:81:
agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::transform(double*, double*) const’:
agg2/include/agg_trans_affine.h:254:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
254 | register double tx = *x;
| ^~
agg2/include/agg_trans_affine.h: In member function ‘void agg::trans_affine::inverse_transform(double*, double*) const’:
agg2/include/agg_trans_affine.h:262:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
262 | register double d = determinant();
| ^
agg2/include/agg_trans_affine.h:263:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
263 | register double a = (*x - m4) * d;
| ^
agg2/include/agg_trans_affine.h:264:25: warning: ISO C++17 does not allow ‘register’ storage class specifier [-Wregister]
264 | register double b = (*y - m5) * d;
| ^
aggdraw.cxx: At global scope:
aggdraw.cxx:269:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
269 | };
| ^
| |
| printfunc {aka int (*)(_object*, FILE*, int)}
aggdraw.cxx:310:1: error: invalid conversion from ‘printfunc’ {aka ‘int (*)(_object*, FILE*, int)’} to ‘Py_ssize_t’ {aka ‘long int’} [-fpermissive]
310 | };
| ^
| |
| printfunc {aka int (*)(_object*, FILE*, int)}
error: command 'gcc' failed with exit status 1
----------------------------------------
ERROR: Command errored out with exit status 1: /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/bin/python -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"'; __file__='"'"'/tmp/pip-install-_7xqrttx/aggdraw_bcd0f8bd313f41a4882c9a0461bd9edd/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /tmp/pip-record-7kzeod5l/install-record.txt --single-version-externally-managed --compile --install-headers /home/barnesc/.pyenv/versions/pypy3.8-7.3.7/envs/cm-pypy38/include/site/python3.8/aggdraw Check the logs for full command output
If I had to guess this is a bug or a change in the CPython API and something that has probably changed in PyPy. To define a python type in C/C++ you need a printfunc
in the object typedef. You can see it in the code here:
https://github.com/pytroll/aggdraw/blob/bd751fc2e27554c06736fa0e2db55a6eb2ee87ac/aggdraw.cxx#L305
It looks like aggdraw is trying to leave this undefined by casting a 0
to type printfunc
. Looks like this field is just there for Python 2 backwards compatibility though:
https://python.readthedocs.io/en/latest/c-api/typeobj.html#c.PyTypeObject.tp_print
You/we will need to find out what the proper way is to leave this field undefined. Maybe it should be set to NULL? But that doesn't really satisfy the Py_ssize_t
that PyPy is looking for. This makes me feel like this is a bug in PyPy, but that is a wild guess.
Thanks for the quick response! I suppose there's no interest in dropping support for a language version declared EOL nearly 2 years ago?
What do you mean? Dropping support for Python 2? I don't think we support it now. But that's not the point, this is the CPython C API. Their PyTypeObject struct includes a field for this. For binary compatibility it can't be removed, but I'm not sure what it should be to make PyPy happy.
To clarify a little more: this binary compatibility is not a aggdraw thing, this is a CPython thing.
Ah, misunderstood - I thought you meant something had been left in aggdraw for py2 compatibility. It does look like your travis config does run against 2.7 and 3.7; appveyor against 3.6 (EOL in a few days).
We haven't had any new commits for quite a while so the CI is pretty out of date. As for the state of the repository, the main
branch has unreleased changes as they switch to a newer version of the agg C++ library, but I found after merging the changes from the contributor who did it that the results are actually pretty different when used in real world cases (the test cases weren't complex enough). If you find a way to resolve the PyPy issue then it should be done from the maint/1.3
branch.
I still think the PyPy issue should be something related to a change in PyPy and not necessarily a bug in aggdraw. I'd be surprised if we are the only project running into this. I would expect the PyPy change to be documented but I'm not really sure where to dive in.