summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-01-06 22:57:47 (GMT)
committerGuido van Rossum <guido@python.org>2003-01-06 22:57:47 (GMT)
commitcd118803b5aa124bcfd8a12f28c22c4cf37c9de7 (patch)
treec90edf29da98b81851df73499ffcc9dafee98c19 /Objects
parent0a2f849b791d13cf0dde97dce2e71a19e2d60465 (diff)
downloadcpython-cd118803b5aa124bcfd8a12f28c22c4cf37c9de7.zip
cpython-cd118803b5aa124bcfd8a12f28c22c4cf37c9de7.tar.gz
cpython-cd118803b5aa124bcfd8a12f28c22c4cf37c9de7.tar.bz2
Add a refinement to SLOT1BINFULL() that fixes the problem reported in
SF bug #623669: only try (e.g.) __rdiv__ before __div__ if the right class actually overrides it.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index f05cf7c..2de5395 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -3494,6 +3494,40 @@ FUNCNAME(PyObject *self, ARG1TYPE arg1) \
return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
}
+/* Boolean helper for SLOT1BINFULL().
+ right.__class__ is a nontrivial subclass of left.__class__. */
+static int
+method_is_overloaded(PyObject *left, PyObject *right, char *name)
+{
+ PyObject *a, *b;
+ int ok;
+
+ b = PyObject_GetAttrString((PyObject *)(right->ob_type), name);
+ if (b == NULL) {
+ PyErr_Clear();
+ /* If right doesn't have it, it's not overloaded */
+ return 0;
+ }
+
+ a = PyObject_GetAttrString((PyObject *)(left->ob_type), name);
+ if (a == NULL) {
+ PyErr_Clear();
+ Py_DECREF(b);
+ /* If right has it but left doesn't, it's overloaded */
+ return 1;
+ }
+
+ ok = PyObject_RichCompareBool(a, b, Py_NE);
+ Py_DECREF(a);
+ Py_DECREF(b);
+ if (ok < 0) {
+ PyErr_Clear();
+ return 0;
+ }
+
+ return ok;
+}
+
#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
static PyObject * \
@@ -3507,7 +3541,8 @@ FUNCNAME(PyObject *self, PyObject *other) \
self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
PyObject *r; \
if (do_other && \
- PyType_IsSubtype(other->ob_type, self->ob_type)) { \
+ PyType_IsSubtype(other->ob_type, self->ob_type) && \
+ method_is_overloaded(self, other, ROPSTR)) { \
r = call_maybe( \
other, ROPSTR, &rcache_str, "(O)", self); \
if (r != Py_NotImplemented) \