Mercurial > cpython-lru_cache-weakref
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; |
