I'm fairly new to cython, so I have a basic question. I'm trying to import a base class from one cython file into another cython file to define a derived class. I have the following code in a single directory called cythonTest/
:
afile.pxd
afile.pyx
bfile.pxd
bfile.pyx
__init__.py
setup.py
afile.pxd:
cdef class A:
pass
afile.pyx:
cdef class A:
def __init__(self):
print("A__init__()")
bfile.pxd:
from afile cimport A
cdef class B(A):
pass
bfile.pyx:
cdef class B(A):
def __init__(self):
print "B.__init__()"
setup.py:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [Extension("afile", ["afile.pyx"]),
Extension("bfile", ["bfile.pyx"])]
setup(ext_modules=cythonize(extensions))
This code seems to compile correctly. Running import afile
works fine, but running import bfile
results in the following error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "bfile.pyx", line 1, in init cythonTest.bfile
cdef class B(A):
ImportError: No module named cythonTest.afile
Does anybody know what I'm doing wrong? I'm using Python 2.7.6 and Cython 0.27.3
One solution is to use explicit import. The minus side: you must install the package for it to work.
I have the following structure:
.
├── cythonTest
│ ├── afile.pxd
│ ├── afile.pyx
│ ├── bfile.pxd
│ ├── bfile.pyx
│ └── __init__.py
└── setup.py
The files:
cythonTest/afile.pxd
cdef class A:
pass
cythonTest/afile.pyx
cdef class A:
def __init__(self):
print("A__init__()")
cythonTest/bfile.pxd
cimport cythonTest.afile
cdef class B(cythonTest.afile.A):
pass
cythonTest/bfile.pyx
cimport cythonTest.afile
cdef class B(cythonTest.afile.A):
def __init__(self):
print "B.__init__()"
The init file is empty, it is only used to define the directory as a module.
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [Extension("cythonTest.afile", ["cythonTest/afile.pyx"]),
Extension("cythonTest.bfile", ["cythonTest/bfile.pyx"])]
setup(
packages=['cythonTest'],
ext_modules=cythonize(extensions),
)
You seem to be using cythonTest
as a package name (directory containing __init__.py
used as a package).
The module name needs to be reflected in the extension names for importing to work correctly:
extensions = [Extension("cythonTest.afile", ["cythonTest/afile.pyx"]),
Extension("cythonTest.bfile", ["cythonTest/bfile.pyx"])]
Will also probably need to move the pyx files under the package directory - Cython uses the package name when building the extensions.