cythonize fails when given `setuptools.extension.Extension`
See original GitHub issueCalling cythonize
with an instance of setuptools.extension.Extension
raises an AttributeError
.
The cause is that setuptools.extension.Extension
subclasses distutils.extension.Extension
, which is defined as an old-style class. These types can be confirmed with:
import distutils.core.Extension
import types
import setuptools.extension.Extension
assert type(distutils.core.Extension) != types.TypeType
assert type(setuptools.extension.Extension) != types.TypeType
This behavior arises with:
setuptools == 28.7.0
cython == 0.25.1
This issue did not exist with earlier cython
versions.
Closer examination of the docstring of function cythonize
reveals that one should pass a list of Extension
objects:
As module list, pass either a glob pattern, a list of glob patterns or a list of
Extension objects. The latter allows you to configure the extensions separately
through the normal distutils options.
So, my usage was wrong. Indeed, passing a list
of Extension
objects avoids the error. Since this error did not exist in the past, and because I believe that I followed some example when I initially wrote the code to pass an extension itself, I wonder whether this case is supposed to be supported, or if not, whether it should be emphasized in the docstring. Tracing the cause took a long time, especially because I assumed that cythonize
was already properly called.
One workaround is to create a new-style subclass:
class Extension(setuptools.extension.Extension,object):
pass
This works fine. Traceback from dd/download.py
when object
is removed from the above subclass definition:
dd:python setup.py install --cudd --linetrace
compile Cython extensions with line tracing
Traceback (most recent call last):
File "setup.py", line 136, in <module>
run_setup()
File "setup.py", line 93, in run_setup
extensions = download.extensions(directives)
File "/path/dd/download.py", line 119, in extensions
v, compiler_directives=directives)
File "~/.virtualenvs/dev/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 809, in cythonize
aliases=aliases)
File "~/.virtualenvs/dev/lib/python2.7/site-packages/Cython/Build/Dependencies.py", line 648, in create_extension_list
elif isinstance(patterns, basestring) or not isinstance(patterns, collections.Iterable):
File "~/.virtualenvs/dev/lib/python2.7/abc.py", line 144, in __instancecheck__
return cls.__subclasscheck__(subtype)
File "~/.virtualenvs/dev/lib/python2.7/abc.py", line 180, in __subclasscheck__
if issubclass(subclass, scls):
File "~/.virtualenvs/dev/lib/python2.7/abc.py", line 180, in __subclasscheck__
if issubclass(subclass, scls):
File "/home/ioannis/.virtualenvs/dev/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "~/.virtualenvs/dev/lib/python2.7/site-packages/backports_abc.py", line 66, in __subclasshook__
mro = C.__mro__
AttributeError: class Extension has no attribute '__mro__'
The failure is due to the isinstance(patterns, collections.Iterable)
. It can be reproduced as follows:
import collections
from Cython.Build import cythonize
from setuptools.extension import Extension
a = Extension('foo', sources=['foo.pyx'])
isinstance([a], collections.Iterable) # works fine
isinstance(a, collections.Iterable) # raises `AttributeError`
I will report this issue also to setuptools
, though it seems to me that defining an old-style class is intentional there.
Issue Analytics
- State:
- Created 7 years ago
- Comments:9 (9 by maintainers)
Top GitHub Comments
This was happening in one virtualenv of mine, but not a fresh one (nor the global one). The answer is in the traceback (see OP):
The error can then be reproduced. I do not know whether this classifies as a bug of
backports_abc
.Thanks for fixing this issue.