It's a fact: for binary operators, *under certain circumstances*,
__rop__ now takes precendence over __op__.  Those circumstances are:

  - Both arguments are new-style classes
  - Both arguments are new-style numbers
  - Their implementation slots for tp_op differ
  - Their types differ
  - The right argument's type is a subtype of the left argument's type

Also did this for the ternary operator (pow) -- only the binary case
is dealt with properly though, since __rpow__ is not supported anyway.
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 2c5e7a4..22ae09a 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -1,8 +1,12 @@
-# Test descriptor-related enhancements
+# Test enhancements related to descriptors and new-style classes
 
 from test_support import verify, verbose, TestFailed, TESTFN
 from copy import deepcopy
 
+def vereq(a, b):
+    if a != b:
+        raise TestFailed, "%r != %r" % (a, b)
+
 def testunop(a, res, expr="len(a)", meth="__len__"):
     if verbose: print "checking", expr
     dict = {'a': a}
@@ -2133,6 +2137,36 @@
     a.bar.append(4)
     verify(d.bar == [1,2,3])
 
+def binopoverride():
+    if verbose: print "Testing overrides of binary operations..."
+    class I(int):
+        def __repr__(self):
+            return "I(%r)" % int(self)
+        def __add__(self, other):
+            return I(int(self) + int(other))
+        __radd__ = __add__
+        def __pow__(self, other, mod=None):
+            if mod is None:
+                return I(pow(int(self), int(other)))
+            else:
+                return I(pow(int(self), int(other), int(mod)))
+        def __rpow__(self, other, mod=None):
+            if mod is None:
+                return I(pow(int(other), int(self), mod))
+            else:
+                return I(pow(int(other), int(self), int(mod)))
+            
+    vereq(`I(1) + I(2)`, "I(3)")
+    vereq(`I(1) + 2`, "I(3)")
+    vereq(`1 + I(2)`, "I(3)")
+    vereq(`I(2) ** I(3)`, "I(8)")
+    vereq(`2 ** I(3)`, "I(8)")
+    vereq(`I(2) ** 3`, "I(8)")
+    vereq(`pow(I(2), I(3), I(5))`, "I(3)")
+    class S(str):
+        def __eq__(self, other):
+            return self.lower() == other.lower()
+
 
 def test_main():
     lists()
@@ -2178,6 +2212,7 @@
     setclass()
     pickles()
     copies()
+    binopoverride()
     if verbose: print "All OK"
 
 if __name__ == "__main__":