Index: Lib/test/test_descr.py =================================================================== --- Lib/test/test_descr.py (revision 54690) +++ Lib/test/test_descr.py (working copy) @@ -2571,6 +2571,25 @@ except: pass + class NotReallyInt(int): + """ + Bug #1694663: there used to be a problem when a class had slot + wrappers for special methods, and those wrappers weren't from + the base class. The problem also showed when a slot wrapper had + an unexpected conversion function. + """ + __mul__ = float.__add__ + __pow__ = int.__add__ + + try: + NotReallyInt(3) * 3 + except TypeError: + pass + else: + raise TestFailed("NotReallyInt(3) * 3 should raise a TypeError " + "because NotReallyInt.__mul__ == float.__add__") + vereq(NotReallyInt(3) ** 3, 6) + def keywords(): if verbose: print "Testing keyword args to basic type constructors ..." Index: Objects/typeobject.c =================================================================== --- Objects/typeobject.c (revision 54690) +++ Objects/typeobject.c (working copy) @@ -5546,14 +5546,11 @@ generic = p->function; d = (PyWrapperDescrObject *)descr; if (d->d_base->wrapper == p->wrapper && - PyType_IsSubtype(type, d->d_type)) - { - if (specific == NULL || - specific == d->d_wrapped) - specific = d->d_wrapped; - else - use_generic = 1; - } + PyType_IsSubtype(type, d->d_type) && + (specific == NULL || specific == d->d_wrapped)) + specific = d->d_wrapped; + else + use_generic = 1; } else if (descr->ob_type == &PyCFunction_Type && PyCFunction_GET_FUNCTION(descr) ==