]> granicus.if.org Git - python/commitdiff
Add a refinement to SLOT1BINFULL() that fixes the problem reported in
authorGuido van Rossum <guido@python.org>
Mon, 6 Jan 2003 22:57:47 +0000 (22:57 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 6 Jan 2003 22:57:47 +0000 (22:57 +0000)
SF bug #623669: only try (e.g.) __rdiv__ before __div__ if the right
class actually overrides it.

Objects/typeobject.c

index f05cf7c97ce2614e2169829fc9a1cdab4920e3dd..2de539515c1a419ac7915b2cc780aada7dd5c9c0 100644 (file)
@@ -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) \