Skip to content

Commit bec7972

Browse files
committed
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.
1 parent e310b12 commit bec7972

1 file changed

Lines changed: 36 additions & 1 deletion

File tree

Objects/typeobject.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2838,6 +2838,40 @@ FUNCNAME(PyObject *self, ARG1TYPE arg1) \
28382838
return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \
28392839
}
28402840

2841+
/* Boolean helper for SLOT1BINFULL().
2842+
right.__class__ is a nontrivial subclass of left.__class__. */
2843+
static int
2844+
method_is_overloaded(PyObject *left, PyObject *right, char *name)
2845+
{
2846+
PyObject *a, *b;
2847+
int ok;
2848+
2849+
b = PyObject_GetAttrString((PyObject *)(right->ob_type), name);
2850+
if (b == NULL) {
2851+
PyErr_Clear();
2852+
/* If right doesn't have it, it's not overloaded */
2853+
return 0;
2854+
}
2855+
2856+
a = PyObject_GetAttrString((PyObject *)(left->ob_type), name);
2857+
if (a == NULL) {
2858+
PyErr_Clear();
2859+
Py_DECREF(b);
2860+
/* If right has it but left doesn't, it's overloaded */
2861+
return 1;
2862+
}
2863+
2864+
ok = PyObject_RichCompareBool(a, b, Py_NE);
2865+
Py_DECREF(a);
2866+
Py_DECREF(b);
2867+
if (ok < 0) {
2868+
PyErr_Clear();
2869+
return 0;
2870+
}
2871+
2872+
return ok;
2873+
}
2874+
28412875

28422876
#define SLOT1BINFULL(FUNCNAME, TESTFUNC, SLOTNAME, OPSTR, ROPSTR) \
28432877
static PyObject * \
@@ -2851,7 +2885,8 @@ FUNCNAME(PyObject *self, PyObject *other) \
28512885
self->ob_type->tp_as_number->SLOTNAME == TESTFUNC) { \
28522886
PyObject *r; \
28532887
if (do_other && \
2854-
PyType_IsSubtype(other->ob_type, self->ob_type)) { \
2888+
PyType_IsSubtype(other->ob_type, self->ob_type) && \
2889+
method_is_overloaded(self, other, ROPSTR)) { \
28552890
r = call_maybe( \
28562891
other, ROPSTR, &rcache_str, "(O)", self); \
28572892
if (r != Py_NotImplemented) \

0 commit comments

Comments
 (0)