Cython assumes you have a functional Python interpreter running (i.e. that you are writing an extension module). In this case, you are embedding Python, rather than extending it. So you need to do some extra work to initialize everything.
Luckily, this is not really a challenging problem:
"""An experiment in shimming from Cython / Python."""
cdef extern from "dlfcn.h":
void* dlsym(void*, char*)
void* RTLD_NEXT
cdef extern from "Python.h":
void Py_Initialize() nogil
cdef extern void initpyshim()
cdef extern int execvp(const char *file, char *const argv[]) nogil: # note nogil here
Py_Initialize() # initialize Python
with gil:
initpyshim() # initialize containing module
print "Intercepted lookup of %r" % file
libc_execvp = dlsym(RTLD_NEXT, "execvp")
if libc_execvp:
with nogil:
return (<int(*)(const char*, char * const *) nogil>libc_execvp)(file, argv)
return -1
If your function may be called multiple times, you may want to avoid re-initializing your module (you can do this by checking Py_IsInitialized()
). You may also need to call Py_Finalize()
before leaving your method.
If you are targeting Python 3, the init method is called PyInit_<modname>
and returns a PyObject *
reference that you need to hold on to until the end of the method (at the very least).