Cython compiled C extension: ImportError: dynamic module does not define init function
Asked Answered
B

9

50

I have just compiled part of my C library as an extension using Cython, as a "proof of concept". I managed to hack the code (const correctnes problems etc aside), to finally get an extension built.

However, when I attempted to import the newly created extension, I got the following error:

ImportError: dynamic module does not define init function 

What am I doing wrong and how do I fix this?

I am using Cythn 0.11.2 and Python 2.6.5 on Ubuntu 10.0.4

Burks answered 6/11, 2011 at 2:21 Comment(1)
What command line did you use for generate the .c ? How did you compile it ?Dawna
P
77

I've found that a frequent cause of this problem is, when using a distutils setup file to compile the code, that the .pyx base name does not match the extension name, e.g:

ext = Extension(name='different', sources=['cython_ext.pyx']) # Won't work

To avoid the problem the extension name should be exactly the same, in this case, cython_ext.

Prickle answered 29/1, 2014 at 12:8 Comment(3)
Nice call. Does anyone know why this works, and why a different name does not?Sixpence
@Dologan, thanks, it helped! I want to make your answer more complete: the name can be nested like make.something.useful.cython_ext. The point is that the module name (word after the last point) should be the same as the name of the source file. I guess, it would be helpful to put such positive example in your answer.Gothicize
thank you thank you. Amazing that this many years later there still isn't a *&# error message that explains this.Deerhound
P
36

It appears that it's a bug/feature in Cython. I had the same thing, but simply added:

STUFF = "Hi"

to the top of my .pyx file and the issue went away. It appears if there is no global initialization (a cinit or setting a global variable), that the required initialization code isn't generated.

Passage answered 20/12, 2012 at 16:30 Comment(2)
Wow. I can't believe that actually worked, but it fixed the same bug in my library.Glennisglennon
Worked for me as wellUndersize
W
2

This is a very late answer - but I just had the same error, and mine went away when I used __cinit__ instead of __init__. I'm still learing about extension types so currently I do not know why this happens. :) (You can take a look at http://docs.cython.org/src/reference/extension_types.html#initialization-cinit-and-init) Hope this is useful to someone.

Wexford answered 3/12, 2012 at 5:25 Comment(1)
This is a very late comment, but I think this answer would relate to a cdef class rather than a module, so probably not the problem reported. However, I realise it's probably difficult to know what issue you were fixing at this stage...Footman
I
1

Another really late answer in my case I had accidentally called cython in a terminal that was running python2, while trying to use the generated library from a terminal that was on another python environment, using python3.

Using the same python version everywhere fixed it.

Iraidairan answered 15/4, 2018 at 19:18 Comment(0)
F
0

Likewise a late answer... but I kept finding my way back to this question in particular. It probably is related to the mismatched names issue that Dologan addresses.

What happened in my case was that I was adapting an example I'd gotten to work, and got the module does not define init function error. This was verified by using (e.g.)

nm -m build/lib.macosx-10.9-x86_64-2.7/myproj.so

In this command's output I searched for 'init' and found

000000000000c0d0 (__TEXT,__text) external _initexample

I had removed all instances of 'example' from my setup.py and .pyx file, but this persisted even after removing the extension from site-packages, removing the build and dist folders, etc. I finally found that the .cpp file being generated from my .pyx file was still referring to the class name in the example. Once I reran my setup.py, import works, and indeed the .so file includes

000000000000c0a0 (__TEXT,__text) external _initmyproj

Fenian answered 10/6, 2014 at 21:27 Comment(0)
T
0

I've also ran into this problem. Make sure that your Cython file contains at least one of the following:

  • a normal Python def
  • a normal Python class (not cdef class)
  • a line of Python initialization, eg. a=None or a logger load

Otherwise Cython won't generate a PyInit routine needed to load the module, and as such the module won't be importable by Python.

Trueman answered 20/12, 2020 at 18:19 Comment(1)
I can't get it to fail even with an empty pyx file. If you have an example of something that doesn't work it'd probably be useful to report it as a bug as github.com/cython/cython/issues.Footman
S
-1

This is solved by adding a doc-string to your functions.

Sulfate answered 21/1, 2018 at 9:56 Comment(1)
There is no reason that should help. Can you explain?Teheran
S
-1

I had the same error and was solved by running the main .py script in "Execute in a dedicated console " mode. Available in Tools - Preferences - Run.

Spook answered 15/11, 2018 at 9:39 Comment(0)
B
-1

I solve it by

def cinit(self): pass

Hope it helps.

Bauxite answered 19/11, 2019 at 5:17 Comment(1)
This sounds like you had a problem with a cdef class while this question is about modules. I'd be surprised if this was correct. Also note __cinit__ not cinit - the double underscores are used for special methods in Python.Footman

© 2022 - 2024 — McMap. All rights reserved.