Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cython c++ example fails to recognize c++, why?

Tags:

c++

python

cython

I'm attempting to build to the example for 'using c++ in cython' at the Cython C++ page, but setup appears not to recognize the language, c++.

The files, taken from that same page are:

Rectangle.cpp

#include "Rectangle.h"

using namespace shapes;

Rectangle::Rectangle(int X0, int Y0, int X1, int Y1){
    x0 = X0;
    y0 = Y0;
    x1 = X1;
    y1 = Y1;
}

Rectangle::~Rectangle() {}

int Rectangle::getLength() {
    return (x1 - x0);
}

int Rectangle::getHeight() {
    return (y1 - y0);
} 

int Rectangle::getArea() {
    return (x1 - x0) * (y1 - y0);
}

void Rectangle::move(int dx, int dy) {
    x0 += dx;
    y0 += dy;
    x1 += dx;
    y1 += dy;
}

Rectangle.h:

namespace shapes {
    class Rectangle {
    public:
    int x0, y0, x1, y1;
    Rectangle(int x0, int y0, int x1, int y1);
    ~Rectangle();
    int getLength();
    int getHeight();
    int getArea();
    void move(int dx, int dy);
    };
 } 

rectangle.pyx

cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
    Rectangle(int, int, int, int)
    int x0, y0, x1, y1
    int getLength()
    int getHeight()
    int getArea()
    void move(int, int)

cdef class PyRectangle:
    cdef Rectangle *thisptr      # hold a C++ instance which we're wrapping
    def __cinit__(self, int x0, int y0, int x1, int y1):
        self.thisptr = new Rectangle(x0, y0, x1, y1)
    def __dealloc__(self):
        del self.thisptr
    def getLength(self):
        return self.thisptr.getLength()
    def getHeight(self):
        return self.thisptr.getHeight()
    def getArea(self):
        return self.thisptr.getArea()
    def move(self, dx, dy):
        self.thisptr.move(dx, dy)

setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize(
       "rectangle.pyx",            # our Cython source
       sources=["Rectangle.cpp"],  # additional source file(s)
       language="c++",             # generate C++ code
      ))

I attempt to build this with:

python setup.py --build_ext --inplace

But this fails, with the error "Operation only allowed in c++" suggesting that the language="c++" option is not being passed correctly.

cython rectangle.pyx --cplus

does produce a c++ file, but I was hoping to be able to get the setup.py method to work.

The entire error text is:

Cythonizing rectangle.pyx

Error compiling Cython file:
------------------------------------------------------------
...
        void move(int, int)

cdef class PyRectangle:
    cdef Rectangle *thisptr      # hold a C++ instance which we're wrapping
    def __cinit__(self, int x0, int y0, int x1, int y1):
        self.thisptr = new Rectangle(x0, y0, x1, y1)
                      ^
------------------------------------------------------------

rectangle.pyx:13:27: Operation only allowed in c++

Error compiling Cython file:
------------------------------------------------------------
...
cdef class PyRectangle:
    cdef Rectangle *thisptr      # hold a C++ instance which we're wrapping
    def __cinit__(self, int x0, int y0, int x1, int y1):
        self.thisptr = new Rectangle(x0, y0, x1, y1)
    def __dealloc__(self):
        del self.thisptr
       ^
------------------------------------------------------------

rectangle.pyx:15:8: Operation only allowed in c++
Traceback (most recent call last):
  File "setup.py", line 8, in <module>
    language="c++",             # generate C++ code
  File "/Library/Python/2.7/site-packages/Cython-0.19.1-py2.7-macosx-10.8intel.egg/Cython/Build/Dependencies.py", line 753, in cythonize
    cythonize_one(*args[1:])
  File "/Library/Python/2.7/site-packages/Cython-0.19.1-py2.7-macosx-10.8intel.egg/Cython/Build/Dependencies.py", line 820, in cythonize_one
    raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: rectangle.pyx
like image 205
Rob Lachlan Avatar asked Aug 09 '13 19:08

Rob Lachlan


1 Answers

Following the example exactly, on a very similar system to yours, everything works fine for me.

But, along with a few other differences (an IndentationError, naming the file rectangle.pyx instead of rect.pyx, …) which turned out not to be relevant to this problem, you also left off this at the top of your Cython file:

# distutils: language = c++
# distutils: sources = Rectangle.cpp

And if I leave that off, I get the same error.

like image 150
abarnert Avatar answered Sep 27 '22 20:09

abarnert