10

I'm trying to write a binding for a vendor C++ library. I've successfully used snippets such as the below to define init functions in the other modules, but in this one it doesn't seem to work: it compiles fine, but throws the ImportError as soon as I try to import it into a test script. What could be wrong here?

#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC initclient(void) {

    PyObject* m;

    ClientType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&ClientType) < 0)
        return;

    m = Py_InitModule3("client", client_methods, "Client module");
    Py_INCREF(&ClientType);
    PyModule_AddObject(m, "Client", (PyObject *) &ClientType);

}

This is on 32-bit Linux, with gcc 4.4.4.

djc
  • 11,603
  • 5
  • 41
  • 54

8 Answers8

8

Make sure you don't mix Python versions. In Python version 2 the init function was called Init_, while in version 3 this function is called PyInit_

In my case this was happening when SWIG 3.0.2 used Python 3.4 to generate bindings, while my Python IDE called the Python 2.7 interpreter.

You can see the difference in the generated .cxx file:

#if PY_VERSION_HEX >= 0x03000000
#  define SWIG_init    PyInit__<modulename>

#else
#  define SWIG_init    init_<modulename>

#endif

On linux you can also use the following command to check your .so exports:

nm -D <modulename> | grep <modulename>

This will give you the name of the init function within your library.

Klaas
  • 81
  • 1
  • 1
  • The answer is spot on. Since I use `cmake` to automatically generate everything using SWIG all I had to change was `find_package(PythonLibs 2.7 REQUIRED)` in order to specify which version I want because the default (without version) was giving me the 3.5 and I landed in the situation described in this answer. – rbaleksandar Nov 07 '18 at 19:12
8

I had the same issue. At compile time:

  • path to the Python header: OK
  • path to the Python library: OK
  • link against the Python library: OK
  • link against needed third parties libraries/object files: OK

I just forgot to compile the C file that defines my module... Sigh...

So yeah, first thing to check: your makefile or your compilation command! :)

lin3
  • 81
  • 1
  • 2
  • You saved my day! I wrote my build script walk though all the src code path, but forget the main file.c, ...sigh – davyzhang Jun 28 '13 at 08:52
5

I had the same error message, but it was because I renamed my .c file, and forgot to update the name inside the code. The "initxxx" function and an argument inside it.

dividebyzero
  • 2,190
  • 1
  • 21
  • 33
1

Make sure you include your _wrap.cxx. It seems to me it doesn't get compiled into your module.

Jackie Lee
  • 239
  • 3
  • 3
0

On linux it can help to run strace in this case. Check that the name of the library python is searching for is the same as the name of the library you built.

demented hedgehog
  • 7,007
  • 4
  • 42
  • 49
0

The swig documentation mentions here:

This error is almost always caused when a bad name is given to the shared object file. For example, if you created a file example.so instead of _example.so you would get this error.

Andre Holzner
  • 18,333
  • 6
  • 54
  • 63
0

In the interface file, SWIG suggests using:

#define SWIG_FILE_WITH_INIT
-3

This turned to be unrelated to Python or the compiler, but was an incorrect compiler incantation (have to pay more attention while editing the Makefile).

djc
  • 11,603
  • 5
  • 41
  • 54
  • 24
    it would be great if you could include your solution for other people who have the same problem! – nont Sep 19 '11 at 01:57
  • 1
    @djc any extra info on you're solution? I'm stuck on this problem currently – Awalias Aug 12 '13 at 13:47
  • 1
    Sorry, I don't remember what the actual issue was, and I can't find relevant changes in my version control repository. – djc Aug 19 '13 at 16:59