From bec7972a2cc1dcc9b5460c9182de87c5d08321d9 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 7 Jan 2003 21:47:44 +0000 Subject: [PATCH] Backport typeobject.c revision 2.201 plus associated tests from 2.3: 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. --- Objects/typeobject.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8b08bc0749c9..fa255985c868 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2838,6 +2838,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 * \ @@ -2851,7 +2885,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) \ -- 2.47.3