It is no longer necessary to coerce both sides of an operator to the same class or type. A class may still provide a __coerce__ method, but this method may return objects of different types or classes if it feels like it. If no __coerce__ is defined, any argument type or class is acceptable.
In order to make it possible to implement binary operators where the right-hand side is a class instance but the left-hand side is not, without using coercions, right-hand versions of all binary operators may be defined. These have an `r' prepended to their name, e.g. __radd__.
For example, here's a very simple class for representing times. Times are initialized from a number of seconds (like time.time()). Times are printed like this: Wed Mar 15 12:28:48 1995. Subtracting two Times gives their difference in seconds. Adding or subtracting a Time and a number gives a new Time. You can't add two times, nor can you subtract a Time from a number.
import time class Time: def __init__(self, seconds): self.seconds = seconds def __repr__(self): return time.ctime(self.seconds) def __add__(self, x): return Time(self.seconds + x) __radd__ = __add__ # support for x+t def __sub__(self, x): if hasattr(x, 'seconds'): # test if x could be a Time return self.seconds - x.seconds else: return self.seconds - x now = Time(time.time()) tomorrow = 24*3600 + now yesterday = now - today print tomorrow - yesterday # prints 172800