exceptions, the right way
Hi All,
I am new to Python C/API, I am trying to follow the official docs, but I am confused about raising and catching exceptions from an extension.
For the example provided at
Extending and Embedding the Python Interpreter 2. Defining New Types 2.1.2. Providing finer control over data attributes eg I don't seem to be able to catch the exceptions raised by the getsetters functions, the interpreter will just end up in an ugly crash. Something like:
try: del mynoddy.last except TypeError, e: print "Error: ", e
doesn't work. I understand that PyErr_SetString just sets the error and does not raises the exception.
Am I missing something?
I am using Python ver 2.6.6 on Windows.
Any advice is greatly appreciated, Lee
Lee wrote:
Hi All,
I am new to Python C/API, I am trying to follow the official docs, but I am confused about raising and catching exceptions from an extension.
For the example provided at
Extending and Embedding the Python Interpreter 2. Defining New Types 2.1.2. Providing finer control over data attributes eg I don't seem to be able to catch the exceptions raised by the getsetters functions, the interpreter will just end up in an ugly crash. Something like:
try: del mynoddy.last except TypeError, e: print "Error: ", e
doesn't work. I understand that PyErr_SetString just sets the error and does not raises the exception.
Am I missing something?
I am using Python ver 2.6.6 on Windows.
Any advice is greatly appreciated,
I'm not sure I understand what you want to do, but raising and catching exceptions in C is not hard:
You raise them by using one of the PyErr_Set*() APIs and return NULL/-1 from your function.
You catch them by checking for NULL/-1 returns and then asking the PyErr_Occurred() function to see whether an exception was set. If so, you can use one of the PyErr_*Matches() functions to determine whether you want to catch the exception or not. If not, you simply pass on the NULL/-1 return value to the higher level function in your call stack.
Resources:
http://docs.python.org/c-api/exceptions.html http://www.velocityreviews.com/forums/t647790-catching-python-exceptions-in-...
-- Marc-Andre Lemburg eGenix.com
Professional Python Services directly from the Source (#1, Nov 17 2011)
Python/Zope Consulting and Support ... http://www.egenix.com/ mxODBC.Zope.Database.Adapter ... http://zope.egenix.com/ mxODBC, mxDateTime, mxTextTools ... http://python.egenix.com/
::: Try our new mxODBC.Connect Python Database Interface for free ! ::::
eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 http://www.egenix.com/company/contact/
Thanks Marc-Andre,
If not, you simply pass on
the NULL/-1 return value to the higher level function in your call stack.
This is exactly my problem. What I am trying to do (and the example seems to show) is:
- define an new type.
- define getsetters functions.
- say, if one want to delete an attribute, one writes in the setter function:
if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute"); return -1; }
so, one expects that can do:
import noddy2 mynoddy = noddy2.Noddy(number=15) mynoddy.first = "a" try: del mynoddy.last except TypeError, e: print "Error: ", e
(passing the PyExc_TypeError to the interpreter). In my situation try/except is ignored and the interpreter crushes. Am I missing something?
Lee
Lee <l_armeanu@yahoo.co.nz> writes:
This is exactly my problem. What I am trying to do (and the example seems to show) is:
- define an new type.
- define getsetters functions.
- say, if one want to delete an attribute, one writes in the setter function:
if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute"); return -1; }
Does unchanged noddy2.c work correctly for you? (It seems to contain the exact check you are quoting.) Maybe you are compiling noddy2 with a compiler incompatible to the one used for building Python?
so, one expects that can do:
import noddy2 mynoddy = noddy2.Noddy(number=15) mynoddy.first = "a" try: del mynoddy.last except TypeError, e: print "Error: ", e
This should be possible, yes.
Lee, 17.11.2011 11:07:
I am new to Python C/API, I am trying to follow the official docs, but I am confused about raising and catching exceptions from an extension.
Just in case your actual goal is not to learn the C-API but to write code for it, you may want to take a look at Cython. It's a Python compiler that allows you to quickly write efficient C extensions for CPython without having to know the details of the underlying C-API.
Stefan
Lee, 17.11.2011 11:07:
I am new to Python C/API, I am trying to follow the official docs, but I am confused about raising and catching exceptions from an extension.
Just in case your actual goal is not to learn the C-API but to write code for it, you may want to take a look at Cython. It's a Python compiler that allows you to quickly write efficient C extensions for CPython without having to know the details of the underlying C-API.
Stefan
participants (5)
-
Hrvoje Niksic
-
Lee
-
M.-A. Lemburg
-
Stefan Behnel
-
Stefan Behnel