Cython: C class 'myclass' is declared but not defined

Viewed 663

I'm trying to create a module in Python that written with Cython. The module planned to use C++ library to provide this to diffrent Python and Cython modules.

The problem is:

(base) $ python setup.py build
Compiling queue/myqueue.pyx because it changed.
[1/1] Cythonizing queue/myqueue.pyx

Error compiling Cython file:
------------------------------------------------------------
...
# cython: language_level=3

from queue.myqueue import myclass
from queue.myqueue cimport myclass

cdef class myclass:
    ^
------------------------------------------------------------

queue/myqueue.pyx:6:5: C class 'myclass' is declared but not defined
Traceback (most recent call last):
  File "setup.py", line 11, in <module>
    setup(name="mymodule", ext_modules=cythonize([inumpy_queue]))
  File "site-packages/Cython/Build/Dependencies.py", line 1096, in cythonize
    cythonize_one(*args)
  File "site-packages/Cython/Build/Dependencies.py", line 1219, in cythonize_one
    raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: queue/myqueue.pyx

I created a small reproducer for the original problem.

topdir:
  setup.py
  queue/

queue directory:
  __init__.py
  myqueue.pxd
  myqueue.pyx

Files: setup.py

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

inumpy_queue = Extension(
    name="myqueue",
    sources=['queue/myqueue.pyx'],
    language="c++"
)

setup(name="mymodule", ext_modules=cythonize([inumpy_queue]))

queue/__init__.py

print("called __init__.py")

queue/myqueue.pxd

# cython: language_level=3
cdef class myclass:
    cdef readonly int data

queue/myqueue.pyx

# cython: language_level=3

from queue.myqueue import myclass
from queue.myqueue cimport myclass

cdef class myclass:
    def __init__(self, shape):
        print("_____myclass::__init__()")

What i'm doing wrong? Thank you

2 Answers

The following lines should be removed from queue/myqueue.pyx:

from queue.myqueue import myclass
from queue.myqueue cimport myclass

cdef declarations of class fields should be in pxd files only. def declarations should be in pyx files only. As your pyx and pxd files represent one Cython module then it is not necessary to import/cimport pxd into pyx.

Also, in setup.py extension name should be queue.myqueue in order to place Cython module myqueue in folder queue.

Also, I use pip install -e . for building Cython module. After that I can use:

from queue.myqueue import myclass
c = myclass(1)

This seems to be related to distutils. Calling cythonize on the command-line works nicely.

In the pyx importing myqueue.myclass without the package prefix works:

from myqueue import myclass
from myqueue cimport myclass
Related