Miscellaneous code fiddling:

- SLOT1BINFULL() macro: changed this to check for __rop__ overriding
  __op__, like binary_op1() in abstract.c -- the latter only calls the
  slot function once if both types use the same slot function, so the
  slot function must make both calls -- which it already did for the
  __op__, __rop__ order, but not yet for the __rop__, __op__ order
  when B.__class__ is a subclass of A.__class__.

- slot_sq_contains(), slot_nb_nonzero(): use lookup_maybe() rather
  than lookup_method() which sets an exception which we then clear.

- slot_nb_coerce(): don't give up when left argument's __coerce__
returns NotImplemented, but give the right argument a chance.
This commit is contained in:
Guido van Rossum 2001-10-01 17:18:22 +00:00
parent 89c4264792
commit 55f2099b2f
1 changed files with 41 additions and 28 deletions

View File

@ -2693,9 +2693,21 @@ static PyObject * \
FUNCNAME(PyObject *self, PyObject *other) \ FUNCNAME(PyObject *self, PyObject *other) \
{ \ { \
static PyObject *cache_str, *rcache_str; \ static PyObject *cache_str, *rcache_str; \
int do_other = self->ob_type != other->ob_type && \
other->ob_type->tp_as_number != NULL && \
other->ob_type->tp_as_number->SLOTNAME == TESTFUNC; \
if (self->ob_type->tp_as_number != NULL && \ if (self->ob_type->tp_as_number != NULL && \
self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
PyObject *r; \ PyObject *r; \
if (do_other && \
PyType_IsSubtype(other->ob_type, self->ob_type)) { \
r = call_maybe( \
other, ROPSTR, &rcache_str, "(O)", self); \
if (r != Py_NotImplemented) \
return r; \
Py_DECREF(r); \
do_other = 0; \
} \
r = call_maybe( \ r = call_maybe( \
self, OPSTR, &cache_str, "(O)", other); \ self, OPSTR, &cache_str, "(O)", other); \
if (r != Py_NotImplemented || \ if (r != Py_NotImplemented || \
@ -2703,8 +2715,7 @@ FUNCNAME(PyObject *self, PyObject *other) \
return r; \ return r; \
Py_DECREF(r); \ Py_DECREF(r); \
} \ } \
if (other->ob_type->tp_as_number != NULL && \ if (do_other) { \
other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
return call_maybe( \ return call_maybe( \
other, ROPSTR, &rcache_str, "(O)", self); \ other, ROPSTR, &rcache_str, "(O)", self); \
} \ } \
@ -2785,7 +2796,7 @@ slot_sq_contains(PyObject *self, PyObject *value)
PyObject *func, *res, *args; PyObject *func, *res, *args;
static PyObject *contains_str; static PyObject *contains_str;
func = lookup_method(self, "__contains__", &contains_str); func = lookup_maybe(self, "__contains__", &contains_str);
if (func != NULL) { if (func != NULL) {
args = Py_BuildValue("(O)", value); args = Py_BuildValue("(O)", value);
@ -2800,8 +2811,9 @@ slot_sq_contains(PyObject *self, PyObject *value)
return -1; return -1;
return PyObject_IsTrue(res); return PyObject_IsTrue(res);
} }
else if (PyErr_Occurred())
return -1;
else { else {
PyErr_Clear();
return _PySequence_IterSearch(self, value, return _PySequence_IterSearch(self, value,
PY_ITERSEARCH_CONTAINS); PY_ITERSEARCH_CONTAINS);
} }
@ -2866,24 +2878,24 @@ slot_nb_nonzero(PyObject *self)
PyObject *func, *res; PyObject *func, *res;
static PyObject *nonzero_str, *len_str; static PyObject *nonzero_str, *len_str;
func = lookup_method(self, "__nonzero__", &nonzero_str); func = lookup_maybe(self, "__nonzero__", &nonzero_str);
if (func == NULL) { if (func == NULL) {
PyErr_Clear(); if (PyErr_Occurred())
func = lookup_method(self, "__len__", &len_str); return -1;
func = lookup_maybe(self, "__len__", &len_str);
if (func == NULL) {
if (PyErr_Occurred())
return -1;
else
return 1;
}
} }
if (func != NULL) {
res = PyObject_CallObject(func, NULL); res = PyObject_CallObject(func, NULL);
Py_DECREF(func); Py_DECREF(func);
if (res == NULL) if (res == NULL)
return -1; return -1;
return PyObject_IsTrue(res); return PyObject_IsTrue(res);
} }
else {
PyErr_Clear();
return 1;
}
}
SLOT0(slot_nb_invert, "__invert__") SLOT0(slot_nb_invert, "__invert__")
SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__") SLOT1BIN(slot_nb_lshift, nb_lshift, "__lshift__", "__rlshift__")
@ -2907,8 +2919,8 @@ slot_nb_coerce(PyObject **a, PyObject **b)
return -1; return -1;
if (r == Py_NotImplemented) { if (r == Py_NotImplemented) {
Py_DECREF(r); Py_DECREF(r);
return 1;
} }
else {
if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"__coerce__ didn't return a 2-tuple"); "__coerce__ didn't return a 2-tuple");
@ -2922,6 +2934,7 @@ slot_nb_coerce(PyObject **a, PyObject **b)
Py_DECREF(r); Py_DECREF(r);
return 0; return 0;
} }
}
if (other->ob_type->tp_as_number != NULL && if (other->ob_type->tp_as_number != NULL &&
other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) {
PyObject *r; PyObject *r;