[Cython] bug: constructor declarations not working

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Tue Aug 12 04:57:00 CEST 2014


Hi,

I want to declare and define C++ classes from Cython.  Sure, I could 
write them in native C++, but it's just small glue code, and I prefer to 
let Cython handle the GIL and all the other good stuff.

First, for reference, the following works (c.f. 
tests/run/cpp_classes_def.pyx):

== cython --cplus example1.pyx ============
cdef cppclass Foo "Foo":
   int _foo
   __init__(int foo) nogil:
     this._foo = foo
   __dealloc__() nogil:
     pass
===========================================

This will emit a declaration for Foo and the implementations of the 
constructor and destructor (output is truncated to show relevant parts 
only):

struct Foo {
   int _foo;
    Foo(int);
   virtual  ~Foo(void);
};
  Foo::Foo(int __pyx_v_foo) {
   this->_foo = __pyx_v_foo;
}
  Foo::~Foo(void) {
}

Now, I want to export the class to other cython files.  The following 
does not work, and I think it's a bug:

== example2.pxd ===========================
cdef extern cppclass Foo:
   int _foo
   __init__(int foo)
   __dealloc__()
===========================================

== cython --cplus example2.pyx ============
cdef cppclass Foo:
   __init__(int foo) nogil:
     this._foo = foo
   __dealloc__() nogil:
     pass
===========================================

== cython --cplus example3.pyx ============
from example2 cimport Foo

cdef Foo* foo_p = new Foo(2)
===========================================

This fails for example2 with an obscure error message:

$ cython --cplus example2.pyx
example2.pyx:3:8: undeclared name not builtin: this
...more spurious errors...

For example3, Cython runs through but trying to compile shows the actual 
problem (which you can also see in example2 if you shift things around a 
bit):

$ g++ -fPIC -shared -o example3.so -I /usr/include/python2.7 example3.cpp
example3.cpp: In function ‘void initexample3()’:
example3.cpp:775:38: error: no matching function for call to ‘Foo::Foo(int)’
    __pyx_v_8example3_foo_p = new Foo(2);

This is in the generated code:

/*--- Type declarations ---*/
struct Foo;
struct Foo {
   int _foo;
   virtual  ~Foo(void);
};

It's missing the constructor declaration!

I traced this a bit down the Compiler/Symtab.py and found this part in 
CppClassScope::declare_var:

4e07fc52 (Robert Bradshaw      2012-08-21 00:46:00 -0700 2112) 
if name != "this" and (defining or name != "<init>"):
4e07fc52 (Robert Bradshaw      2012-08-21 00:46:00 -0700 2113) 
    self.var_entries.append(entry)

Here defining is 0, so the declaration is skipped.  I don't know Cython 
internals, so I am hoping someone who does can fix this easily given the 
above information or point me in the right direction.

Thanks a lot for Cython, it's very useful!

Marcus Brinkmann


More information about the cython-devel mailing list