question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

cython fails to compile pyx after version bump

See original GitHub issue

I currently use Cython 0.17 and have a large codebase in Cython that I want to upgrade to the latest version. From that codebase I extracted the following simple example to demonstrate the failure.

example.hpp:

#include <stdint.h>

class MyBool {
public:
  MyBool(void) : m_value(0) {}
  MyBool(bool value) : m_value(value) {}
  operator bool() const { return bool(m_value); }

private:
  uint8_t m_value;
}

example.pyx:

cdef extern from "example.hpp":
    cdef cppclass MyBool_c "MyBool"

cdef class MyBoolArray(object):
    def __getitem__(self, key):
        cdef MyBool_c* my_bool = <MyBool_c*>0
        my_bool[0] = <MyBool_c>(0)
        return <bint>(my_bool[0])

Until Cython=0.20, everything works fine. From 0.21 to 0.22 the following error occurs:

Error compiling Cython file:
------------------------------------------------------------
...

cdef class MyBoolArray(object):
    def __getitem__(self, key):
        cdef MyBool_c* my_bool = <MyBool_c*>0
        my_bool[0] = <MyBool_c>(0)
        return <bint>(my_bool[0])
                            ^
------------------------------------------------------------

example.pyx:8:29: Type 'MyBool_c' not acceptable as a boolean

Error compiling Cython file:
------------------------------------------------------------
...

cdef class MyBoolArray(object):
    def __getitem__(self, key):
        cdef MyBool_c* my_bool = <MyBool_c*>0
        my_bool[0] = <MyBool_c>(0)
        return <bint>(my_bool[0])
                            ^
------------------------------------------------------------

example.pyx:8:29: Cannot convert 'MyBool_c' to Python object

From 0.23 an on, I got a different crash:

Error compiling Cython file:
------------------------------------------------------------
...
    cdef cppclass MyBool_c "MyBool"

cdef class MyBoolArray(object):
    def __getitem__(self, key):
        cdef MyBool_c* my_bool = <MyBool_c*>0
        my_bool[0] = <MyBool_c>(0)
                    ^
------------------------------------------------------------

example.pyx:7:21: Compiler crash in AnalyseExpressionsTransform

ModuleNode.body = StatListNode(example.pyx:1:0)
StatListNode.stats[1] = CClassDefNode(example.pyx:4:5,
    as_name = u'MyBoolArray',
    class_name = u'MyBoolArray',
    module_name = u'',
    visibility = u'private')
CClassDefNode.body = StatListNode(example.pyx:5:4)
StatListNode.stats[0] = DefNode(example.pyx:5:4,
    modifiers = [...]/0,
    name = u'__getitem__',
    num_required_args = 2,
    py_wrapper_required = True,
    reqd_kw_flags_cname = '0',
    used = True)
File 'Nodes.py', line 430, in analyse_expressions: StatListNode(example.pyx:6:8,
    is_terminator = True)
File 'Nodes.py', line 4774, in analyse_expressions: SingleAssignmentNode(example.pyx:7:21)
File 'Nodes.py', line 4920, in analyse_types: SingleAssignmentNode(example.pyx:7:21)

Compiler crash traceback from this point on:
  File "/home/asaf/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Nodes.py", line 4920, in analyse_types
    op = env.lookup_operator_for_types(self.pos, '=', [self.lhs.type, self.rhs.type])
  File "/home/asaf/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Symtab.py", line 844, in lookup_operator_for_types
    return self.lookup_operator(operator, operands)
  File "/home/asaf/miniconda2/lib/python2.7/site-packages/Cython/Compiler/Symtab.py", line 829, in lookup_operator
    method = obj_type.scope.lookup("operator%s" % operator)
AttributeError: 'NoneType' object has no attribute 'lookup'

I also tried to read the changelog to see which change could lead for this kind of error, but I didn’t find anything. Any idea what could have happened or how the problem can be solved?

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
da-woodscommented, Mar 6, 2020

No but cdef MyBool_c* my_bool = <MyBool_c*>0 creates a NULL pointer and then my_bool[0] attempts to use that pointer.

I do agree with your suggestions on how to change it so it’ll compile. I just think it will crash when run.

0reactions
asafkahloncommented, Mar 6, 2020

I updated example.pyx to this:

cdef extern from "<stdint.h>" nogil:
    ctypedef unsigned char  uint8_t

from libcpp cimport bool as boolean

cdef extern from "example.hpp":
    cdef cppclass MyBool_c:
        MyBool()
        MyBool(boolean value)
        uint8_t m_value

cdef class MyBoolArray(object):
    def __getitem__(self, key):
        cdef MyBool_c* my_bool = <MyBool_c*>0
        my_bool[0] = <MyBool_c>(0)
        return <boolean> (my_bool[0])

This file works also on the newest version. Pay attention - I still got the second error if call the constructor directly as you suggested before. It works only with the original usage. Do you still think I should call the constructor directly? Should there be any difference?

Read more comments on GitHub >

github_iconTop Results From Across the Web

"local variable 'result' referenced before assignment" compiler ...
gevent fails to compile with cython 0.26 (observed on OS X, Windows and Linux): cython -o gevent.ares.c src/gevent/ares.pyx Error compiling ...
Read more >
build failure when cython files are not "cythonized" beforehand.
Cython version 0.14.1-1, Python 2.7, OSX. I have the following setup.py;. setup.py. ------------. from distutils.core import setup.
Read more >
pycapnp - PyPI
A cython wrapping of the C++ Cap'n Proto library. ... Added Python 3.4 to the travis build matrix; Bump version for bundled C++...
Read more >
Cython attemps to compile twice, and fails - Stack Overflow
It turns out the .pyx file contains a line # distutils: sources = Donline.cpp Handler.cpp Process.cpp Filter.cpp Localize.cpp.
Read more >
Cannot install moments using 'pip install'. - Bitbucket
The same failure is seen doing pip install . from the source folder. ... Compiling moments/LinearSystem_1D.pyx because it changed.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found