mirror of
https://github.com/python/cpython.git
synced 2025-10-22 14:42:22 +00:00
cmp_exception gets promoted (essentially) to the C API function
PyErr_GivenExceptionMatches(). set_exc_info(): make sure to normalize exceptions. do_raise(): Use PyErr_NormalizeException() if type is a class. loop_subscript(): Use PyErr_ExceptionMatches() instead of raw pointer compare for PyExc_IndexError.
This commit is contained in:
parent
c0dc92af7d
commit
4249f54b28
1 changed files with 10 additions and 59 deletions
|
@ -84,7 +84,6 @@ static int slice_index Py_PROTO((PyObject *, int *));
|
||||||
static PyObject *apply_slice Py_PROTO((PyObject *, PyObject *, PyObject *));
|
static PyObject *apply_slice Py_PROTO((PyObject *, PyObject *, PyObject *));
|
||||||
static int assign_slice Py_PROTO((PyObject *, PyObject *,
|
static int assign_slice Py_PROTO((PyObject *, PyObject *,
|
||||||
PyObject *, PyObject *));
|
PyObject *, PyObject *));
|
||||||
static int cmp_exception Py_PROTO((PyObject *, PyObject *));
|
|
||||||
static int cmp_member Py_PROTO((PyObject *, PyObject *));
|
static int cmp_member Py_PROTO((PyObject *, PyObject *));
|
||||||
static PyObject *cmp_outcome Py_PROTO((int, PyObject *, PyObject *));
|
static PyObject *cmp_outcome Py_PROTO((int, PyObject *, PyObject *));
|
||||||
static int import_from Py_PROTO((PyObject *, PyObject *, PyObject *));
|
static int import_from Py_PROTO((PyObject *, PyObject *, PyObject *));
|
||||||
|
@ -1872,6 +1871,9 @@ set_exc_info(tstate, type, value, tb)
|
||||||
{
|
{
|
||||||
PyFrameObject *frame;
|
PyFrameObject *frame;
|
||||||
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
PyObject *tmp_type, *tmp_value, *tmp_tb;
|
||||||
|
|
||||||
|
PyErr_NormalizeException(&type, &value, &tb);
|
||||||
|
|
||||||
frame = tstate->frame;
|
frame = tstate->frame;
|
||||||
if (frame->f_exc_type == NULL) {
|
if (frame->f_exc_type == NULL) {
|
||||||
/* This frame didn't catch an exception before */
|
/* This frame didn't catch an exception before */
|
||||||
|
@ -2000,44 +2002,12 @@ do_raise(type, value, tb)
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now switch on the exception's type */
|
if (PyString_Check(type))
|
||||||
if (PyString_Check(type)) {
|
|
||||||
;
|
;
|
||||||
}
|
|
||||||
else if (PyClass_Check(type)) {
|
else if (PyClass_Check(type))
|
||||||
/* Raising a class. If the value is an instance, it
|
PyErr_NormalizeException(&type, &value, &tb);
|
||||||
better be an instance of the class. If it is not,
|
|
||||||
it will be used to create an instance. */
|
|
||||||
if (PyInstance_Check(value)) {
|
|
||||||
PyObject *inclass = (PyObject*)
|
|
||||||
(((PyInstanceObject*)value)->in_class);
|
|
||||||
if (!PyClass_IsSubclass(inclass, type)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError,
|
|
||||||
"raise <class>, <instance> requires that <instance> is a member of <class>");
|
|
||||||
goto raise_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* Go instantiate the class */
|
|
||||||
PyObject *args, *res;
|
|
||||||
if (value == Py_None)
|
|
||||||
args = Py_BuildValue("()");
|
|
||||||
else if (PyTuple_Check(value)) {
|
|
||||||
Py_INCREF(value);
|
|
||||||
args = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
args = Py_BuildValue("(O)", value);
|
|
||||||
if (args == NULL)
|
|
||||||
goto raise_error;
|
|
||||||
res = PyEval_CallObject(type, args);
|
|
||||||
Py_DECREF(args);
|
|
||||||
if (res == NULL)
|
|
||||||
goto raise_error;
|
|
||||||
Py_DECREF(value);
|
|
||||||
value = res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (PyInstance_Check(type)) {
|
else if (PyInstance_Check(type)) {
|
||||||
/* Raising an instance. The value should be a dummy. */
|
/* Raising an instance. The value should be a dummy. */
|
||||||
if (value != Py_None) {
|
if (value != Py_None) {
|
||||||
|
@ -2465,7 +2435,7 @@ loop_subscript(v, w)
|
||||||
v = (*sq->sq_item)(v, i);
|
v = (*sq->sq_item)(v, i);
|
||||||
if (v)
|
if (v)
|
||||||
return v;
|
return v;
|
||||||
if (PyErr_Occurred() == PyExc_IndexError)
|
if (PyErr_ExceptionMatches(PyExc_IndexError))
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -2520,25 +2490,6 @@ assign_slice(u, v, w, x) /* u[v:w] = x */
|
||||||
return PySequence_SetSlice(u, ilow, ihigh, x);
|
return PySequence_SetSlice(u, ilow, ihigh, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
cmp_exception(err, v)
|
|
||||||
PyObject *err, *v;
|
|
||||||
{
|
|
||||||
if (PyTuple_Check(v)) {
|
|
||||||
int i, n;
|
|
||||||
n = PyTuple_Size(v);
|
|
||||||
for (i = 0; i < n; i++) {
|
|
||||||
/* Test recursively */
|
|
||||||
if (cmp_exception(err, PyTuple_GET_ITEM(v, i)))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (PyClass_Check(v) && PyClass_Check(err))
|
|
||||||
return PyClass_IsSubclass(err, v);
|
|
||||||
return err == v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cmp_member(v, w)
|
cmp_member(v, w)
|
||||||
PyObject *v, *w;
|
PyObject *v, *w;
|
||||||
|
@ -2613,7 +2564,7 @@ cmp_outcome(op, v, w)
|
||||||
res = !res;
|
res = !res;
|
||||||
break;
|
break;
|
||||||
case EXC_MATCH:
|
case EXC_MATCH:
|
||||||
res = cmp_exception(v, w);
|
res = PyErr_GivenExceptionMatches(v, w);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cmp = PyObject_Compare(v, w);
|
cmp = PyObject_Compare(v, w);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue