<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--Converted with LaTeX2HTML 98.2 beta6 (August 14th, 1998)
original version by:  Nikos Drakos, CBLU, University of Leeds
* revised and updated by:  Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
  Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<HTML>
<HEAD>
<TITLE>1.3 Exceptions </TITLE>
<META NAME="description" CONTENT="1.3 Exceptions ">
<META NAME="keywords" CONTENT="api">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<LINK REL="STYLESHEET" HREF="api.css">
<LINK REL="next" HREF="embedding.html">
<LINK REL="previous" HREF="objects.html">
<LINK REL="up" HREF="intro.html">
<LINK REL="next" HREF="embedding.html">
</HEAD>
<BODY bgcolor="#ffffff">
<div class=navigation>
<table align=center width="100%" cellpadding=0 cellspacing=2>
<tr>
<td><A HREF="embedding.html"><img width=32 height=32 align=bottom border=0 alt="next"
 src="../icons/next.gif"></A></td>
<td><A HREF="intro.html"><img width=32 height=32 align=bottom border=0 alt="up"
 src="../icons/up.gif"></A></td>
<td><A HREF="types.html"><img width=32 height=32 align=bottom border=0 alt="previous"
 src="../icons/previous.gif"></A></td>
<td align=center bgcolor="#99CCFF" width="100%">
 <b class=title>Python/C API Reference Manual</b></td>
<td><A HREF="contents.html"><img width=32 height=32 align=bottom border=0 alt="contents"
 src="../icons/contents.gif"></A></td>
<td><img width=32 height=32 align=bottom border=0 alt=""
 src="../icons/blank.gif"></td>
<td><A HREF="genindex.html"><img width=32 height=32 align=bottom border=0 alt="index"
 src="../icons/index.gif"></A></td>
</tr></table><b class=navlabel>Next:</b> <span class=sectref><A HREF="embedding.html">1.4 Embedding Python</A></span>
<b class=navlabel>Up:</b> <span class=sectref><A HREF="intro.html">1. Introduction</A></span>
<b class=navlabel>Previous:</b> <span class=sectref><A HREF="types.html">1.2.2 Types</A></span>
<br><hr></div>
<!--End of Navigation Panel-->

<H1><A NAME="SECTION003300000000000000000"></A>
<BR>
1.3 Exceptions 
</H1>

<P>
The Python programmer only needs to deal with exceptions if specific 
error handling is required; unhandled exceptions are automatically 
propagated to the caller, then to the caller's caller, and so on, till 
they reach the top-level interpreter, where they are reported to the 
user accompanied by a stack traceback.

<P>
For C programmers, however, error checking always has to be explicit.  
All functions in the Python/C API can raise exceptions, unless an 
explicit claim is made otherwise in a function's documentation.  In 
general, when a function encounters an error, it sets an exception, 
discards any object references that it owns, and returns an 
error indicator -- usually <tt>NULL</tt> or <tt>-1</tt>.  A few functions 
return a Boolean true/false result, with false indicating an error.
Very few functions return no explicit error indicator or have an 
ambiguous return value, and require explicit testing for errors with 
<tt class=cfunction>PyErr_Occurred()</tt>.

<P>
Exception state is maintained in per-thread storage (this is 
equivalent to using global storage in an unthreaded application).  A 
thread can be in one of two states: an exception has occurred, or not.
The function <tt class=cfunction>PyErr_Occurred()</tt> can be used to check for
this: it returns a borrowed reference to the exception type object
when an exception has occurred, and <tt>NULL</tt> otherwise.  There are a
number of functions to set the exception state:
<tt class=cfunction>PyErr_SetString()</tt> is the most common (though not the most
general) function to set the exception state, and
<tt class=cfunction>PyErr_Clear()</tt> clears the exception state.

<P>
The full exception state consists of three objects (all of which can 
be <tt>NULL</tt>): the exception type, the corresponding exception 
value, and the traceback.  These have the same meanings as the Python 
object <tt>sys.exc_type</tt>, <tt>sys.exc_value</tt>, 
<tt>sys.exc_traceback</tt>; however, they are not the same: the Python 
objects represent the last exception being handled by a Python 
<tt class=keyword>try</tt> ... <tt class=keyword>except</tt> statement, while the C level
exception state only exists while an exception is being passed on
between C functions until it reaches the Python interpreter, which
takes care of transferring it to <tt>sys.exc_type</tt> and friends.

<P>
Note that starting with Python 1.5, the preferred, thread-safe way to 
access the exception state from Python code is to call the function 
<tt class=function>sys.exc_info()</tt>, which returns the per-thread exception state 
for Python code.  Also, the semantics of both ways to access the 
exception state have changed so that a function which catches an 
exception will save and restore its thread's exception state so as to 
preserve the exception state of its caller.  This prevents common bugs 
in exception handling code caused by an innocent-looking function 
overwriting the exception being handled; it also reduces the often 
unwanted lifetime extension for objects that are referenced by the 
stack frames in the traceback.

