import numpy as np

class ArrayWrapper(object):

    __array_priority__ = 20.0

    def __init__(self, shape, array=None):
        self.array = np.ones(shape)
        if not array is None:
            self.array = array
    
    def __array__(self):
        print "Calling __array__ on %r" % hex(id(self))
        return self.array
    
    def __array_wrap__(self, obj, context=None):
        print "Calling __array_wrap__ on %r" % hex(id(self))
        return ArrayWrapper(obj.shape, obj)

# This works fine (c comes back as an ArrayWrapper)
a = ArrayWrapper(10)
b = ArrayWrapper(10)
c = np.add(a, b)
print c

# Passing in an ndarray as the return array causes __array_wrap__ to not 
# be called.  Thus, you get back an ndarray.
d = np.empty_like(a.array)
d = np.add(a, b, d)
print d

# This fails saying that the return array must be an ArrayType
d = ArrayWrapper(10)
d = np.add(a, b, d)
print d