[Numpy-discussion] numarray unfriendly to user defined types

Todd Miller jmiller at stsci.edu
Tue Sep 30 07:55:02 EDT 2003

On Fri, 2003-09-26 at 12:20, Tim Hochberg wrote:
> Todd Miller wrote:
> I'd make the same comment for this case as for the above case except 
> that all else being equal, subclasses should prevail over superclasses.
> >I don't have a solution yet, but am hopeful that more free candy will
> >fall from the sky... or YAGNI.  Perry pointed out that similar problems
> >exist for *any* Python class hierarchy, so we're not alone, and perhaps
> >should forget about this until it matters.  If someone sees an easy
> >fix,  now would be better than later.
> >  
> >
> Here's some quick thoughts. In order for this to work out sensibly you 
> want the order between classes to be transistive and you probably also 
> always want to be able to insert a class into the order between any two 
> classes  This is equivalent to deciding the op priority based on a 
> comparison based on some real number associated with each class. This 
> leads to something like:

Once again I think your ideas solve the problem, so thanks.  I have a
few things I wanted to bounce off you.

> class NumArrayFamily:
>     op_priority = 0.0
> # This makes it compatible with the current proposal , but isn't 
> strictly necessary.
> class DeferredToByNumarray(NumArrayFamily):
>     op_priority = 1000.0
> class NumArrary(..., NumArrayFamily):
>     # ...
>     def __add__(self, object):
>         if isinstance(object, NumArrayFamily):
>             if ((object.op_priority > self.object.op_priority) or
>                 (object.op_priority == self.object.op_priority) and 
> issubclass(object, self.__class__)):
>                     return other.__radd__(self)
>         return ufunc.add(self, other)
> class MySubclassOfNumarray(NumArray):
>     op_priority = 10.0 # deffered to by NumArray, but defers to 
> DeferredToByNumarray classes.

As I understand it, 2.2 new style object subclass r-operators
automatically get priority (subclass.__radd__ is called in preference to
superclass.__add__).  I think this has two implications:

1) the ==/subclass term won't work, because __add__ will never get

2) we have to redefine __radd__ as well to implement the priority
scheme.   I'm not sure the isinstance is necessary for __radd__,  but I
like the symmetry.

How does this look:

class DeferredToByNumArray: # name seems a little off now, but whatever

class NumArray(..., DeferredToByNumArray):
	op_priority = 0

	def __add__(self, object):
		if (isinstance(object, DeferredToByNumArray) and 
		    object.op_priority > self.op_priority):
			return object.__radd__(self)
		return ufunc.add(self, object)

	def __radd__(self, object):
		if (isinstance(object, DeferredToByNumArray) and
		    object.op_priority > self.op_priority):
			return object.__add__(self)
		return ufunc.add(object, self)

class MyForeignClass(DeferredToNumArray):
	op_priority = 1.0

class MySubclassOfNumArray(NumArray):
	op_priority = -1.0

> Of course the user still has to be careful to make sure the priority 
> order makes sense and you could have big problems when combining 
> packages with disprate ideas about priority levels, but I'm not sure how 
> you can get away from that.

As long as there's a scheme in place to resolve potential conflicts with
a little discussion,  I think your solution is already ahead of the

I told Colin last week I'd raise this issue on c.l.py.  I have decided
not to (although someone else could obviously do it if they are still
concerned about it),  because (a) the problem is solved,  (b) explaining
the problem well enough to get usable input is difficult and I've got
other stuff to do.

Thanks again for these ideas,


Todd Miller <jmiller at stsci.edu>

More information about the NumPy-Discussion mailing list