Skip to content

Instantly share code, notes, and snippets.

@michitux
Last active October 22, 2019 15:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save michitux/1650cd0e1474c8a59a14 to your computer and use it in GitHub Desktop.
Save michitux/1650cd0e1474c8a59a14 to your computer and use it in GitHub Desktop.
Simple example that shows a compilation problem with Cython (see error.log for the error message), fixedTest.pyx shows a workaround. anotherTest.pyx is another failing example.
# This file also fails to compile with error error: redefinition of ‘std::vector<int, std::allocator<int> > __pyx_convert_vector_from_py_int(PyObject*)’. Note that it only fails when I have another definition without the fused type.
from libcpp.vector cimport vector
cdef extern from "test.h":
cdef cppclass _TestClassInt "TestClass<int>":
vector[double] toDouble(const vector[int] &items) except +
cdef cppclass _TestClassChar "TestClass<char>":
vector[double] toDouble(const vector[char] &items) except +
ctypedef fused CharInt:
int
char
cdef class TestClass:
cdef _TestClassInt _thisInt
def toDouble(self, vector[int] items):
return self._thisInt.toDouble(items)
# This is actually what I want (with more useful code of course)
cdef class TestClass2:
cdef _TestClassInt _thisInt
cdef _TestClassChar _thisChar
def toDouble(self, vector[CharInt] items):
if CharInt is int:
return self._thisInt.toDouble(items)
else:
return self._thisChar.toDouble(items)
running build_ext
building 'test' extension
gcc -pthread -Wno-unused-result -DNDEBUG -fmessage-length=0 -grecord-gcc-switches -fstack-protector -O2 -Wall -D_FORTIFY_SOURCE=2 -funwind-tables -fasynchronous-unwind-tables -g -fPIC -I/usr/include/python3.3m -c test.cpp -o build/temp.linux-x86_64-3.3/test.o
test.cpp: In function ‘PyObject* __pyx_convert_vector_to_py_double(const std::vector<double>&)’:
test.cpp:1142:18: error: redefinition of ‘PyObject* __pyx_convert_vector_to_py_double(const std::vector<double>&)’
static PyObject *__pyx_convert_vector_to_py_double(const std::vector<double> &__pyx_v_v) {
^
test.cpp:1086:18: error: ‘PyObject* __pyx_convert_vector_to_py_double(const std::vector<double>&)’ previously defined here
static PyObject *__pyx_convert_vector_to_py_double(const std::vector<double> &__pyx_v_v) {
^
error: command 'gcc' failed with exit status 1
from libcpp.vector cimport vector
cdef extern from "test.h":
cdef cppclass _TestClassInt "TestClass<int>":
vector[double] toDouble(const vector[int] &items) except +
cdef class TestClassInt:
cdef _TestClassInt _this
def toDouble(self, vector[int] items):
return self._this.toDouble(items)
cdef extern from "test.h":
cdef cppclass _TestClassChar "TestClass<char>":
vector[double] toDouble(const vector[char] &items) except +
cdef class TestClassChar:
cdef _TestClassChar _this
def toDouble(self, vector[char] items):
return self._this.toDouble(items)
from distutils.core import setup
from setuptools import Extension
from Cython.Build import cythonize
setup(ext_modules = cythonize([Extension("*", ["*.pyx"], language = "c++")]))
#include <vector>
template<typename Item>
class TestClass {
public:
std::vector<double> toDouble(const std::vector<Item> &items) {
std::vector<double> result(items.size());
for (size_t i = 0; i < items.size(); ++i) {
result[i] = (double)items[i];
}
return result;
}
};
from libcpp.vector cimport vector
cdef extern from "test.h":
cdef cppclass _TestClass "TestClass"[Item]:
vector[double] toDouble(const vector[Item] &items) except +
cdef class TestClassInt:
cdef _TestClass[int] _this
def toDouble(self, vector[int] items):
return self._this.toDouble(items)
cdef class TestClassChar:
cdef _TestClass[char] _this
def toDouble(self, vector[char] items):
return self._this.toDouble(items)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment