Blake T. Garretson <bl*************@gmail.com> 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 <ni**@craig-wood.com> --
http://www.craig-wood.com/nick