summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-10-01 17:18:22 (GMT)
committerGuido van Rossum <guido@python.org>2001-10-01 17:18:22 (GMT)
commit55f2099b2f31cfab6c881989f60552c3621ce752 (patch)
tree4179e294bc49f63bfba6fd7cac90f42fec57e232
parent89c4264792da06293b197e14f581763f46138935 (diff)
downloadcpython-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.c69
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) {