-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
API: Add npt.NDArray
, a runtime-subscriptable alias for np.ndarray
#18935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I am happy to just add @BvB93 if it helps you, I can add this over the weekend, we ping the mailing list about comments (I doubt anyone will be bothered) and then you have it. |
That would be nice, yes; it's definitely one of the things on my wish lists. |
@BvB93 what is the typical behviour? Since EDIT: Or maybe, I could allow it, but raise an error unless: |
I would actually propose to just stick same semantics as cpython used in PEP 585 for the builtin types (python/cpython#18239). For example, with the likes of import types
def __class_getitem__(cls, args):
return types.GenericAlias(cls, args) Or a bit more fancy and and some basic error checking (i.e. this will raise for import types
Scalar = TypeVar("Scalar")
_ALIAS = types.GenericAlias(cls, (Scalar,))
def __class_getitem__(cls, args):
return _ALIAS[args] # Let `GenericAlias` handle the error checking This would have a few consequences though:
|
Wait, but that sounds pretty much useless at run-time? I thought this would be useful semantics to get the actual subclass. |
No objections from me -- this looks very handy! |
Well... yes. Going the
Then again, I'm not opposing either option. |
@BvB93 no, its not really any work at all, because I already have that. The point is that this is what happens if you type
must already be able to effectively do:
In other words: I already have a function that does |
Sorry, I hadn't parsed the typing side of what it means to return subclasses... I am not too fond about strings at runtime, but if typing wants it, sure. From the runtime side of things, I feel it would be natural to have:
(both of these are guaranteed. I am not 100% sure about the opposite direction that That would allow doing things like:
But, of course we probably don't need that all that often... |
25c3425
to
04670a1
Compare
FYI the discussion on Secondly, I'd like to point the attention of (potential) reviewers to the snippet below, as it would be useful to sort out some of these details already (most importantly: would the names make sense?).
|
Thanks Bas. |
This PR introduces a runtime-subscriptable alias for
np.ndarray[Any, np.dtype[~Scalar]]
by the name ofnpt.NDArray
.Follow up on #17719, which made the initial attempt at introducing aforementioned type alias before being deferred to a later PR.
Motivation for the introduction of this type alias is two-fold:
typing.Sequence
fulfilled forcollections.abc.Sequence
prior to python 3.9. While runetime-subsription is already, more or less, possible to withfrom __future__ import annotations
, the latter only helps with annotations, and not the creation of type aliases. All in allnpt.NDArray
would add a big convenience factor.np.generic
(see NEP 42), which will either have to define their own aliases or stick to the complete form.Future Work
Currently I can think of two other (potential) candidates:
np.dtype[~Scalar]
. I'm not 100% sure if the big dtype update (NEP 40-42) already has plans on adding adtype.__class_getitem__
method or not, so adding a subscriptable alias tonumpy.typing
might be redudant. @seberg do you have any comments this?np.ndarray[~Shape, np.dtype[~Scalar]]
. I'd say this would be worthwhile to introduce, once we have shape-typing sorted out (Typing support for shapes #16544), that is.There is an open question of what would be the best name for such type-alias.
npt.Array
perhaps? To distinguish it from the arbitrary shapednpt.NDarray
introduced in this PR.Implementation
Fortunately PEP 585 has provided us with all the tools we need for constructing what are effectively subscriptable wrappers:
types.GenericAlias
. Aforementioned class is designed such that (nearly) all operations wrap around the underlying type, e.g.np.ndarray
behaves virtually the same astypes.GenericAlias(np.ndarray, ())
.The only bad news is that
GenericAlias
is exclusive to python >= 3.9 (and written in C), hence the introduction of a (python-based) backport in this PR. The backport can of course be removed once we've dropped support for 3.8 at some point in the future.Examples