<P>
As a general principle, a function that calls another function to 
perform some task should check whether the called function raised an 
exception, and if so, pass the exception state on to its caller.  It 
should discard any object references that it owns, and returns an 
error indicator, but it should <i>not</i> set another exception --
that would overwrite the exception that was just raised, and lose
important information about the exact cause of the error.

<P>
A simple example of detecting exceptions and passing them on is shown 
in the <tt class=cfunction>sum_sequence()</tt> example above.  It so happens that
that example doesn't need to clean up any owned references when it
detects an error.  The following example function shows some error
cleanup.  First, to remind you why you like Python, we show the
equivalent Python code:

<P>
<dl><dd><pre class=verbatim>
def incr_item(dict, key):
    try:
        item = dict[key]
    except KeyError:
        item = 0
    return item + 1
</pre></dl>

<P>
Here is the corresponding C code, in all its glory:

<P>
<dl><dd><pre class=verbatim>
int incr_item(PyObject *dict, PyObject *key)
{
    /* Objects all initialized to NULL for Py_XDECREF */
    PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
    int rv = -1; /* Return value initialized to -1 (failure) */

    item = PyObject_GetItem(dict, key);
    if (item == NULL) {
        /* Handle KeyError only: */
        if (!PyErr_ExceptionMatches(PyExc_KeyError)) goto error;

        /* Clear the error and use zero: */
        PyErr_Clear();
        item = PyInt_FromLong(0L);
        if (item == NULL) goto error;
    }

    const_one = PyInt_FromLong(1L);
    if (const_one == NULL) goto error;

    incremented_item = PyNumber_Add(item, const_one);
    if (incremented_item == NULL) goto error;

    if (PyObject_SetItem(dict, key, incremented_item) &lt; 0) goto error;
    rv = 0; /* Success */
    /* Continue with cleanup code */

 error:
    /* Cleanup code, shared by success and failure path */

    /* Use Py_XDECREF() to ignore NULL references */
    Py_XDECREF(item);
    Py_XDECREF(const_one);
    Py_XDECREF(incremented_item);

    return rv; /* -1 for error, 0 for success */
}
</pre></dl>

<P>
This example represents an endorsed use of the <tt class=keyword>goto</tt> statement 
in C!  It illustrates the use of
<tt class=cfunction>PyErr_ExceptionMatches()</tt> and <tt class=cfunction>PyErr_Clear()</tt> to
handle specific exceptions, and the use of <tt class=cfunction>Py_XDECREF()</tt> to
dispose of owned references that may be <tt>NULL</tt> (note the "<tt class=samp>X</tt>" in
the name; <tt class=cfunction>Py_DECREF()</tt> would crash when confronted with a
<tt>NULL</tt> reference).  It is important that the variables used to hold
owned references are initialized to <tt>NULL</tt> for this to work;
likewise, the proposed return value is initialized to <tt>-1</tt>(failure) and only set to success after the final call made is
successful.

<P>
<p>
<div class=navigation><hr><table align=center width="100%" cellpadding=0 cellspacing=2>
<tr>
<td><A HREF="embedding.html"><img width=32 height=32 align=bottom border=0 alt="next"
 src="../icons/next.gif"></A></td>
<td><A HREF="intro.html"><img width=32 height=32 align=bottom border=0 alt="up"
 src="../icons/up.gif"></A></td>
<td><A HREF="types.html"><img width=32 height=32 align=bottom border=0 alt="previous"
 src="../icons/previous.gif"></A></td>
<td align=center bgcolor="#99CCFF" width="100%">
 <b class=title>Python/C API Reference Manual</b></td>
<td><A HREF="contents.html"><img width=32 height=32 align=bottom border=0 alt="contents"
 src="../icons/contents.gif"></A></td>
<td><img width=32 height=32 align=bottom border=0 alt=""
 src="../icons/blank.gif"></td>
<td><A HREF="genindex.html"><img width=32 height=32 align=bottom border=0 alt="index"
 src="../icons/index.gif"></A></td>
</tr></table><b class=navlabel>Next:</b> <span class=sectref><A HREF="embedding.html">1.4 Embedding Python</A></span>
<b class=navlabel>Up:</b> <span class=sectref><A HREF="intro.html">1. Introduction</A></span>
<b class=navlabel>Previous:</b> <span class=sectref><A HREF="types.html">1.2.2 Types</A></span>
</div>
<!--End of Navigation Panel-->
<ADDRESS>
<hr>Send comments on this document to <a href="mailto:python-docs@python.org">python-docs@python.org</a>.
</ADDRESS>
</BODY>
</HTML>
