| 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> |