Skip to content

Conversation

jorenham
Copy link
Member

@jorenham jorenham commented Aug 27, 2025

In the stubs, datetime64 is a generic type with an optional type parameter. But due to the lack of __class_getitem__, something like np.datetime64[int] would fail at runtime, even though it's valid in static typing land.

This changes datetime64 so that it's can also be used as generic type at runtime by adding a __class_getitem__ method that returns a types.GenericAliasType (yea, the naming is horrible...).

Before:

In [1]: np.__version__
Out[1]: '2.3.2'

In [2]: np.datetime64[int]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 np.datetime64[int]

TypeError: type 'numpy.datetime64' is not subscriptable

After:

In [1]: np.__version__
Out[1]: '2.4.0.dev0+git20250825.47430c7'

In [2]: np.datetime64[int]
Out[2]: numpy.datetime64[int]

(I'm getting pretty good at pretending to know C, eh?)


related to #29370

@jorenham jorenham force-pushed the typing/runtime-generic-datetime64 branch from 290b83a to ef9edae Compare August 27, 2025 01:05
@@ -4564,6 +4568,7 @@ initialize_numeric_types(void)

/**end repeat**/

PyDatetimeArrType_Type.tp_methods = datetimetype_methods;
Copy link
Member

@mattip mattip Aug 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.
I don't know much about the __class_getitem__ protocol implementation, don't the other dtypes need them as well? Why are datetime64 and bool special?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case of np.bool it can be useful to be able to distinguish between np.True_: np.bool[Literal[True]] and np.False_: np.bool[Literal[False]] like that.
For np.datetime64 the generic type parameter tells what .item() will return. So np.datetime64[None] is the type of NaT, np.datetime64[int] have units below ms, and likewise there are np.datetime64[datetime.datetime] and np.datetime64[datetime.date].
For the other conrete scalar types, at least the numerical ones, there are no such usecases at the moment.
So in short: If you write np.int8[Any] you'll see a squiggly. If you write np.bool[Any] or np.datetime64[Any], you don't.

@mattip mattip merged commit c0caaeb into numpy:main Aug 27, 2025
80 of 82 checks passed
@mattip
Copy link
Member

mattip commented Aug 27, 2025

Thanks @jorenham

@jorenham jorenham deleted the typing/runtime-generic-datetime64 branch August 27, 2025 17:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants