Reputation: 301
Here's my very simple cython program.
test/__init__.py
(Blank file)
test/__main__.py
(Main file)
from test.program import Program
Program.Main([])
test/program.pyx
from .example import *
from .example cimport *
class Program:
@staticmethod
def Main(args):
h = ExampleClass()
h.SayHi()
test/example.pyx
cdef class ExampleClass:
cdef SayHi(self):
print("HI")
test/example.pxd
cdef class ExampleClass:
cdef SayHi(self)
If I run this program by py36 test/__main__.py
, program outputs this incomprehensible error..
Traceback (most recent call last):
File "test\__main__.py", line 1, in <module>
from test.program import Program
File "test\program.pyx", line 1, in init test.program
from .example import *
TypeError: Cannot overwrite C type ExampleClass
If I modify the code
from .example import *
from .example cimport *
to one of following code blocks
from .example import ExampleClass
from .example cimport *
or
from .example import *
from .example cimport ExampleClass
or
from .example import ExampleClass
from .example cimport ExampleClass
, the error disappears and program runs nicely without error.
I can't really understand why original unmodified code outputs weird TypeError: Cannot overwrite C Type ExampleClass
..
Can someone please help me to understand the error and what the problem is?
Upvotes: 4
Views: 515
Reputation: 5270
In program.pyx
, both the Python module and Cython imports are used.
When the example.pyx
code is compiled, ExampleClass
has already been defined as a native type.
The python level import then instructs the python interpreter to load the python module containing ExampleClass
native type - note, not the Cython definition of it but the runtime python module.
As that type had already been declared at compile time by Cython with a fixed definition, it is seen as an attempt to re-declare a native type. That is what TypeError: Cannot overwrite C type ExampleClass
means.
In other words, the python level import is trying to re-declared a statically defined C extension class which is not allowed by Cython.
In short, remove from .example import <..>
lines from .pyx
files.
Python level imports are only needed when there are both Python only, as in a regular .py
file, and Cython only declarations that both need to be used - that is not the case above.
As a side note, relative imports are not supported by Cython's cimport
and also best not to use *
for imports. The relative cimport
code will break when installed as a package.
Upvotes: 1