C built and raised exceptions are not being catched in Python code

Vinko Vrsalovic vinko at cprsig.cl
Wed Feb 26 16:00:46 EST 2003


On Wed, Feb 26, 2003 at 01:53:09PM -0500, WP wrote:
> >
> >	- If I raise the C-built exception in Python code, I can catch it in
> >	  Python or C code.
> 
> >	- If I raise it in C code, I can only catch it in C code, the
> >	  except clause in Python code acts as if no exception was
> >	  raised.
> >
> >	Of course, I'd like to catch C raised exceptions in Python
> >	code also, but I don't see what might be failing.
> 
> 
> What do you mean, raise exception in C? Do you mean return a NULL from a 
> method in a C extension?
> In C you have return codes of NULL. Any time you return NULL, an exception 
> is raised. You set
> the exception type (global) and return NULL.


What do you mean by (global) there? That you can't raise it inside a C
implemented method? where should you raise it if you must raise it from
C?

I don't know if this can work, but this is what I'm doing: (sorry for
the length of this post).

In a C implemented function of a Python module, I do:


static PyObject* foo(...) {

...
if (1) { // 1 just for testing...
	PyErr_SetString(ChangeStatus,"done");
	return NULL;
}
...
}

Where ChangeStatus is an exception class built in another module, not the same
module where foo is.

Here is its definition:

exc_module = Py_InitModule("exc",ChgStMethods);
exc_module_dict = PyModule_GetDict(exc_module);
exc_dict = PyDict_New();
PyDict_SetItemString(exc_dict,"value",PyString_FromString(""));
ChangeStatus = PyErr_NewException("exc.ChangeStatus",NULL,exc_dict);
PyDict_SetItemString(exc_module_dict,"ChangeStatus",ChangeStatus);

for (def = ChgStMethods; def->ml_name != NULL; def++) {
        PyObject *func = PyCFunction_New(def, NULL);
	PyObject *method = PyMethod_New(func, NULL, ChangeStatus);
        PyDict_SetItemString(exc_module_dict, def->ml_name, method);
        Py_DECREF(func);
        Py_DECREF(method);
}


In ChgStMethods i defined __init__ and __str__ only.

and foo belongs to a module init'ed like this:

module = Py_InitModule("eva", EvaMethods);

In EvaMethods there is foo, and a few others.

According to what I've understood from the docs, that doesn't seem
wrong, but then, from C I call a Python script using PyImport and
PyObject_CallObject(), and the script contains:

import eva
import exc

def test():
	try:
		res = eva.foo(...)
	except Exception, e:
		print e.value
		return repr(e)


And the statements in the except clause don't get executed... but the
exception gets caught in a PyErr_Fetch() call that is made just after the
call to PyObject_CallObject() 

if the Python script is:

import eva
import exc

def test():
	try:
		exc.ChangeStatus.value = "hey"
		raise exc.ChangeStatus
	except Exception, e:
		print e.value
		return repr(e)

the statemens in the except clause get executed... and of course
PyErr_Fetch doesn't get any exception to catch.

As a side note, if I raise a built-in exception in foo, the except
clause in the first text() function also doesn't get executed, so I
think its the way I'm raising the exceptions from C that is wrong.

-- 
Vinko Vrsalovic <el[|- at -|]vinko.cl>
http://www.cprsig.cl





More information about the Python-list mailing list