@@ -349,19 +349,27 @@ with ``__array_ufunc__``, so ``numpy.ndarray`` also defines a
349
349
350
350
This method matches NumPy's dispatching rules, so for most part it is
351
351
possible to pretend that ``ndarray.__array_function__ `` does not exist.
352
+ The private ``_implementation `` attribute, defined below in the
353
+ ``array_function_dispatch `` decorator, allows us to avoid the special cases for
354
+ NumPy arrays that were needed in the ``__array_ufunc__ `` protocol.
352
355
353
356
The ``__array_function__ `` protocol always calls subclasses before
354
357
superclasses, so if any ``ndarray `` subclasses are involved in an operation,
355
358
they will get the chance to override it, just as if any other argument
356
- overrides ``__array_function__ ``. However, the default behavior in an operation
359
+ overrides ``__array_function__ ``. But the default behavior in an operation
357
360
that combines a base NumPy array and a subclass is different: if the subclass
358
361
returns ``NotImplemented ``, NumPy's implementation of the function will be
359
362
called instead of raising an exception. This is appropriate since subclasses
360
363
are `expected to be substitutable <https://en.wikipedia.org/wiki/Liskov_substitution_principle >`_.
361
364
362
- Note that the private ``_implementation `` attribute, defined below in the
363
- ``array_function_dispatch `` decorator, allows us to avoid the special cases for
364
- NumPy arrays that were needed in the ``__array_ufunc__ `` protocol.
365
+ We still caution authors of subclasses to exercise caution when relying
366
+ upon details of NumPy's internal implementations. It is not always possible to
367
+ write a perfectly substitutable ndarray subclass, e.g., in cases involving the
368
+ creation of new arrays, not least because NumPy makes use of internal
369
+ optimizations specialized to base NumPy arrays, e.g., code written in C. Even
370
+ if NumPy's implementation happens to work today, it may not work in the future.
371
+ In these cases, your recourse is to re-implement top-level NumPy functions via
372
+ ``__array_function__ `` on your subclass.
365
373
366
374
Changes within NumPy functions
367
375
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0 commit comments