<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Monaco;
panose-1:0 0 0 0 0 0 0 0 0 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
pre
{mso-style-priority:99;
mso-style-link:"HTML Preformatted Char";
margin:0cm;
margin-bottom:.0001pt;
font-size:10.0pt;
font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0cm;
mso-margin-bottom-alt:auto;
margin-left:0cm;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle18
{mso-style-type:personal;
font-family:"Calibri",sans-serif;
color:windowtext;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
span.HTMLPreformattedChar
{mso-style-name:"HTML Preformatted Char";
mso-style-priority:99;
mso-style-link:"HTML Preformatted";
font-family:"Courier New";}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
{page:WordSection1;}
--></style></head><body lang=DE link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>The full-text of the NEP is quoted below, apologies for not including it earlier:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>============================================================<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>NEP 31 — Context-local and global overrides of the NumPy API<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>============================================================<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>:Author: Hameer Abbasi <habbasi@quansight.com><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>:Author: Ralf Gommers <rgommers@quansight.com><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>:Author: Peter Bell <peterbell10@live.co.uk><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>:Status: Draft<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>:Type: Standards Track<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>:Created: 2019-08-22<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Abstract<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>--------<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>This NEP proposes to make all of NumPy's public API overridable via an<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>extensible backend mechanism, using a library called ``uarray`` `[1]`_<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>``uarray`` provides global and context-local overrides, as well as a dispatch<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>mechanism similar to NEP-18 `[2]`_. First experiences with ``__array_function__``<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>show that it is necessary to be able to override NumPy functions that<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>*do not take an array-like argument*, and hence aren't overridable via<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>``__array_function__``. The most pressing need is array creation and coercion<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>functions - see e.g. NEP-30 `[9]`_.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>This NEP proposes to allow, in an opt-in fashion, overriding any part of the NumPy API.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>It is intended as a comprehensive resolution to NEP-22 `[3]`_, and obviates the need to<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>add an ever-growing list of new protocols for each new type of function or object that needs<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>to become overridable.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Motivation and Scope<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>--------------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The motivation behind ``uarray`` is manyfold: First, there have been several attempts to allow<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>dispatch of parts of the NumPy API, including (most prominently), the ``__array_ufunc__`` protocol<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>in NEP-13 `[4]`_, and the ``__array_function__`` protocol in NEP-18 `[2]`_, but this has shown the<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>need for further protocols to be developed, including a protocol for coercion (see `[5]`_). The reasons<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>these overrides are needed have been extensively discussed in the references, and this NEP will not<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>attempt to go into the details of why these are needed. Another pain point requiring yet another<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>protocol is the duck-array protocol (see `[9]`_).<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>This NEP takes a more holistic approach: It assumes that there are parts of the API that need to be<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>overridable, and that these will grow over time. It provides a general framework and a mechanism to<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>avoid a design of a new protocol each time this is required.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>This NEP proposes the following: That ``unumpy`` `[8]`_ becomes the recommended override mechanism<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>for the parts of the NumPy API not yet covered by ``__array_function__`` or ``__array_ufunc__``,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>and that ``uarray`` is vendored into a new namespace within NumPy to give users and downstream dependencies<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>access to these overrides. This vendoring mechanism is similar to what SciPy decided to do for<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>making ``scipy.fft`` overridable (see `[10]`_).<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Detailed description<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>--------------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>**Note:** *This section will not attempt to explain the specifics or the mechanism of ``uarray``,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>that is explained in the ``uarray`` documentation.* `[1]`_ *However, the NumPy community<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>will have input into the design of ``uarray``, and any backward-incompatible changes<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>will be discussed on the mailing list.*<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The way we propose the overrides will be used by end users is::<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> import numpy.overridable as np<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> with np.set_backend(backend):<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> x = np.asarray(my_array, dtype=dtype)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>And a library that implements a NumPy-like API will use it in the following manner (as an example)::<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> import numpy.overridable as np<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> _ua_implementations = {}<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> __ua_domain__ = "numpy"<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> def __ua_function__(func, args, kwargs):<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> fn = _ua_implementations.get(func, None)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> return fn(*args, **kwargs) if fn is not None else NotImplemented<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> def implements(ua_func):<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> def inner(func):<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> _ua_implementations[ua_func] = func<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> return func<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> return inner<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> @implements(np.asarray)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> def asarray(a, dtype=None, order=None):<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # Code here<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # Either this method or __ua_convert__ must<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # return NotImplemented for unsupported types,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # Or they shouldn't be marked as dispatchable.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # Provides a default implementation for ones and zeros.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> @implements(np.full)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> def full(shape, fill_value, dtype=None, order='C'):<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # Code here<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The only change this NEP proposes at its acceptance, is to make ``unumpy`` the officially recommended<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>way to override NumPy. ``unumpy`` will remain a separate repository/package (which we propose to vendor<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>to avoid a hard dependency, and use the separate ``unumpy`` package only if it is installed)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>rather than depend on for the time being), and will be developed<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>primarily with the input of duck-array authors and secondarily, custom dtype authors, via the usual<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>GitHub workflow. There are a few reasons for this:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Faster iteration in the case of bugs or issues.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Faster design changes, in the case of needed functionality.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* ``unumpy`` will work with older versions of NumPy as well.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* The user and library author opt-in to the override process,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> rather than breakages happening when it is least expected.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> In simple terms, bugs in ``unumpy`` mean that ``numpy`` remains<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> unaffected.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Advantanges of ``unumpy`` over other solutions<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>``unumpy`` offers a number of advantanges over the approach of defining a new protocol for every<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>problem encountered: Whenever there is something requiring an override, ``unumpy`` will be able to<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>offer a unified API with very minor changes. For example:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* ``ufunc`` objects can be overridden via their ``__call__``, ``reduce`` and other methods.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* ``dtype`` objects can be overridden via the dispatch/backend mechanism, going as far as to allow<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> ``np.float32`` et. al. to be overridden by overriding ``__get__``.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Other functions can be overridden in a similar fashion.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* ``np.asduckarray`` goes away, and becomes ``np.asarray`` with a backend set.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* The same holds for array creation functions such as ``np.zeros``, ``np.empty`` and so on.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>This also holds for the future: Making something overridable would require only minor changes to ``unumpy``.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Another promise ``unumpy`` holds is one of default implementations. Default implementations can be provided for<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>any multimethod, in terms of others. This allows one to override a large part of the NumPy API by defining<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>only a small part of it. This is to ease the creation of new duck-arrays, by providing default implementations of many<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>functions that can be easily expressed in terms of others, as well as a repository of utility functions<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>that help in the implementation of duck-arrays that most duck-arrays would require.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The last benefit is a clear way to coerce to a given backend, and a protocol for coercing not only arrays,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>but also ``dtype`` objects and ``ufunc`` objects with similar ones from other libraries. This is due to the existence of<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>actual, third party dtype packages, and their desire to blend into the NumPy ecosystem (see `[6]`_). This is a separate<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>issue compared to the C-level dtype redesign proposed in `[7]`_, it's about allowing third-party dtype implementations to<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>work with NumPy, much like third-party array implementations.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Mixing NumPy and ``unumpy`` in the same file<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Normally, one would only want to import only one of ``unumpy`` or ``numpy``, you would import it as ``np`` for<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>familiarity. However, there may be situations where one wishes to mix NumPy and the overrides, and there are<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>a few ways to do this, depending on the user's style::<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> import numpy.overridable as unumpy<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> import numpy as np<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>or::<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> import numpy as np<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> # Use unumpy via np.overridable<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Related Work<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Previous override mechanisms<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>^^^^^^^^^^^^^^^^^^^^^^^^^^^^<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* NEP-18, the ``__array_function__`` protocol. `[2]`_<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* NEP-13, the ``__array_ufunc__`` protocol. `[3]`_<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Existing NumPy-like array implementations<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Dask: https://dask.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* CuPy: https://cupy.chainer.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* PyData/Sparse: https://sparse.pydata.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Xnd: https://xnd.readthedocs.io/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Astropy's Quantity: https://docs.astropy.org/en/stable/units/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Existing and potential consumers of alternative arrays<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Dask: https://dask.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* scikit-learn: https://scikit-learn.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Xarray: https://xarray.pydata.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* TensorLy: http://tensorly.org/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Existing alternate dtype implementations<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* ``ndtypes``: https://ndtypes.readthedocs.io/en/latest/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Datashape: https://datashape.readthedocs.io<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Plum: https://plum-py.readthedocs.io/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Implementation<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>--------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The implementation of this NEP will require the following steps:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Implementation of ``uarray`` multimethods corresponding to the<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> NumPy API, including classes for overriding ``dtype``, ``ufunc``<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'> and ``array`` objects, in the ``unumpy`` repository.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Moving backends from ``unumpy`` into the respective array libraries.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Backward compatibility<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>----------------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>There are no backward incompatible changes proposed in this NEP.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Alternatives<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The current alternative to this problem is NEP-30 plus adding more protocols<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>(not yet specified) in addition to it. Even then, some parts of the NumPy<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>API will remain non-overridable, so it's a partial alternative.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>The main alternative to vendoring ``unumpy`` is to simply move it into NumPy<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>completely and not distribute it as a separate package. This would also achieve<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>the proposed goals, however we prefer to keep it a separate package for now,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>for reasons already stated above.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Discussion<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>----------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* ``uarray`` blogpost: https://labs.quansight.org/blog/2019/07/uarray-update-api-changes-overhead-and-comparison-to-__array_function__/<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* The discussion section of NEP-18: https://numpy.org/neps/nep-0018-array-function-protocol.html#discussion<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* NEP-22: https://numpy.org/neps/nep-0022-ndarray-duck-typing-overview.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Dask issue #4462: https://github.com/dask/dask/issues/4462<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* PR #13046: https://github.com/numpy/numpy/pull/13046<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Dask issue #4883: https://github.com/dask/dask/issues/4883<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Issue #13831: https://github.com/numpy/numpy/issues/13831<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Discussion PR 1: https://github.com/hameerabbasi/numpy/pull/3<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>* Discussion PR 2: https://github.com/hameerabbasi/numpy/pull/4<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>References and Footnotes<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>------------------------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[1]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[1] uarray, A general dispatch mechanism for Python: https://uarray.readthedocs.io<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[2]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[2] NEP 18 — A dispatch mechanism for NumPy’s high level array functions: https://numpy.org/neps/nep-0018-array-function-protocol.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[3]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[3] NEP 22 — Duck typing for NumPy arrays – high level overview: https://numpy.org/neps/nep-0022-ndarray-duck-typing-overview.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[4]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[4] NEP 13 — A Mechanism for Overriding Ufuncs: https://numpy.org/neps/nep-0013-ufunc-overrides.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[5]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[5] Reply to Adding to the non-dispatched implementation of NumPy methods: http://numpy-discussion.10968.n7.nabble.com/Adding-to-the-non-dispatched-implementation-of-NumPy-methods-tp46816p46874.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[6]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[6] Custom Dtype/Units discussion: http://numpy-discussion.10968.n7.nabble.com/Custom-Dtype-Units-discussion-td43262.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[7]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[7] The epic dtype cleanup plan: https://github.com/numpy/numpy/issues/2899<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[8]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[8] unumpy: NumPy, but implementation-independent: https://unumpy.readthedocs.io<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[9]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[9] NEP 30 — Duck Typing for NumPy Arrays - Implementation: https://www.numpy.org/neps/nep-0030-duck-array-protocol.html<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>.. _[10]:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>[10] http://scipy.github.io/devdocs/fft.html#backend-control<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>Copyright<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>---------<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:10.0pt;font-family:Monaco;mso-fareast-language:EN-GB'>This document has been placed in the public domain.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'><o:p> </o:p></span></p><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span style='color:black'>From: </span></b><span style='color:black'>Hameer Abbasi <hameerabbasi@yahoo.com><br><b>Date: </b>Wednesday, 28. August 2019 at 10:18<br><b>To: </b>Discussion of Numerical Python <numpy-discussion@python.org><br><b>Cc: </b>"rgommers@quansight.com" <rgommers@quansight.com>, Peter Bell <peterbell10@live.co.uk><br><b>Subject: </b>NEP 31: Context-local and global overrides of the NumPy API</span><span style='color:black;mso-fareast-language:EN-GB'><o:p></o:p></span></p></div><div><p class=MsoNormal><span style='font-size:11.0pt'><o:p> </o:p></span></p></div><p class=MsoNormal><span style='font-size:11.0pt'>Hello,</span><o:p></o:p></p><p class=MsoNormal><span style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>Me, Ralf Gommers and Peter Bell (both cc’d) have come up with a proposal on how to solve the array creation and duck array problems. The solution is outlined in NEP-31, currently in the form of a PR, [1]</span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>Following the high level discussion in NEP-22. [2]</span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>It would be nice to get some feedback.</span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>Best regards,</span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>Hameer Abbasi</span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'> </span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>[1] <a href="https://github.com/numpy/numpy/pull/14389">https://github.com/numpy/numpy/pull/14389</a></span><o:p></o:p></p><p class=MsoNormal><span lang=EN-US style='font-size:11.0pt'>[2] <a href="https://numpy.org/neps/nep-0022-ndarray-duck-typing-overview.html">https://numpy.org/neps/nep-0022-ndarray-duck-typing-overview.html</a></span><o:p></o:p></p></div></body></html>