BUG: core: ensure __r*__ has precedence over __numpy_ufunc__

Add a special case to the implementation of `ndarray.__mul__` et al. that refuses to work on other objects that are not ndarray subclasses and implement both `__numpy_ufunc__` and `__r*__`.

This way, execution passes first to the custom `__r*__` method, which makes it possible to have e.g. `__mul__` and np.multiply do different things.

Additionally, disable one `__array_priority__` special case handling when also `__numpy_ufunc__` is defined (which may have been the reason why `__rmul__` continued to work in scipy.sparse matrices).

Addresses gh-3812

Feedback welcome --- I think this solves the issue without being too magical, but YMMV