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 *