From 613f24fd73b90c90b219aa764e8e37b35cff717a Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 6 Jan 2003 23:00:59 +0000 Subject: [PATCH] Add a test for a feature added in rev. 2.82 of typeobject.c: - SLOT1BINFULL() macro: changed this to check for __rop__ overriding __op__, like binary_op1() in abstract.c -- the latter only calls the slot function once if both types use the same slot function, so the slot function must make both calls -- which it already did for the __op__, __rop__ order, but not yet for the __rop__, __op__ order when B.__class__ is a subclass of A.__class__. Also test the refinement added in rev. 2.201 that fixes the problem reported in SF bug #623669. Also test a similar provision in abstract.c's binary_op1(). --- Lib/test/test_descr.py | 53 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 19fd7749319..974fd25cd70 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3634,6 +3634,58 @@ def mutable_names(): C.__name__ = 'D.E' vereq((C.__module__, C.__name__), (mod, 'D.E')) +def subclass_right_op(): + if verbose: + print "Testing correct dispatch of subclass overloading __r__..." + + # This code tests various cases where right-dispatch of a subclass + # should be preferred over left-dispatch of a base class. + + # Case 1: subclass of int; this tests code in abstract.c::binary_op1() + + class B(int): + def __div__(self, other): + return "B.__div__" + def __rdiv__(self, other): + return "B.__rdiv__" + + vereq(B(1) / 1, "B.__div__") + vereq(1 / B(1), "B.__rdiv__") + + # Case 2: subclass of object; this is just the baseline for case 3 + + class C(object): + def __div__(self, other): + return "C.__div__" + def __rdiv__(self, other): + return "C.__rdiv__" + + vereq(C(1) / 1, "C.__div__") + vereq(1 / C(1), "C.__rdiv__") + + # Case 3: subclass of new-style class; here it gets interesting + + class D(C): + def __div__(self, other): + return "D.__div__" + def __rdiv__(self, other): + return "D.__rdiv__" + + vereq(D(1) / C(1), "D.__div__") + vereq(C(1) / D(1), "D.__rdiv__") + + # Case 4: this didn't work right in 2.2.2 and 2.3a1 + + class E(C): + pass + + vereq(E.__rdiv__, C.__rdiv__) + + vereq(E(1) / 1, "C.__div__") + vereq(1 / E(1), "C.__rdiv__") + vereq(E(1) / C(1), "C.__div__") + vereq(C(1) / E(1), "C.__div__") # This one would fail + def test_main(): do_this_first() @@ -3718,6 +3770,7 @@ def test_main(): test_mutable_bases_with_failing_mro() test_mutable_bases_catch_mro_conflict() mutable_names() + subclass_right_op() if verbose: print "All OK"