Mercurial > cpython-lru_cache-weakref
comparison Python/errors.c @ 5370:1ea1f019268d legacy-trunk
Quickly renamed. Also removed the long comment explaining why this is
better than the old error API.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Tue, 29 Apr 1997 18:22:47 +0000 |
| parents | 2c4b802a3b5d |
| children | b7871ca930ad |
comparison
equal
deleted
inserted
replaced
| 5369:3ca14503170c | 5370:1ea1f019268d |
|---|---|
| 27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | 27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| 28 PERFORMANCE OF THIS SOFTWARE. | 28 PERFORMANCE OF THIS SOFTWARE. |
| 29 | 29 |
| 30 ******************************************************************/ | 30 ******************************************************************/ |
| 31 | 31 |
| 32 /* Error handling -- see also run.c */ | 32 /* Error handling */ |
| 33 | 33 |
| 34 /* New error handling interface. | 34 #include "Python.h" |
| 35 | |
| 36 The following problem exists (existed): methods of built-in modules | |
| 37 are called with 'self' and 'args' arguments, but without a context | |
| 38 argument, so they have no way to raise a specific exception. | |
| 39 The same is true for the object implementations: no context argument. | |
| 40 The old convention was to set 'errno' and to return NULL. | |
| 41 The caller (usually call_function() in eval.c) detects the NULL | |
| 42 return value and then calls puterrno(ctx) to turn the errno value | |
| 43 into a true exception. Problems with this approach are: | |
| 44 - it used standard errno values to indicate Python-specific errors, | |
| 45 but this means that when such an error code is reported by a system | |
| 46 call (e.g., in module posix), the user gets a confusing message | |
| 47 - errno is a global variable, which makes extensions to a multi- | |
| 48 threading environment difficult; e.g., in IRIX, multi-threaded | |
| 49 programs must use the function oserror() instead of looking in errno | |
| 50 - there is no portable way to add new error numbers for specic | |
| 51 situations -- the value space for errno is reserved to the OS, yet | |
| 52 the way to turn module-specific errors into a module-specific | |
| 53 exception requires module-specific values for errno | |
| 54 - there is no way to add a more situation-specific message to an | |
| 55 error. | |
| 56 | |
| 57 The new interface solves all these problems. To return an error, a | |
| 58 built-in function calls err_set(exception), err_setval(exception, | |
| 59 value) or err_setstr(exception, string), and returns NULL. These | |
| 60 functions save the value for later use by puterrno(). To adapt this | |
| 61 scheme to a multi-threaded environment, only the implementation of | |
| 62 err_setval() has to be changed. | |
| 63 */ | |
| 64 | |
| 65 #include "allobjects.h" | |
| 66 #include "traceback.h" | |
| 67 | |
| 68 #include <errno.h> | |
| 69 | 35 |
| 70 #ifdef SYMANTEC__CFM68K__ | 36 #ifdef SYMANTEC__CFM68K__ |
| 71 #pragma lib_export on | 37 #pragma lib_export on |
| 72 #endif | 38 #endif |
| 73 | 39 |
| 75 #ifndef __MSL__ | 41 #ifndef __MSL__ |
| 76 /* Replace strerror with a Mac specific routine. | 42 /* Replace strerror with a Mac specific routine. |
| 77 XXX PROBLEM: some positive errors have a meaning for MacOS, | 43 XXX PROBLEM: some positive errors have a meaning for MacOS, |
| 78 but some library routines set Unix error numbers... | 44 but some library routines set Unix error numbers... |
| 79 */ | 45 */ |
| 80 extern char *PyMac_StrError PROTO((int)); | 46 extern char *PyMac_StrError Py_PROTO((int)); |
| 81 #undef strerror | 47 #undef strerror |
| 82 #define strerror PyMac_StrError | 48 #define strerror PyMac_StrError |
| 83 #endif | 49 #endif |
| 84 #endif /* macintosh */ | 50 #endif /* macintosh */ |
| 85 | 51 |
| 86 #ifndef __STDC__ | 52 #ifndef __STDC__ |
| 87 #ifndef MS_WINDOWS | 53 #ifndef MS_WINDOWS |
| 88 extern char *strerror PROTO((int)); | 54 extern char *strerror Py_PROTO((int)); |
| 89 #endif | 55 #endif |
| 90 #endif | 56 #endif |
| 91 | 57 |
| 92 /* Last exception stored by err_setval() */ | 58 /* Last exception stored */ |
| 93 | 59 |
| 94 static object *last_exception; | 60 static PyObject *last_exception; |
| 95 static object *last_exc_val; | 61 static PyObject *last_exc_val; |
| 96 | 62 |
| 97 void | 63 void |
| 98 err_restore(exception, value, traceback) | 64 PyErr_Restore(exception, value, traceback) |
| 99 object *exception; | 65 PyObject *exception; |
| 100 object *value; | 66 PyObject *value; |
| 101 object *traceback; | 67 PyObject *traceback; |
| 102 { | 68 { |
| 103 err_clear(); | 69 PyErr_Clear(); |
| 104 | 70 |
| 105 last_exception = exception; | 71 last_exception = exception; |
| 106 last_exc_val = value; | 72 last_exc_val = value; |
| 107 (void) tb_store(traceback); | 73 (void) PyTraceBack_Store(traceback); |
| 108 XDECREF(traceback); | 74 Py_XDECREF(traceback); |
| 109 } | 75 } |
| 110 | 76 |
| 111 void | 77 void |
| 112 err_setval(exception, value) | 78 PyErr_SetObject(exception, value) |
| 113 object *exception; | 79 PyObject *exception; |
| 114 object *value; | 80 PyObject *value; |
| 115 { | 81 { |
| 116 XINCREF(exception); | 82 Py_XINCREF(exception); |
| 117 XINCREF(value); | 83 Py_XINCREF(value); |
| 118 err_restore(exception, value, (object *)NULL); | 84 PyErr_Restore(exception, value, (PyObject *)NULL); |
| 119 } | 85 } |
| 120 | 86 |
| 121 void | 87 void |
| 122 err_set(exception) | 88 PyErr_SetNone(exception) |
| 123 object *exception; | 89 PyObject *exception; |
| 124 { | 90 { |
| 125 err_setval(exception, (object *)NULL); | 91 PyErr_SetObject(exception, (PyObject *)NULL); |
| 126 } | 92 } |
| 127 | 93 |
| 128 void | 94 void |
| 129 err_setstr(exception, string) | 95 PyErr_SetString(exception, string) |
| 130 object *exception; | 96 PyObject *exception; |
| 131 const char *string; | 97 const char *string; |
| 132 { | 98 { |
| 133 object *value = newstringobject(string); | 99 PyObject *value = PyString_FromString(string); |
| 134 err_setval(exception, value); | 100 PyErr_SetObject(exception, value); |
| 135 XDECREF(value); | 101 Py_XDECREF(value); |
| 136 } | 102 } |
| 137 | 103 |
| 138 | 104 |
| 139 object * | 105 PyObject * |
| 140 err_occurred() | 106 PyErr_Occurred() |
| 141 { | 107 { |
| 142 return last_exception; | 108 return last_exception; |
| 143 } | 109 } |
| 144 | 110 |
| 145 void | 111 void |
| 146 err_fetch(p_exc, p_val, p_tb) | 112 PyErr_Fetch(p_exc, p_val, p_tb) |
| 147 object **p_exc; | 113 PyObject **p_exc; |
| 148 object **p_val; | 114 PyObject **p_val; |
| 149 object **p_tb; | 115 PyObject **p_tb; |
| 150 { | 116 { |
| 151 *p_exc = last_exception; | 117 *p_exc = last_exception; |
| 152 last_exception = NULL; | 118 last_exception = NULL; |
| 153 *p_val = last_exc_val; | 119 *p_val = last_exc_val; |
| 154 last_exc_val = NULL; | 120 last_exc_val = NULL; |
| 155 *p_tb = tb_fetch(); | 121 *p_tb = PyTraceBack_Fetch(); |
| 156 } | 122 } |
| 157 | 123 |
| 158 void | 124 void |
| 159 err_clear() | 125 PyErr_Clear() |
| 160 { | 126 { |
| 161 object *tb; | 127 PyObject *tb; |
| 162 XDECREF(last_exception); | 128 Py_XDECREF(last_exception); |
| 163 last_exception = NULL; | 129 last_exception = NULL; |
| 164 XDECREF(last_exc_val); | 130 Py_XDECREF(last_exc_val); |
| 165 last_exc_val = NULL; | 131 last_exc_val = NULL; |
| 166 /* Also clear interpreter stack trace */ | 132 /* Also clear interpreter stack trace */ |
| 167 tb = tb_fetch(); | 133 tb = PyTraceBack_Fetch(); |
| 168 XDECREF(tb); | 134 Py_XDECREF(tb); |
| 169 } | 135 } |
| 170 | 136 |
| 171 /* Convenience functions to set a type error exception and return 0 */ | 137 /* Convenience functions to set a type error exception and return 0 */ |
| 172 | 138 |
| 173 int | 139 int |
| 174 err_badarg() | 140 PyErr_BadArgument() |
| 175 { | 141 { |
| 176 err_setstr(TypeError, "illegal argument type for built-in operation"); | 142 PyErr_SetString(PyExc_TypeError, "illegal argument type for built-in operation"); |
| 177 return 0; | 143 return 0; |
| 178 } | 144 } |
| 179 | 145 |
| 180 object * | 146 PyObject * |
| 181 err_nomem() | 147 PyErr_NoMemory() |
| 182 { | 148 { |
| 183 err_set(MemoryError); | 149 PyErr_SetNone(PyExc_MemoryError); |
| 184 return NULL; | 150 return NULL; |
| 185 } | 151 } |
| 186 | 152 |
| 187 object * | 153 PyObject * |
| 188 err_errno(exc) | 154 PyErr_SetFromErrno(exc) |
| 189 object *exc; | 155 PyObject *exc; |
| 190 { | 156 { |
| 191 object *v; | 157 PyObject *v; |
| 192 int i = errno; | 158 int i = errno; |
| 193 #ifdef EINTR | 159 #ifdef EINTR |
| 194 if (i == EINTR && sigcheck()) | 160 if (i == EINTR && PyErr_CheckSignals()) |
| 195 return NULL; | 161 return NULL; |
| 196 #endif | 162 #endif |
| 197 v = mkvalue("(is)", i, strerror(i)); | 163 v = Py_BuildValue("(is)", i, strerror(i)); |
| 198 if (v != NULL) { | 164 if (v != NULL) { |
| 199 err_setval(exc, v); | 165 PyErr_SetObject(exc, v); |
| 200 DECREF(v); | 166 Py_DECREF(v); |
| 201 } | 167 } |
| 202 return NULL; | 168 return NULL; |
| 203 } | 169 } |
| 204 | 170 |
| 205 void | 171 void |
| 206 err_badcall() | 172 PyErr_BadInternalCall() |
| 207 { | 173 { |
| 208 err_setstr(SystemError, "bad argument to internal function"); | 174 PyErr_SetString(PyExc_SystemError, "bad argument to internal function"); |
| 209 } | 175 } |
| 210 | 176 |
| 211 | 177 |
| 212 #ifdef HAVE_STDARG_PROTOTYPES | 178 #ifdef HAVE_STDARG_PROTOTYPES |
| 213 PyObject * | 179 PyObject * |
