[Cython] Compiler crash: forward declaration of cdef class with "public" attributes

Robert Bradshaw robertwb at gmail.com
Wed Jul 23 08:42:24 CEST 2014


On Tue, Jul 8, 2014 at 4:34 PM, Alok Singhal <gandalf013 at gmail.com> wrote:
> Hi,
>
> I am getting a compiler crash with the following code:
>
> $ cat foo.pxd
> cdef class Foo:
>     cdef public object x
> $ cat foo.pyx
> cdef class Foo
>
> cdef class Foo:
>     pass
> $ ./cython.py  foo.pyx
>
> Error compiling Cython file:
> ------------------------------------------------------------
> ...
> cdef class Foo
>     ^
> ------------------------------------------------------------
>
> foo.pyx:1:5: Compiler crash in AnalyseDeclarationsTransform
>
> ModuleNode.body = StatListNode(foo.pyx:1:0)
> StatListNode.stats[0] = CClassDefNode(foo.pyx:1:5,
>     as_name = u'Foo',
>     class_name = u'Foo',
>     module_name = '',
>     visibility = 'private')
>
> Compiler crash traceback from this point on:
>   File "/Users/alok/Downloads/repos/cython.git/Cython/Compiler/Visitor.py",
> line 173, in _visit
>     return handler_method(obj)
>   File
> "/Users/alok/Downloads/repos/cython.git/Cython/Compiler/ParseTreeTransforms.py",
> line 1478, in visit_CClassDefNode
>     node.body.stats += stats
> AttributeError: 'NoneType' object has no attribute 'stats'
>
> The problem seems to be due to having a .pxd file with the attributes of the
> cdef class in it.  Since the attributes are declared "public", Cython is
> trying to generate property code for "Foo.x".  But it's trying to do that at
> the point of forward declaration in the .pyx file, instead of the definition
> of the class.
>
> An easy fix seems to be to change
> AnalyseDeclarationsTransform.visit_CClassDefNode in ParseTreeTransforms.py
> to check for node.body not being none.  I.e., the following patch seems to
> work:
>
> diff --git a/Cython/Compiler/ParseTreeTransforms.py
> b/Cython/Compiler/ParseTreeTransforms.py
> index f8c2efa..7811d56 100644
> --- a/Cython/Compiler/ParseTreeTransforms.py
> +++ b/Cython/Compiler/ParseTreeTransforms.py
> @@ -1466,7 +1466,7 @@ if VALUE is not None:
>
>      def visit_CClassDefNode(self, node):
>          node = self.visit_ClassDefNode(node)
> -        if node.scope and node.scope.implemented:
> +        if node.body and node.scope and node.scope.implemented:
>              stats = []
>              for entry in node.scope.var_entries:
>                  if entry.needs_property:
>
> Thanks,
> Alok

Thanks. https://github.com/cython/cython/commit/967c8e11da94ddae1ea7f1524f6beef2e030c4d9

FWIW, forward declarations should not generally be needed, and
certainly not needed if the class is already declared in a pxd file.


More information about the cython-devel mailing list