Skip to content
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

ENH: Add __class_getitem__ to ndarray, dtype and number #19879

Merged
merged 10 commits into from Sep 25, 2021

Conversation

BvB93
Copy link
Member

@BvB93 BvB93 commented Sep 15, 2021

This PR adds the __class_getitem__ classmethod to the ndarray, dtype and number classes,
mimicking what PEP 585 did for the standard library. Consequently, expressions that were previously
only allowed in .pyi stub files or with the help of from __future__ import annotations are now also
legal during runtime.

A couple things of note (most of them summarized from the linked PEP):

  • The new __class_getitem__ method returns parametrized wrapper (types.GenericAlias) around the original type and, in most situations, can be used whenever the non-wrapped type is expected.
  • The types.GenericAlias class is only available for for python >= 3.9, consequently __class_getitem__ will only be available for these version.
  • types.GenericAlias performs no minimal validation (i.e. checking the number of passed parameters) on the passed object, so this means that __class_getitem__ can in practice take any object. I'm personally not a huge fan of this, but, on the other hand, I feel that copying the stdlib approach here is the lesser of evils due to its simplicity and maintainability, especially since the more thorough argument parsing performed by typing.Generic.__class_getitem__ is quite complex and prone to change.
  • Matching the stub files, the concrete number subclasses (uint8, int32, etc.) are treated as if they were already subscribed, and will thus raise upon calling __class_getitem__ due to a lack of free parameters.

Examples

In [1]: import numpy as np
   ...: from typing import Any

In [2]: np.dtype[np.int64]
Out[2]: numpy.dtype[numpy.int64]

In [3]: np.inexact[Any]
Out[3]: numpy.inexact[typing.Any]

In [4]: np.ndarray[Any, np.dtype[np.float64]]
Out[4]: numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]

In [5]: np.float64[Any]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-d62322c38e84> in <module>
----> 1 np.float64[Any]

TypeError: There are no type variables left in numpy.float64

@BvB93 BvB93 added 01 - Enhancement 62 - Python API Changes or additions to the Python API. Mailing list should usually be notified. labels Sep 15, 2021
numpy/core/src/multiarray/scalartypes.c.src Outdated Show resolved Hide resolved
numpy/core/src/multiarray/descriptor.c Outdated Show resolved Hide resolved
@BvB93 BvB93 force-pushed the cls_getitem branch 3 times, most recently from 4dd0a96 to 3fc9eb5 Compare September 16, 2021 10:59
…erform basic validation of its input arguments

It will still raise on python 3.8, but now with a more explicit exception message
@charris
Copy link
Member

charris commented Sep 20, 2021

@BvB93 Do you consider this ready?

@BvB93
Copy link
Member Author

BvB93 commented Sep 20, 2021

Personally, I'm happy with the current state of the PR. I'm not sure if anyone else has some final remarks?

@charris charris merged commit ac78192 into numpy:main Sep 25, 2021
@charris
Copy link
Member

charris commented Sep 25, 2021

Let's give it a shot. Sounds like we will want it in Python >= 3.9 in any case. Thanks Bas.

@BvB93 BvB93 deleted the cls_getitem branch September 27, 2021 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
01 - Enhancement 62 - Python API Changes or additions to the Python API. Mailing list should usually be notified.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants