Blake T. Garretson <[EMAIL PROTECTED]> wrote: > I'm having some issues with decimal.Decimal objects playing nice with > custom data types. I have my own matrix and rational classes which > implement __add__ and __radd__. They know what to do with Decimal > objects and react appropriately. > > The problem is that they only work with Decimals if the custom type is > on the left (and therefore __add__ gets called), but NOT if the Decimal > is on the left. The Decimal immediately throws the usual "TypeError: > You can interact Decimal only with int, long or Decimal data types." > without even trying my __radd__ method to see if my custom type can > handle Decimals. > > From the Python docs (specifically sections 3.3.7 and 3.3.8), I thought > that the left object should try its own __add__, and if it doesn't know > what to do, THEN try the right object's __radd__ method. I guess > Decimal objects don't do this? Is there a way to change this behavior? > If Decimal objects prematurely throw a TypeError before trying the > __rop__, is Decimal broken, or was it designed this way? I think I'm > missing something...
It looks like from reading 3.3.8 if decimal raised a NotImplemented exception instead of a TypeError then it would work. For objects x and y, first x.__op__(y) is tried. If this is not implemented or returns NotImplemented, y.__rop__(x) is tried. If this is also not implemented or returns NotImplemented, a TypeError exception is raised. But see the following exception: Exception to the previous item: if the left operand is an instance of a built-in type or a new-style class, and the right operand is an instance of a proper subclass of that type or class, the right operand's __rop__() method is tried before the left operand's __op__() method. This is done so that a subclass can completely override binary operators. Otherwise, the left operand's __op__ method would always accept the right operand: when an instance of a given class is expected, an instance of a subclass of that class is always acceptable. You could try this with a local copy of decimal.py since it is written in Python. -- Nick Craig-Wood <[EMAIL PROTECTED]> -- http://www.craig-wood.com/nick -- http://mail.python.org/mailman/listinfo/python-list