What do I want to do: install a python/cython module exposing a c++ class and being able to cimport
it in any .pyx
files later.
What does not work: I cannot manage to cimport
the file once the module is installed. The cython compilation is working as I can use the wrapped class in pure python.
File structure:
├── cytest
│ ├── cywrappers
│ │ ├── cynode.pxd
│ │ └── cynode.pyx
│ └── hpp
│ └── node.hpp
└── setup.py
node.hpp:
#ifndef graph_HPP
#define graph_HPP
class Node
{
public:
int ID;
double value;
Node(){;};
Node(int tid, double tvalue)
{this->ID = tid; this->value = tvalue;}
void multiplicate(double num){this->value = this->value * num;}
};
#endif
cynode.pxd
cdef extern from "node.hpp":
cdef cppclass Node:
Node()
Node(int tid, double tvalue)
int ID
double value
void multiplicate(double num)
cynode.pyx
cimport cynode
cdef class pynode:
cdef cynode.Node c_node
def __cinit__(self, int tid, double tval):
self.c_node = cynode.Node(tid,tval)
def print_val(self):
print("ID: ", self.c_node.ID, "value: ", self.c_node.value)
def multiplicate(self, mul):
self.c_node.multiplicate(mul)
and the setup.py
:
from setuptools import setup, find_packages, Extension
from Cython.Distutils import build_ext
import numpy as np
setup(
name = "pycytest",
packages=find_packages(include=['cytest', 'cytest.*']),
package_data={'': ['*.pxd', '*.pyx', '*.hpp']},
zip_safe=False,
ext_modules=
[Extension("cytest.cywrappers.cynode",
sources = ["cytest/cywrappers/cynode.pyx"],
language="c++", extra_compile_args=["-O3", "-std=c++11"],
include_dirs=["./cytest/hpp/", np.get_include()])],
cmdclass = {'build_ext': build_ext}
)
I install with pip install .
and try to use it in a jupyter notebook
(from another location).
import cytest.cywrappers.cynode as cynode
node = cynode.pynode(5, 7.6)
node.print_val()
node.multiplicate(67)
node.print_val()
outputs as it should:
('ID: ', 5, 'value: ', 7.6)
('ID: ', 5, 'value: ', 509.2)
However if I try any of the lines bellow:
%%cython --cplus
# from cytest cimport cywrappers
# cimport cytest
# cimport cynode
I always get a 'XXX.pxd' not found
.
Anyone has a solution? I search for quite a long time and I am afraid I am not managing to find the right keywords.
I managed to get it to work:
pyx
pxd
imported the hpp
in relative import (cdef extern from "../hpp/node.hpp":
)package_data
to find and include all the files in the repository (needed to reuse the code in later pyx
), I added an empty __init__.py
in every directories.Now I can cimport cytest.cywrappers.cynode as cynode
.
I tried a lot of things, so all the edits are not relevant but here is a working setup.py
:
from setuptools import setup, find_packages, Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import numpy as np
extension = cythonize( [Extension("cytest.cywrappers.cynode",
sources = ["cytest/cywrappers/cynode.pyx"],
language="c++", extra_compile_args=["-O3", "-std=c++11"],
include_dirs=["./cytest/hpp/", np.get_include()])], compiler_directives = {"language_level": 3, "embedsignature": True})
setup(
name = "pycytest",
packages=find_packages(include=['cytest', 'cytest.cywrappers']),
package_data={"cytest": ["./*/*.pyx", "./*/*.pxd", "./*/*.hpp" ]},
zip_safe=False,
ext_modules=extension
,
cmdclass = {'build_ext': build_ext}
)