Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / amd64 / html / python / api / exceptions.html
CommitLineData
920dae64
AT
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2<html>
3<head>
4<link rel="STYLESHEET" href="api.css" type='text/css' />
5<link rel="SHORTCUT ICON" href="../icons/pyfav.png" type="image/png" />
6<link rel='start' href='../index.html' title='Python Documentation Index' />
7<link rel="first" href="api.html" title='Python/C API Reference Manual' />
8<link rel='contents' href='contents.html' title="Contents" />
9<link rel='index' href='genindex.html' title='Index' />
10<link rel='last' href='about.html' title='About this document...' />
11<link rel='help' href='about.html' title='About this document...' />
12<link rel="next" href="embedding.html" />
13<link rel="prev" href="objects.html" />
14<link rel="parent" href="intro.html" />
15<link rel="next" href="embedding.html" />
16<meta name='aesop' content='information' />
17<title>1.3 Exceptions </title>
18</head>
19<body>
20<DIV CLASS="navigation">
21<div id='top-navigation-panel' xml:id='top-navigation-panel'>
22<table align="center" width="100%" cellpadding="0" cellspacing="2">
23<tr>
24<td class='online-navigation'><a rel="prev" title="1.2.2 Types"
25 href="types.html"><img src='../icons/previous.png'
26 border='0' height='32' alt='Previous Page' width='32' /></A></td>
27<td class='online-navigation'><a rel="parent" title="1. Introduction"
28 href="intro.html"><img src='../icons/up.png'
29 border='0' height='32' alt='Up One Level' width='32' /></A></td>
30<td class='online-navigation'><a rel="next" title="1.4 Embedding Python"
31 href="embedding.html"><img src='../icons/next.png'
32 border='0' height='32' alt='Next Page' width='32' /></A></td>
33<td align="center" width="100%">Python/C API Reference Manual</td>
34<td class='online-navigation'><a rel="contents" title="Table of Contents"
35 href="contents.html"><img src='../icons/contents.png'
36 border='0' height='32' alt='Contents' width='32' /></A></td>
37<td class='online-navigation'><img src='../icons/blank.png'
38 border='0' height='32' alt='' width='32' /></td>
39<td class='online-navigation'><a rel="index" title="Index"
40 href="genindex.html"><img src='../icons/index.png'
41 border='0' height='32' alt='Index' width='32' /></A></td>
42</tr></table>
43<div class='online-navigation'>
44<b class="navlabel">Previous:</b>
45<a class="sectref" rel="prev" href="types.html">1.2.2 Types</A>
46<b class="navlabel">Up:</b>
47<a class="sectref" rel="parent" href="intro.html">1. Introduction</A>
48<b class="navlabel">Next:</b>
49<a class="sectref" rel="next" href="embedding.html">1.4 Embedding Python</A>
50</div>
51<hr /></div>
52</DIV>
53<!--End of Navigation Panel-->
54
55<H1><A NAME="SECTION003300000000000000000"></A><A NAME="exceptions"></A>
56<BR>
571.3 Exceptions
58</H1>
59
60<P>
61The Python programmer only needs to deal with exceptions if specific
62error handling is required; unhandled exceptions are automatically
63propagated to the caller, then to the caller's caller, and so on, until
64they reach the top-level interpreter, where they are reported to the
65user accompanied by a stack traceback.
66
67<P>
68For C programmers, however, error checking always has to be explicit.
69All functions in the Python/C API can raise exceptions, unless an
70explicit claim is made otherwise in a function's documentation. In
71general, when a function encounters an error, it sets an exception,
72discards any object references that it owns, and returns an
73error indicator -- usually <tt class="constant">NULL</tt> or <code>-1</code>. A few functions
74return a Boolean true/false result, with false indicating an error.
75Very few functions return no explicit error indicator or have an
76ambiguous return value, and require explicit testing for errors with
77<tt class="cfunction">PyErr_Occurred()</tt><a id='l2h-20' xml:id='l2h-20'></a>.
78
79<P>
80Exception state is maintained in per-thread storage (this is
81equivalent to using global storage in an unthreaded application). A
82thread can be in one of two states: an exception has occurred, or not.
83The function <tt class="cfunction">PyErr_Occurred()</tt> can be used to check for
84this: it returns a borrowed reference to the exception type object
85when an exception has occurred, and <tt class="constant">NULL</tt> otherwise. There are a
86number of functions to set the exception state:
87<tt class="cfunction">PyErr_SetString()</tt><a id='l2h-21' xml:id='l2h-21'></a> is the most
88common (though not the most general) function to set the exception
89state, and <tt class="cfunction">PyErr_Clear()</tt><a id='l2h-22' xml:id='l2h-22'></a> clears the
90exception state.
91
92<P>
93The full exception state consists of three objects (all of which can
94be <tt class="constant">NULL</tt>): the exception type, the corresponding exception
95value, and the traceback. These have the same meanings as the Python
96<a id='l2h-17' xml:id='l2h-17'></a>objects <code>sys.exc_type</code>, <code>sys.exc_value</code>, and
97<code>sys.exc_traceback</code>; however, they are not the same: the Python
98objects represent the last exception being handled by a Python
99<tt class="keyword">try</tt> ... <tt class="keyword">except</tt> statement, while the C level
100exception state only exists while an exception is being passed on
101between C functions until it reaches the Python bytecode interpreter's
102main loop, which takes care of transferring it to <code>sys.exc_type</code>
103and friends.
104
105<P>
106Note that starting with Python 1.5, the preferred, thread-safe way to
107access the exception state from Python code is to call the function
108<a id='l2h-19' xml:id='l2h-19'></a><tt class="function">sys.exc_info()</tt>, which returns the per-thread exception state
109for Python code. Also, the semantics of both ways to access the
110exception state have changed so that a function which catches an
111exception will save and restore its thread's exception state so as to
112preserve the exception state of its caller. This prevents common bugs
113in exception handling code caused by an innocent-looking function
114overwriting the exception being handled; it also reduces the often
115unwanted lifetime extension for objects that are referenced by the
116stack frames in the traceback.
117
118<P>
119As a general principle, a function that calls another function to
120perform some task should check whether the called function raised an
121exception, and if so, pass the exception state on to its caller. It
122should discard any object references that it owns, and return an
123error indicator, but it should <em>not</em> set another exception --
124that would overwrite the exception that was just raised, and lose
125important information about the exact cause of the error.
126
127<P>
128A simple example of detecting exceptions and passing them on is shown
129in the <tt class="cfunction">sum_sequence()</tt><a id='l2h-23' xml:id='l2h-23'></a> example
130above. It so happens that that example doesn't need to clean up any
131owned references when it detects an error. The following example
132function shows some error cleanup. First, to remind you why you like
133Python, we show the equivalent Python code:
134
135<P>
136<div class="verbatim"><pre>
137def incr_item(dict, key):
138 try:
139 item = dict[key]
140 except KeyError:
141 item = 0
142 dict[key] = item + 1
143</pre></div>
144
145<P>
146Here is the corresponding C code, in all its glory:
147
148<P>
149<div class="verbatim"><pre>
150int
151incr_item(PyObject *dict, PyObject *key)
152{
153 /* Objects all initialized to NULL for Py_XDECREF */
154 PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
155 int rv = -1; /* Return value initialized to -1 (failure) */
156
157 item = PyObject_GetItem(dict, key);
158 if (item == NULL) {
159 /* Handle KeyError only: */
160 if (!PyErr_ExceptionMatches(PyExc_KeyError))
161 goto error;
162
163 /* Clear the error and use zero: */
164 PyErr_Clear();
165 item = PyInt_FromLong(0L);
166 if (item == NULL)
167 goto error;
168 }
169 const_one = PyInt_FromLong(1L);
170 if (const_one == NULL)
171 goto error;
172
173 incremented_item = PyNumber_Add(item, const_one);
174 if (incremented_item == NULL)
175 goto error;
176
177 if (PyObject_SetItem(dict, key, incremented_item) &lt; 0)
178 goto error;
179 rv = 0; /* Success */
180 /* Continue with cleanup code */
181
182 error:
183 /* Cleanup code, shared by success and failure path */
184
185 /* Use Py_XDECREF() to ignore NULL references */
186 Py_XDECREF(item);
187 Py_XDECREF(const_one);
188 Py_XDECREF(incremented_item);
189
190 return rv; /* -1 for error, 0 for success */
191}
192</pre></div>
193
194<P>
195This example represents an endorsed use of the <tt class="keyword">goto</tt> statement
196in C! It illustrates the use of
197<tt class="cfunction">PyErr_ExceptionMatches()</tt><a id='l2h-24' xml:id='l2h-24'></a> and
198<tt class="cfunction">PyErr_Clear()</tt><a id='l2h-25' xml:id='l2h-25'></a> to
199handle specific exceptions, and the use of
200<tt class="cfunction">Py_XDECREF()</tt><a id='l2h-26' xml:id='l2h-26'></a> to
201dispose of owned references that may be <tt class="constant">NULL</tt> (note the
202"<tt class="character">X</tt>" in the name; <tt class="cfunction">Py_DECREF()</tt> would crash when
203confronted with a <tt class="constant">NULL</tt> reference). It is important that the
204variables used to hold owned references are initialized to <tt class="constant">NULL</tt> for
205this to work; likewise, the proposed return value is initialized to
206<code>-1</code> (failure) and only set to success after the final call made
207is successful.
208
209<P>
210
211<DIV CLASS="navigation">
212<div class='online-navigation'>
213<p></p><hr />
214<table align="center" width="100%" cellpadding="0" cellspacing="2">
215<tr>
216<td class='online-navigation'><a rel="prev" title="1.2.2 Types"
217 href="types.html"><img src='../icons/previous.png'
218 border='0' height='32' alt='Previous Page' width='32' /></A></td>
219<td class='online-navigation'><a rel="parent" title="1. Introduction"
220 href="intro.html"><img src='../icons/up.png'
221 border='0' height='32' alt='Up One Level' width='32' /></A></td>
222<td class='online-navigation'><a rel="next" title="1.4 Embedding Python"
223 href="embedding.html"><img src='../icons/next.png'
224 border='0' height='32' alt='Next Page' width='32' /></A></td>
225<td align="center" width="100%">Python/C API Reference Manual</td>
226<td class='online-navigation'><a rel="contents" title="Table of Contents"
227 href="contents.html"><img src='../icons/contents.png'
228 border='0' height='32' alt='Contents' width='32' /></A></td>
229<td class='online-navigation'><img src='../icons/blank.png'
230 border='0' height='32' alt='' width='32' /></td>
231<td class='online-navigation'><a rel="index" title="Index"
232 href="genindex.html"><img src='../icons/index.png'
233 border='0' height='32' alt='Index' width='32' /></A></td>
234</tr></table>
235<div class='online-navigation'>
236<b class="navlabel">Previous:</b>
237<a class="sectref" rel="prev" href="types.html">1.2.2 Types</A>
238<b class="navlabel">Up:</b>
239<a class="sectref" rel="parent" href="intro.html">1. Introduction</A>
240<b class="navlabel">Next:</b>
241<a class="sectref" rel="next" href="embedding.html">1.4 Embedding Python</A>
242</div>
243</div>
244<hr />
245<span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span>
246</DIV>
247<!--End of Navigation Panel-->
248<ADDRESS>
249See <i><a href="about.html">About this document...</a></i> for information on suggesting changes.
250</ADDRESS>
251</BODY>
252</HTML>