Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> |
2 | <html> | |
3 | <head> | |
4 | <link rel="STYLESHEET" href="ext.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="ext.html" title='Extending and Embedding the Python Interpreter' /> | |
8 | <link rel='contents' href='contents.html' title="Contents" /> | |
9 | <link rel='last' href='about.html' title='About this document...' /> | |
10 | <link rel='help' href='about.html' title='About this document...' /> | |
11 | <link rel="next" href="backToExample.html" /> | |
12 | <link rel="prev" href="simpleExample.html" /> | |
13 | <link rel="parent" href="intro.html" /> | |
14 | <link rel="next" href="backToExample.html" /> | |
15 | <meta name='aesop' content='information' /> | |
16 | <title>1.2 Intermezzo: Errors and Exceptions | |
17 | </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.1 A Simple Example" | |
25 | href="simpleExample.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. Extending Python with" | |
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.3 Back to the" | |
31 | href="backToExample.html"><img src='../icons/next.png' | |
32 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
33 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</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'><img src='../icons/blank.png' | |
40 | border='0' height='32' alt='' width='32' /></td> | |
41 | </tr></table> | |
42 | <div class='online-navigation'> | |
43 | <b class="navlabel">Previous:</b> | |
44 | <a class="sectref" rel="prev" href="simpleExample.html">1.1 A Simple Example</A> | |
45 | <b class="navlabel">Up:</b> | |
46 | <a class="sectref" rel="parent" href="intro.html">1. Extending Python with</A> | |
47 | <b class="navlabel">Next:</b> | |
48 | <a class="sectref" rel="next" href="backToExample.html">1.3 Back to the</A> | |
49 | </div> | |
50 | <hr /></div> | |
51 | </DIV> | |
52 | <!--End of Navigation Panel--> | |
53 | ||
54 | <H1><A NAME="SECTION003200000000000000000"></A><A NAME="errors"></A> | |
55 | <BR> | |
56 | 1.2 Intermezzo: Errors and Exceptions | |
57 | ||
58 | </H1> | |
59 | ||
60 | <P> | |
61 | An important convention throughout the Python interpreter is the | |
62 | following: when a function fails, it should set an exception condition | |
63 | and return an error value (usually a <tt class="constant">NULL</tt> pointer). Exceptions | |
64 | are stored in a static global variable inside the interpreter; if this | |
65 | variable is <tt class="constant">NULL</tt> no exception has occurred. A second global | |
66 | variable stores the ``associated value'' of the exception (the second | |
67 | argument to <tt class="keyword">raise</tt>). A third variable contains the stack | |
68 | traceback in case the error originated in Python code. These three | |
69 | variables are the C equivalents of the Python variables | |
70 | <code>sys.exc_type</code>, <code>sys.exc_value</code> and <code>sys.exc_traceback</code> (see | |
71 | the section on module <tt class="module">sys</tt> in the | |
72 | <em class="citetitle"><a | |
73 | href="../lib/lib.html" | |
74 | title="Python Library Reference" | |
75 | >Python Library Reference</a></em>). It is | |
76 | important to know about them to understand how errors are passed | |
77 | around. | |
78 | ||
79 | <P> | |
80 | The Python API defines a number of functions to set various types of | |
81 | exceptions. | |
82 | ||
83 | <P> | |
84 | The most common one is <tt class="cfunction">PyErr_SetString()</tt>. Its arguments | |
85 | are an exception object and a C string. The exception object is | |
86 | usually a predefined object like <tt class="cdata">PyExc_ZeroDivisionError</tt>. The | |
87 | C string indicates the cause of the error and is converted to a | |
88 | Python string object and stored as the ``associated value'' of the | |
89 | exception. | |
90 | ||
91 | <P> | |
92 | Another useful function is <tt class="cfunction">PyErr_SetFromErrno()</tt>, which only | |
93 | takes an exception argument and constructs the associated value by | |
94 | inspection of the global variable <tt class="cdata">errno</tt>. The most | |
95 | general function is <tt class="cfunction">PyErr_SetObject()</tt>, which takes two object | |
96 | arguments, the exception and its associated value. You don't need to | |
97 | <tt class="cfunction">Py_INCREF()</tt> the objects passed to any of these functions. | |
98 | ||
99 | <P> | |
100 | You can test non-destructively whether an exception has been set with | |
101 | <tt class="cfunction">PyErr_Occurred()</tt>. This returns the current exception object, | |
102 | or <tt class="constant">NULL</tt> if no exception has occurred. You normally don't need | |
103 | to call <tt class="cfunction">PyErr_Occurred()</tt> to see whether an error occurred in a | |
104 | function call, since you should be able to tell from the return value. | |
105 | ||
106 | <P> | |
107 | When a function <var>f</var> that calls another function <var>g</var> detects | |
108 | that the latter fails, <var>f</var> should itself return an error value | |
109 | (usually <tt class="constant">NULL</tt> or <code>-1</code>). It should <em>not</em> call one of the | |
110 | <tt class="cfunction">PyErr_*()</tt> functions -- one has already been called by <var>g</var>. | |
111 | <var>f</var>'s caller is then supposed to also return an error indication | |
112 | to <em>its</em> caller, again <em>without</em> calling <tt class="cfunction">PyErr_*()</tt>, | |
113 | and so on -- the most detailed cause of the error was already | |
114 | reported by the function that first detected it. Once the error | |
115 | reaches the Python interpreter's main loop, this aborts the currently | |
116 | executing Python code and tries to find an exception handler specified | |
117 | by the Python programmer. | |
118 | ||
119 | <P> | |
120 | (There are situations where a module can actually give a more detailed | |
121 | error message by calling another <tt class="cfunction">PyErr_*()</tt> function, and in | |
122 | such cases it is fine to do so. As a general rule, however, this is | |
123 | not necessary, and can cause information about the cause of the error | |
124 | to be lost: most operations can fail for a variety of reasons.) | |
125 | ||
126 | <P> | |
127 | To ignore an exception set by a function call that failed, the exception | |
128 | condition must be cleared explicitly by calling <tt class="cfunction">PyErr_Clear()</tt>. | |
129 | The only time C code should call <tt class="cfunction">PyErr_Clear()</tt> is if it doesn't | |
130 | want to pass the error on to the interpreter but wants to handle it | |
131 | completely by itself (possibly by trying something else, or pretending | |
132 | nothing went wrong). | |
133 | ||
134 | <P> | |
135 | Every failing <tt class="cfunction">malloc()</tt> call must be turned into an | |
136 | exception -- the direct caller of <tt class="cfunction">malloc()</tt> (or | |
137 | <tt class="cfunction">realloc()</tt>) must call <tt class="cfunction">PyErr_NoMemory()</tt> and | |
138 | return a failure indicator itself. All the object-creating functions | |
139 | (for example, <tt class="cfunction">PyInt_FromLong()</tt>) already do this, so this | |
140 | note is only relevant to those who call <tt class="cfunction">malloc()</tt> directly. | |
141 | ||
142 | <P> | |
143 | Also note that, with the important exception of | |
144 | <tt class="cfunction">PyArg_ParseTuple()</tt> and friends, functions that return an | |
145 | integer status usually return a positive value or zero for success and | |
146 | <code>-1</code> for failure, like <span class="Unix">Unix</span> system calls. | |
147 | ||
148 | <P> | |
149 | Finally, be careful to clean up garbage (by making | |
150 | <tt class="cfunction">Py_XDECREF()</tt> or <tt class="cfunction">Py_DECREF()</tt> calls for objects | |
151 | you have already created) when you return an error indicator! | |
152 | ||
153 | <P> | |
154 | The choice of which exception to raise is entirely yours. There are | |
155 | predeclared C objects corresponding to all built-in Python exceptions, | |
156 | such as <tt class="cdata">PyExc_ZeroDivisionError</tt>, which you can use directly. | |
157 | Of course, you should choose exceptions wisely -- don't use | |
158 | <tt class="cdata">PyExc_TypeError</tt> to mean that a file couldn't be opened (that | |
159 | should probably be <tt class="cdata">PyExc_IOError</tt>). If something's wrong with | |
160 | the argument list, the <tt class="cfunction">PyArg_ParseTuple()</tt> function usually | |
161 | raises <tt class="cdata">PyExc_TypeError</tt>. If you have an argument whose value | |
162 | must be in a particular range or must satisfy other conditions, | |
163 | <tt class="cdata">PyExc_ValueError</tt> is appropriate. | |
164 | ||
165 | <P> | |
166 | You can also define a new exception that is unique to your module. | |
167 | For this, you usually declare a static object variable at the | |
168 | beginning of your file: | |
169 | ||
170 | <P> | |
171 | <div class="verbatim"><pre> | |
172 | static PyObject *SpamError; | |
173 | </pre></div> | |
174 | ||
175 | <P> | |
176 | and initialize it in your module's initialization function | |
177 | (<tt class="cfunction">initspam()</tt>) with an exception object (leaving out | |
178 | the error checking for now): | |
179 | ||
180 | <P> | |
181 | <div class="verbatim"><pre> | |
182 | PyMODINIT_FUNC | |
183 | initspam(void) | |
184 | { | |
185 | PyObject *m; | |
186 | ||
187 | m = Py_InitModule("spam", SpamMethods); | |
188 | ||
189 | SpamError = PyErr_NewException("spam.error", NULL, NULL); | |
190 | Py_INCREF(SpamError); | |
191 | PyModule_AddObject(m, "error", SpamError); | |
192 | } | |
193 | </pre></div> | |
194 | ||
195 | <P> | |
196 | Note that the Python name for the exception object is | |
197 | <tt class="exception">spam.error</tt>. The <tt class="cfunction">PyErr_NewException()</tt> function | |
198 | may create a class with the base class being <tt class="exception">Exception</tt> | |
199 | (unless another class is passed in instead of <tt class="constant">NULL</tt>), described in the | |
200 | <em class="citetitle"><a | |
201 | href="../lib/lib.html" | |
202 | title="Python Library Reference" | |
203 | >Python Library Reference</a></em> under ``Built-in | |
204 | Exceptions.'' | |
205 | ||
206 | <P> | |
207 | Note also that the <tt class="cdata">SpamError</tt> variable retains a reference to | |
208 | the newly created exception class; this is intentional! Since the | |
209 | exception could be removed from the module by external code, an owned | |
210 | reference to the class is needed to ensure that it will not be | |
211 | discarded, causing <tt class="cdata">SpamError</tt> to become a dangling pointer. | |
212 | Should it become a dangling pointer, C code which raises the exception | |
213 | could cause a core dump or other unintended side effects. | |
214 | ||
215 | <P> | |
216 | We discuss the use of PyMODINIT_FUNC as a function return type later in this | |
217 | sample. | |
218 | ||
219 | <P> | |
220 | ||
221 | <DIV CLASS="navigation"> | |
222 | <div class='online-navigation'> | |
223 | <p></p><hr /> | |
224 | <table align="center" width="100%" cellpadding="0" cellspacing="2"> | |
225 | <tr> | |
226 | <td class='online-navigation'><a rel="prev" title="1.1 A Simple Example" | |
227 | href="simpleExample.html"><img src='../icons/previous.png' | |
228 | border='0' height='32' alt='Previous Page' width='32' /></A></td> | |
229 | <td class='online-navigation'><a rel="parent" title="1. Extending Python with" | |
230 | href="intro.html"><img src='../icons/up.png' | |
231 | border='0' height='32' alt='Up One Level' width='32' /></A></td> | |
232 | <td class='online-navigation'><a rel="next" title="1.3 Back to the" | |
233 | href="backToExample.html"><img src='../icons/next.png' | |
234 | border='0' height='32' alt='Next Page' width='32' /></A></td> | |
235 | <td align="center" width="100%">Extending and Embedding the Python Interpreter</td> | |
236 | <td class='online-navigation'><a rel="contents" title="Table of Contents" | |
237 | href="contents.html"><img src='../icons/contents.png' | |
238 | border='0' height='32' alt='Contents' width='32' /></A></td> | |
239 | <td class='online-navigation'><img src='../icons/blank.png' | |
240 | border='0' height='32' alt='' width='32' /></td> | |
241 | <td class='online-navigation'><img src='../icons/blank.png' | |
242 | border='0' height='32' alt='' width='32' /></td> | |
243 | </tr></table> | |
244 | <div class='online-navigation'> | |
245 | <b class="navlabel">Previous:</b> | |
246 | <a class="sectref" rel="prev" href="simpleExample.html">1.1 A Simple Example</A> | |
247 | <b class="navlabel">Up:</b> | |
248 | <a class="sectref" rel="parent" href="intro.html">1. Extending Python with</A> | |
249 | <b class="navlabel">Next:</b> | |
250 | <a class="sectref" rel="next" href="backToExample.html">1.3 Back to the</A> | |
251 | </div> | |
252 | </div> | |
253 | <hr /> | |
254 | <span class="release-info">Release 2.4.2, documentation updated on 28 September 2005.</span> | |
255 | </DIV> | |
256 | <!--End of Navigation Panel--> | |
257 | <ADDRESS> | |
258 | See <i><a href="about.html">About this document...</a></i> for information on suggesting changes. | |
259 | </ADDRESS> | |
260 | </BODY> | |
261 | </HTML> |