comparison Python/errors.c @ 6146:a2a1df0ca808 legacy-trunk

Three new C API functions: - int PyErr_GivenExceptionMatches(obj1, obj2) Returns 1 if obj1 and obj2 are the same object, or if obj1 is an instance of type obj2, or of a class derived from obj2 - int PyErr_ExceptionMatches(obj) Higher level wrapper around PyErr_GivenExceptionMatches() which uses PyErr_Occurred() as obj1. This will be the more commonly called function. - void PyErr_NormalizeException(typeptr, valptr, tbptr) Normalizes exceptions, and places the normalized values in the arguments. If type is not a class, this does nothing. If type is a class, then it makes sure that value is an instance of the class by: 1. if instance is of the type, or a class derived from type, it does nothing. 2. otherwise it instantiates the class, using the value as an argument. If value is None, it uses an empty arg tuple, and if the value is a tuple, it uses just that.
author Barry Warsaw <barry@python.org>
date Fri, 22 Aug 1997 21:22:58 +0000
parents 422960523286
children b5757e87eb32
comparison
equal deleted inserted replaced
6145:341fcb7bad90 6146:a2a1df0ca808
113 PyThreadState *tstate = PyThreadState_Get(); 113 PyThreadState *tstate = PyThreadState_Get();
114 114
115 return tstate->curexc_type; 115 return tstate->curexc_type;
116 } 116 }
117 117
118
119 int
120 PyErr_GivenExceptionMatches(err, exc)
121 PyObject *err, *exc;
122 {
123 if (PyTuple_Check(exc)) {
124 int i, n;
125 n = PyTuple_Size(exc);
126 for (i = 0; i < n; i++) {
127 /* Test recursively */
128 if (PyErr_GivenExceptionMatches(
129 err, PyTuple_GET_ITEM(exc, i)))
130 {
131 return 1;
132 }
133 }
134 return 0;
135 }
136 /* err might be an instance, so check its class. */
137 if (PyInstance_Check(err))
138 err = (PyObject*)((PyInstanceObject*)err)->in_class;
139
140 if (PyClass_Check(err) && PyClass_Check(exc))
141 return PyClass_IsSubclass(err, exc);
142
143 return err == exc;
144 }
145
146
147 int
148 PyErr_ExceptionMatches(exc)
149 PyObject *exc;
150 {
151 return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);
152 }
153
154
155 /* Used in many places to normalize a raised exception, including in
156 eval_code2(), do_raise(), and PyErr_Print()
157 */
158 void
159 PyErr_NormalizeException(exc, val, tb)
160 PyObject **exc;
161 PyObject **val;
162 PyObject **tb;
163 {
164 PyObject *type = *exc;
165 PyObject *value = *val;
166 PyObject *inclass = NULL;
167
168 /* If PyErr_SetNone() was used, the value will have been actually
169 set to NULL.
170 */
171 if (!value) {
172 value = Py_None;
173 Py_INCREF(value);
174 }
175
176 if (PyInstance_Check(value))
177 inclass = (PyObject*)((PyInstanceObject*)value)->in_class;
178
179 /* Normalize the exception so that if the type is a class, the
180 value will be an instance.
181 */
182 if (PyClass_Check(type)) {
183 /* if the value was not an instance, or is not an instance
184 whose class is (or is derived from) type, then use the
185 value as an argument to instantiation of the type
186 class.
187 */
188 if (!inclass || !PyClass_IsSubclass(inclass, type)) {
189 PyObject *args, *res;
190
191 if (value == Py_None)
192 args = Py_BuildValue("()");
193 else if (PyTuple_Check(value)) {
194 Py_INCREF(value);
195 args = value;
196 }
197 else
198 args = Py_BuildValue("(O)", value);
199
200 if (args == NULL)
201 goto finally;
202 res = PyEval_CallObject(type, args);
203 Py_DECREF(args);
204 if (res == NULL)
205 goto finally;
206 Py_DECREF(value);
207 value = res;
208 }
209 }
210 *exc = type;
211 *val = value;
212 return;
213 finally:
214 Py_DECREF(*exc);
215 Py_DECREF(*val);
216 Py_XDECREF(*tb);
217 PyErr_Fetch(exc, val, tb);
218 /* normalize recursively */
219 PyErr_NormalizeException(exc, val, tb);
220 }
221
222
118 void 223 void
119 PyErr_Fetch(p_type, p_value, p_traceback) 224 PyErr_Fetch(p_type, p_value, p_traceback)
120 PyObject **p_type; 225 PyObject **p_type;
121 PyObject **p_value; 226 PyObject **p_value;
122 PyObject **p_traceback; 227 PyObject **p_traceback;