On Wed, Feb 22, 2017 at 6:31 AM, Marten van Kerkwijk <m.h.vankerkwijk@gmail.com> wrote:
It seems to me entirely logical (but then it would, I suggested it
before...) that we allow opting out by setting `__array_ufunc__` to
None; in that case, binops return NotImplemented and ufuncs raise
errors. (In addtion, or alternatively, one could allow setting
`__array__` to None, which would generally disable something to be
turned into an array object).

This is indeed appealing, but I recall this was still a point of contention because it leaves intact two different ways to override arithmetic involving numpy arrays. Mimicking all this logic on classes designed to wrap well-behaved array-like classes (e.g., xarray, which can wrap NumPy or Dask arrays) could be painful -- it's easier to just call np.add and let it handle all the dispatching rather than also worrying about NotImplemented. That said, I think the opt-out is probably OK, as long we make it clear that defining __array_ufunc__ to do arithmetic overriding is the preferred solution (and provide appropriate Mixin classes to make this easier).

Just to be clear: if __array__ = None but __array_ufunc__ is defined, this would be a class that defines array-like operations but can't be directly converted into a NumPy array? For example, a scipy.sparse matrix?