PyObject_Compare can raise an exception now.

This commit is contained in:
Guido van Rossum 1997-05-23 00:06:51 +00:00
parent 5b2121b25f
commit c8b6df9004
7 changed files with 67 additions and 31 deletions

View file

@ -349,7 +349,6 @@ instance_dealloc(inst)
PyObject *f, *t, *v, *tb;
PyErr_Fetch(&t, &v, &tb);
f = PySys_GetObject("stderr");
PyErr_Clear();
if (f != NULL) {
PyFile_WriteString("Exception ", f);
if (t) {
@ -565,9 +564,13 @@ instance_compare(inst, other)
PyObject *result;
long outcome;
result = instance_compare1(inst, other);
if (result == NULL || !PyInt_Check(result)) {
PyErr_Clear();
return (inst < other) ? -1 : 1;
if (result == NULL)
return -1;
if (!PyInt_Check(result)) {
Py_DECREF(result);
PyErr_SetString(PyExc_TypeError,
"comparison did not return an int");
return -1;
}
outcome = PyInt_AsLong(result);
Py_DECREF(result);
@ -899,6 +902,11 @@ PyInstance_DoBinOp(v, w, opname, ropname, thisfunc)
return result;
if (halfbinop(w, v, ropname, &result, thisfunc, 1) <= 0)
return result;
/* Sigh -- special case for comnparisons */
if (strcmp(opname, "__cmp__") == 0) {
long c = (v < w) ? -1 : (v > w) ? 1 : 0;
return PyInt_FromLong(c);
}
sprintf(buf, "%s nor %s defined for these operands", opname, ropname);
PyErr_SetString(PyExc_TypeError, buf);
return NULL;

View file

@ -580,8 +580,12 @@ docompare(x, y, compare)
PyObject *args, *res;
int i;
if (compare == NULL)
return PyObject_Compare(x, y);
if (compare == NULL) {
i = PyObject_Compare(x, y);
if (i && PyErr_Occurred())
i = CMPERROR;
return i;
}
args = Py_BuildValue("(OO)", x, y);
if (args == NULL)
@ -955,6 +959,8 @@ listindex(self, args)
for (i = 0; i < self->ob_size; i++) {
if (PyObject_Compare(self->ob_item[i], args) == 0)
return PyInt_FromLong((long)i);
if (PyErr_Occurred())
return NULL;
}
PyErr_SetString(PyExc_ValueError, "list.index(x): x not in list");
return NULL;
@ -975,6 +981,8 @@ listcount(self, args)
for (i = 0; i < self->ob_size; i++) {
if (PyObject_Compare(self->ob_item[i], args) == 0)
count++;
if (PyErr_Occurred())
return NULL;
}
return PyInt_FromLong((long)count);
}
@ -998,7 +1006,8 @@ listremove(self, args)
Py_INCREF(Py_None);
return Py_None;
}
if (PyErr_Occurred())
return NULL;
}
PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
return NULL;

View file

@ -255,13 +255,17 @@ static PyObject *
do_cmp(v, w)
PyObject *v, *w;
{
long c;
/* __rcmp__ actually won't be called unless __cmp__ isn't defined,
because the check in cmpobject() reverses the objects first.
This is intentional -- it makes no sense to define cmp(x,y)
different than -cmp(y,x). */
if (PyInstance_Check(v) || PyInstance_Check(w))
return PyInstance_DoBinOp(v, w, "__cmp__", "__rcmp__", do_cmp);
return PyInt_FromLong((long)PyObject_Compare(v, w));
c = PyObject_Compare(v, w);
if (c && PyErr_Occurred())
return NULL;
return PyInt_FromLong(c);
}
int
@ -269,25 +273,25 @@ PyObject_Compare(v, w)
PyObject *v, *w;
{
PyTypeObject *tp;
if (v == NULL || w == NULL) {
PyErr_BadInternalCall();
return -1;
}
if (v == w)
return 0;
if (v == NULL)
return -1;
if (w == NULL)
return 1;
if (PyInstance_Check(v) || PyInstance_Check(w)) {
PyObject *res;
int c;
if (!PyInstance_Check(v))
return -PyObject_Compare(w, v);
res = do_cmp(v, w);
if (res == NULL) {
PyErr_Clear();
return (v < w) ? -1 : 1;
}
if (res == NULL)
return -1;
if (!PyInt_Check(res)) {
Py_DECREF(res);
return (v < w) ? -1 : 1;
PyErr_SetString(PyExc_TypeError,
"comparison did not return an int");
return -1;
}
c = PyInt_AsLong(res);
Py_DECREF(res);
@ -296,11 +300,8 @@ PyObject_Compare(v, w)
if ((tp = v->ob_type) != w->ob_type) {
if (tp->tp_as_number != NULL &&
w->ob_type->tp_as_number != NULL) {
if (PyNumber_Coerce(&v, &w) != 0) {
PyErr_Clear();
/* XXX Should report the error,
XXX but the interface isn't there... */
}
if (PyNumber_Coerce(&v, &w) != 0)
return -1;
else {
int cmp = (*v->ob_type->tp_compare)(v, w);
Py_DECREF(v);