diff options
author | Guido van Rossum <guido@python.org> | 2001-10-01 17:18:22 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-10-01 17:18:22 (GMT) |
commit | 55f2099b2f31cfab6c881989f60552c3621ce752 (patch) | |
tree | 4179e294bc49f63bfba6fd7cac90f42fec57e232 | |
parent | 89c4264792da06293b197e14f581763f46138935 (diff) | |
download | cpython-55f2099b2f31cfab6c881989f60552c3621ce752.zip cpython-55f2099b2f31cfab6c881989f60552c3621ce752.tar.gz cpython-55f2099b2f31cfab6c881989f60552c3621ce752.tar.bz2 |
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.
-rw-r--r-- | Objects/typeobject.c | 69 |
1 files changed, 41 insertions, 28 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ec36bfd..8a11dff 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2693,9 +2693,21 @@ static PyObject * \ FUNCNAME(PyObject *self, PyObject *other) \ { \ 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 && \ self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ 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( \ self, OPSTR, &cache_str, "(O)", other); \ if (r != Py_NotImplemented || \ @@ -2703,8 +2715,7 @@ FUNCNAME(PyObject *self, PyObject *other) \ return r; \ Py_DECREF(r); \ } \ - if (other->ob_type->tp_as_number != NULL && \ - other->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \ + if (do_other) { \ return call_maybe( \ other, ROPSTR, &rcache_str, "(O)", self); \ } \ @@ -2785,7 +2796,7 @@ slot_sq_contains(PyObject *self, PyObject *value) PyObject *func, *res, *args; static PyObject *contains_str; - func = lookup_method(self, "__contains__", &contains_str); + func = lookup_maybe(self, "__contains__", &contains_str); if (func != NULL) { args = Py_BuildValue("(O)", value); @@ -2800,8 +2811,9 @@ slot_sq_contains(PyObject *self, PyObject *value) return -1; return PyObject_IsTrue(res); } + else if (PyErr_Occurred()) + return -1; else { - PyErr_Clear(); return _PySequence_IterSearch(self, value, PY_ITERSEARCH_CONTAINS); } @@ -2866,23 +2878,23 @@ slot_nb_nonzero(PyObject *self) PyObject *func, *res; static PyObject *nonzero_str, *len_str; - func = lookup_method(self, "__nonzero__", &nonzero_str); + func = lookup_maybe(self, "__nonzero__", &nonzero_str); if (func == NULL) { - PyErr_Clear(); - func = lookup_method(self, "__len__", &len_str); - } - - if (func != NULL) { - res = PyObject_CallObject(func, NULL); - Py_DECREF(func); - if (res == NULL) + if (PyErr_Occurred()) return -1; - return PyObject_IsTrue(res); - } - else { - PyErr_Clear(); - return 1; + func = lookup_maybe(self, "__len__", &len_str); + if (func == NULL) { + if (PyErr_Occurred()) + return -1; + else + return 1; + } } + res = PyObject_CallObject(func, NULL); + Py_DECREF(func); + if (res == NULL) + return -1; + return PyObject_IsTrue(res); } SLOT0(slot_nb_invert, "__invert__") @@ -2907,20 +2919,21 @@ slot_nb_coerce(PyObject **a, PyObject **b) return -1; if (r == Py_NotImplemented) { Py_DECREF(r); - return 1; } - if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { - PyErr_SetString(PyExc_TypeError, + else { + if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { + PyErr_SetString(PyExc_TypeError, "__coerce__ didn't return a 2-tuple"); + Py_DECREF(r); + return -1; + } + *a = PyTuple_GET_ITEM(r, 0); + Py_INCREF(*a); + *b = PyTuple_GET_ITEM(r, 1); + Py_INCREF(*b); Py_DECREF(r); - return -1; + return 0; } - *a = PyTuple_GET_ITEM(r, 0); - Py_INCREF(*a); - *b = PyTuple_GET_ITEM(r, 1); - Py_INCREF(*b); - Py_DECREF(r); - return 0; } if (other->ob_type->tp_as_number != NULL && other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { |