[Pyrex] Handling exception when embedding
Franck Pommereau
pommereau at univ-paris12.fr
Sat Nov 17 19:17:44 CET 2007
Dear all,
I'm trying to use Pyrex in order to embed Python modules into C
applications. I have problems to retrieve the information related to
exceptions from the C program (typically the name and message of the
exception).
Is there a standard way to do that?
Below is some stripped down code that causes an error (which is
unfortunately not the exact error I get with the module I really use,
but maybe if I can get a fix for this example, I'll be able to fix the
real code).
Let's say I have the following Python module:
# foo.py ###################################
import sys
class Foo :
def __init__ (self, name) :
self.name = name
def hello (self) :
print self.name, "says: hello", sys.argv[1]
return 1
# end ######################################
I have the following Pyrex wrapper:
# cfoo.pyx #################################
cdef extern from "Python.h":
void Py_Initialize()
void Py_Finalize()
void PySys_SetArgv(int argc, char **argv)
cdef extern void initcfoo()
cdef public void cfoo_initialize (int argc, char **argv) :
Py_Initialize()
PySys_SetArgv(argc, argv)
initcfoo()
cdef public void cfoo_finalize () :
Py_Finalize()
import sys
_error = ""
cdef public char *error () :
global _error # in order to keep the Python str alive
try :
t, v, s = sys.exc_info()
_error = ("%s: %s" % (str(t.__name__), str(v))).strip()
except Exception, e : # see below why I need that
_error = "*** %s: %s ***" % (e.__class__.__name__, str(e))
return _error
import foo
cdef public object new_Foo (char *name) :
return foo.Foo(name)
cdef public int Foo_hello (object self) :
return self.hello()
# end ######################################
Then the following C program uses to module:
/* tester.c *******************************/
#include <Python.h>
#include "cfoo.h"
int main(int argc, char **argv) {
PyObject *f;
int i;
cfoo_initialize(argc, argv);
f = new_Foo("test");
i = Foo_hello(f);
if (i != 1) {
printf("\n%s\n", error());
}
cfoo_finalize();
return 0;
}
/* end *************************************/
When I compile and execute with no argument (so that sys.argv[1] does
not exist), I get the following message:
*** AttributeError: 'NoneType' object has no attribute '__name__' ***
Apparently sys.exc_info() returned (None, None, None).
On my real application (much more complex), the function error fails on
sys.exc_info() and I have the message:
*** NameError: sys ***
I discovered that I could work around by adding the line:
sys = __import__("sys")
before to call sys.exc_info() but then, I still retrieve None as the
current exception...
I've also discovered that with functions that return nothing (void), my
function error works correctly.
I have no idea about what's going on. I should mention that I'm not a C
programmer and I could not really understand the code generated by Pyrex.
Any idea around?
Thanks in advance for help...
Franck
More information about the Pyrex
mailing list