summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Hoyer <shoyer@google.com>2019-05-26 16:12:26 -0700
committerStephan Hoyer <shoyer@google.com>2019-05-26 16:12:26 -0700
commit5e8a4a11a900d9427368fe1f10c8086290ff01f1 (patch)
tree9eb6358ef5a85c1479de5f3ed6f00f60c3e39762
parent849e4d429951ad93691e6149d070b9d31536cc12 (diff)
downloadnumpy-5e8a4a11a900d9427368fe1f10c8086290ff01f1.tar.gz
DOC: caution against relying upon NumPy's implementation in subclasses
I think this is an important warning to include for subclass authors. Otherwise, we will be expanding our exposure of internal APIs as part of ``__array_function__``. All things being equal, it's great when things "just work" subclasses, but I don't want to guarantee it. In particular, I would be very displeased if ``__array_function__`` leads to NumPy adding more subclass specific hacks like always calling ``mean()`` inside ``median()`` (GH-3846). mhvk: please take a look.
-rw-r--r--doc/neps/nep-0018-array-function-protocol.rst16
1 files changed, 12 insertions, 4 deletions
diff --git a/doc/neps/nep-0018-array-function-protocol.rst b/doc/neps/nep-0018-array-function-protocol.rst
index 01bd22522..27a462239 100644
--- a/doc/neps/nep-0018-array-function-protocol.rst
+++ b/doc/neps/nep-0018-array-function-protocol.rst
@@ -349,19 +349,27 @@ with ``__array_ufunc__``, so ``numpy.ndarray`` also defines a
This method matches NumPy's dispatching rules, so for most part it is
possible to pretend that ``ndarray.__array_function__`` does not exist.
+The private ``_implementation`` attribute, defined below in the
+``array_function_dispatch`` decorator, allows us to avoid the special cases for
+NumPy arrays that were needed in the ``__array_ufunc__`` protocol.
The ``__array_function__`` protocol always calls subclasses before
superclasses, so if any ``ndarray`` subclasses are involved in an operation,
they will get the chance to override it, just as if any other argument
-overrides ``__array_function__``. However, the default behavior in an operation
+overrides ``__array_function__``. But the default behavior in an operation
that combines a base NumPy array and a subclass is different: if the subclass
returns ``NotImplemented``, NumPy's implementation of the function will be
called instead of raising an exception. This is appropriate since subclasses
are `expected to be substitutable <https://en.wikipedia.org/wiki/Liskov_substitution_principle>`_.
-Note that the private ``_implementation`` attribute, defined below in the
-``array_function_dispatch`` decorator, allows us to avoid the special cases for
-NumPy arrays that were needed in the ``__array_ufunc__`` protocol.
+We still caution authors of subclasses to exercise caution when relying
+upon details of NumPy's internal implementations. It is not always possible to
+write a perfectly substitutable ndarray subclass, e.g., in cases involving the
+creation of new arrays, not least because NumPy makes use of internal
+optimizations specialized to base NumPy arrays, e.g., code written in C. Even
+if NumPy's implementation happens to work today, it may not work in the future.
+In these cases, your recourse is to re-implement top-level NumPy functions via
+``__array_function__`` on your subclass.
Changes within NumPy functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^