mirror of https://github.com/python/cpython
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().
This commit is contained in:
parent
cd118803b5
commit
613f24fd73
|
@ -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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue