pytroll / aggdraw

Python package wrapping AGG2 drawing functionality

Home Page:https://aggdraw.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PyPy3.8 support

clbarnes opened this issue · comments

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:

(printfunc)0, /* tp_print */

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.