summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-01-06 23:00:59 (GMT)
committerGuido van Rossum <guido@python.org>2003-01-06 23:00:59 (GMT)
commit613f24fd73b90c90b219aa764e8e37b35cff717a (patch)
treeabaff2f060aa81e22e0a8c636af17090ca632827 /Lib/test
parentcd118803b5aa124bcfd8a12f28c22c4cf37c9de7 (diff)
downloadcpython-613f24fd73b90c90b219aa764e8e37b35cff717a.zip
cpython-613f24fd73b90c90b219aa764e8e37b35cff717a.tar.gz
cpython-613f24fd73b90c90b219aa764e8e37b35cff717a.tar.bz2
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().
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_descr.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 19fd774..974fd25 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<op>__..."
+
+ # 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"