[Numpy-discussion] ndarray special methods should raise NotImplemented instead of TypeError
hoytak at stat.washington.edu
Sun Mar 13 17:24:01 EDT 2011
Apologies for cross posting -- I posted this to the scipy developer
list a few days ago, since it's really a development question, but
after getting no response I reread my question and realized it was a
bit unclear and also was more appropriate for numpy. So here goes.
Currently, the numerical special methods of the ndarray class, like
__add__, __gt__, __mul__, etc., raise a TypeError when they encounter
a class or type they don't understand. I do not think this is the
correct behavior. Instead, they should raise a NotImplemented error.
Here's the logic behind this. Classes can also define right operators
that correspond to each of the above methods -- e.g. __radd__, __le__,
__rmul__. However, these are only called under three conditions (see
1. When the left object doesn't implement the left operator.
2. When the left object raises a NotImplemented exception.
3. When the right object is a subclass of the left object. In this
case, the left operator method is never called.
In my use case, I've been working on implementing a matrix-like class
of symbolic objects that have to interact seamlessly with numpy
arrays. It's a wrapper for CPlex's Concert library, which effectively
presents variables in an optimization problem as symbolic C++ objects
that can be used to build the model. I'm trying to wrap this to work
with numpy (I'd be happy to share my code when it's done) and the
current behavior is causing a bit of a headache.
Consider working with A + X, where A is an ndarray and X is an
instance of my class that represents my symbolic objects, and let's
suppose my matrix class implements __radd__ sensibly. Obviously, 1.
doesn't apply here. If I go with 2., a TypeError is raised, which
blows things apart. So the only solution I have is 3.
However, it isn't possible for me to use the underlying array
machinery provided by ndarray, as the python class simply wraps other
C++ containers. Thus, if I subclass ndarray, the underlying array is
meaningless -- while I do implement slicing and various other
array-like methods, the only reason I'm subclassing ndarray is (3).
The big problem with this is that many of the attributes and methods
of ndarray don't make sense for my class, so I have to cover them up
with dummy methods that simply raise exceptions. Doable, but far from
For now, I'm doing (3) to get it to work, but it would be really nice
if ndarray would raise a NotImplemented error instead of a TypeError.
Is there any reason / use case justifying the current behavior? Would
it be possible/easy to change it?
+ Hoyt Koepke
+ University of Washington Department of Statistics
+ hoytak at gmail.com
More information about the NumPy-Discussion