8000 MAINT: Make `__class_getitem__` available to all python version and p… · numpy/numpy@3fc9eb5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3fc9eb5

Browse files
author
Bas van Beek
committed
MAINT: Make __class_getitem__ available to all python version and perform basic validation of its input arguments
It will still raise on python 3.8, but now with a more explicit exception message
1 parent 0baeeb1 commit 3fc9eb5

File tree

7 files changed

+190
-99
lines changed

7 files changed

+190
-99
lines changed

numpy/core/_add_newdocs.py

Lines changed: 66 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
1010
"""
1111

12-
import sys
1312
from numpy.core.function_base import add_newdoc
1413
from numpy.core.overrides import array_function_like_doc
1514

@@ -2799,38 +2798,37 @@
27992798
"""))
28002799

28012800

2802-
if sys.version_info > (3, 9):
2803-
add_newdoc('numpy.core.multiarray', 'ndarray', ('__class_getitem__',
2804-
"""a.__class_getitem__(item, /)
2801+
add_newdoc('numpy.core.multiarray', 'ndarray', ('__class_getitem__',
2802+
"""a.__class_getitem__(item, /)
28052803
2806-
Return a parametrized wrapper around the `~numpy.ndarray` type.
2804+
Return a parametrized wrapper around the `~numpy.ndarray` type.
28072805
2808-
.. versionadded:: 1.22
2806+
.. versionadded:: 1.22
28092807
2810-
Returns
2811-
-------
2812-
alias : types.GenericAlias
2813-
A parametrized `~numpy.ndarray` type.
2808+
Returns
2809+
-------
2810+
alias : types.GenericAlias
2811+
A parametrized `~numpy.ndarray` type.
28142812
2815-
Examples
2816-
--------
2817-
>>> from typing import Any
2818-
>>> import numpy as np
2813+
Examples
2814+
--------
2815+
>>> from typing import Any
2816+
>>> import numpy as np
28192817
2820-
>>> np.ndarray[Any, np.dtype]
2821-
numpy.ndarray[typing.Any, numpy.dtype]
2818+
>>> np.ndarray[Any, np.dtype[Any]]
2819+
numpy.ndarray[typing.Any, numpy.dtype[Any]]
28222820
2823-
Note
2824-
----
2825-
This method is only available for python 3.9 and later.
2821+
Note
2822+
----
2823+
This method is only available for python 3.9 and later.
28262824
2827-
See Also
2828-
--------
2829-
:pep:`585` : Type hinting generics in standard collections.
2830-
numpy.typing.NDArray : An ndarray alias :term:`generic <generic type>`
2831-
w.r.t. its `dtype.type <numpy.dtype.type>`.
2825+
See Also
2826+
--------
2827+
:pep:`585` : Type hinting generics in standard collections.
2828+
numpy.typing.NDArray : An ndarray alias :term:`generic <generic type>`
2829+
w.r.t. its `dtype.type <numpy.dtype.type>`.
28322830
2833-
"""))
2831+
"""))
28342832

28352833

28362834
add_newdoc('numpy.core.multiarray', 'ndarray', ('__deepcopy__',
@@ -6079,36 +6077,35 @@
60796077
60806078
"""))
60816079

6082-
if sys.version_info >= (3, 9):
6083-
add_newdoc('numpy.core.multiarray', 'dtype', ('__class_getitem__',
6084-
"""
6085-
__class_getitem__(item, /)
6080+
add_newdoc('numpy.core.multiarray', 'dtype', ('__class_getitem__',
6081+
"""
6082+
__class_getitem__(item, /)
60866083
6087-
Return a parametrized wrapper around the `~numpy.dtype` type.
6084+
Return a parametrized wrapper around the `~numpy.dtype` type.
60886085
6089-
.. versionadded:: 1.22
6086+
.. versionadded:: 1.22
60906087
6091-
Returns
6092-
-------
6093-
alias : types.GenericAlias
6094-
A parametrized `~numpy.dtype` type.
6088+
Returns
6089+
-------
6090+
alias : types.GenericAlias
6091+
A parametrized `~numpy.dtype` type.
60956092
6096-
Examples
6097-
--------
6098-
>>> import numpy as np
6093+
Examples
6094+
--------
6095+
>>> import numpy as np
60996096
6100-
>>> np.dtype[np.int64]
6101-
numpy.dtype[numpy.int64]
6097+
>>> np.dtype[np.int64]
6098+
numpy.dtype[numpy.int64]
61026099
6103-
Note
6104-
----
6105-
This method is only available for python 3.9 and later.
6100+
Note
6101+
----
6102+
This method is only available for python 3.9 and later.
61066103
6107-
See Also
6108-
--------
6109-
:pep:`585` : Type hinting generics in standard collections.
6104+
See Also
6105+
--------
6106+
:pep:`585` : Type hinting generics in standard collections.
61106107
6111-
"""))
6108+
"""))
61126109

61136110
##############################################################################
61146111
#
@@ -6530,37 +6527,36 @@ def refer_to_array_attribute(attr, method=True):
65306527
add_newdoc('numpy.core.numerictypes', 'generic',
65316528
refer_to_array_attribute('view'))
65326529

6533-
if sys.version_info >= (3, 9):
6534-
add_newdoc('numpy.core.numerictypes', 'number', ('__class_getitem__',
6535-
"""
6536-
__class_getitem__(item, /)
6530+
add_newdoc('numpy.core.numerictypes', 'number', ('__class_getitem__',
6531+
"""
6532+
__class_getitem__(item, /)
65376533
6538-
Return a parametrized wrapper around the `~numpy.number` type.
6534+
Return a parametrized wrapper around the `~numpy.number` type.
65396535
6540-
.. versionadded:: 1.22
6536+
.. versionadded:: 1.22
65416537
6542-
Returns
6543-
-------
6544-
alias : types.GenericAlias
6545-
A parametrized `~numpy.number` type.
6538+
Returns
6539+
-------
6540+
alias : types.GenericAlias
6541+
A parametrized `~numpy.number` type.
65466542
6547-
Examples
6548-
--------
6549-
>>> from typing import Any
6550-
>>> import numpy as np
6543+
Examples
6544+
--------
6545+
>>> from typing import Any
6546+
>>> import numpy as np
65516547
6552-
>>> np.signedinteger[Any]
6553-
numpy.signedinteger[typing.Any]
6548+
>>> np.signedinteger[Any]
6549+
numpy.signedinteger[typing.Any]
65546550
6555-
Note
6556-
----
6557-
This method is only available for python 3.9 and later.
6551+
Note
6552+
----
6553+
This method is only available for python 3.9 and later.
65586554
6559-
See Also
6560-
--------
6561-
:pep:`585` : Type hinting generics in standard collections.
6555+
See Also
6556+
--------
6557+
:pep:`585` : Type hinting generics in standard collections.
65626558
6563-
"""))
6559+
"""))
65646560

65656561
##############################################################################
65666562
#

numpy/core/src/multiarray/descriptor.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3101,6 +3101,28 @@ arraydescr_newbyteorder(PyArray_Descr *self, PyObject *args)
31013101
return (PyObject *)PyArray_DescrNewByteorder(self, endian);
31023102
}
31033103

3104+
static PyObject *
3105+
arraydescr_class_getitem(PyObject *cls, PyObject *args)
3106+
{
3107+
Py_ssize_t args_len;
3108+
PyObject *generic_alias;
3109+
3110+
#ifdef Py_GENERICALIASOBJECT_H
3111+
args_len = PyTuple_Check(args) ? PyTuple_Size(args) : 1;
3112+
if (args_len != 1) {
3113+
return PyErr_Format(PyExc_TypeError,
3114+
"Too %s arguments for %s",
3115+
args_len > 1 ? "many" : "few",
3116+
((PyTypeObject *)cls)->tp_name);
3117+
}
3118+
generic_alias = Py_GenericAlias(cls, args);
3119+
#else
3120+
return PyErr_SetString(PyExc_TypeError,
3121+
"Type subscription requires python >= 3.9");
3122+
#endif
3123+
return generic_alias;
3124+
}
3125+
31043126
static PyMethodDef arraydescr_methods[] = {
31053127
/* for pickling */
31063128
{"__reduce__",
@@ -3112,13 +3134,10 @@ static PyMethodDef arraydescr_methods[] = {
31123134
{"newbyteorder",
31133135
(PyCFunction)arraydescr_newbyteorder,
31143136
METH_VARARGS, NULL},
3115-
31163137
/* for typing; requires python >= 3.9 */
3117-
#ifdef Py_GENERICALIASOBJECT_H
31183138
{"__class_getitem__",
3119-
(PyCFunction)Py_GenericAlias,
3139+
(PyCFunction)arraydescr_class_getitem,
31203140
METH_CLASS | METH_O, NULL},
3121-
#endif
31223141
{NULL, NULL, 0, NULL} /* sentinel */
31233142
};
31243143

numpy/core/src/multiarray/methods.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,6 +2699,28 @@ array_complex(PyArrayObject *self, PyObject *NPY_UNUSED(args))
26992699
return c;
27002700
}
27012701

2702+
static PyObject *
2703+
array_class_getitem(PyObject *cls, PyObject *args)
2704+
{
2705+
Py_ssize_t args_len;
2706+
PyObject *generic_alias;
2707+
2708+
#ifdef Py_GENERICALIASOBJECT_H
2709+
args_len = PyTuple_Check(args) ? PyTuple_Size(args) : 1;
2710+
if (args_len != 2) {
2711+
return PyErr_Format(PyExc_TypeError,
2712+
"Too %s arguments for %s",
2713+
args_len > 2 ? "many" : "few",
2714+
((PyTypeObject *)cls)->tp_name);
2715+
}
2716+
generic_alias = Py_GenericAlias(cls, args);
2717+
#else
2718+
return PyErr_SetString(PyExc_TypeError,
2719+
"Type subscription requires python >= 3.9");
2720+
#endif
2721+
return generic_alias;
2722+
}
2723+
27022724
NPY_NO_EXPORT PyMethodDef array_methods[] = {
27032725

27042726
/* for subtypes */
@@ -2757,11 +2779,9 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
27572779
METH_VARARGS, NULL},
27582780

27592781
/* for typing; requires python >= 3.9 */
2760-
#ifdef Py_GENERICALIASOBJECT_H
27612782
{"__class_getitem__",
2762-
(PyCFunction)Py_GenericAlias,
2783+
(PyCFunction)array_class_getitem,
27632784
METH_CLASS | METH_O, NULL},
2764-
#endif
27652785

27662786
/* Original and Extended methods added 2005 */
27672787
{"all",

numpy/core/src/multiarray/scalartypes.c.src

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,20 +1805,46 @@ gentype_setflags(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args),
18051805
Py_RETURN_NONE;
18061806
}
18071807

1808+
static PyObject *
1809+
numbertype_class_getitem_abc(PyObject *cls, PyObject *args)
1810+
{
1811+
Py_ssize_t args_len;
1812+
PyObject *generic_alias;
1813+
1814+
#ifdef Py_GENERICALIASOBJECT_H
1815+
args_len = PyTuple_Check(args) ? PyTuple_Size(args) : 1;
1816+
if (args_len != 1) {
1817+
return PyErr_Format(PyExc_TypeError,
1818+
"Too %s arguments for %s",
1819+
args_len > 1 ? "many" : "few",
1820+
((PyTypeObject *)cls)->tp_name);
1821+
}
1822+
generic_alias = Py_GenericAlias(cls, args);
1823+
#else
1824+
return PyErr_SetString(PyExc_TypeError,
1825+
"Type subscription requires python >= 3.9");
1826+
#endif
1827+
return generic_alias;
1828+
}
1829+
18081830
/*
18091831
* Use for concrete np.number subclasses, making them act as if they
18101832
* were subtyped from e.g. np.signedinteger[object], thus lacking any
18111833
* free subscription parameters. Requires python >= 3.9.
18121834
*/
1813-
#ifdef Py_GENERICALIASOBJECT_H
18141835
static PyObject *
18151836
numbertype_class_getitem(PyObject *cls, PyObject *args)
18161837
{
1817-
return PyErr_Format(PyExc_TypeError,
1818-
"There are no type variables left in %s",
1819-
((PyTypeObject *)cls)->tp_name);
1820-
}
1838+
#ifdef Py_GENERICALIASOBJECT_H
1839+
PyErr_Format(PyExc_TypeError,
1840+
"There are no type variables left in %s",
1841+
((PyTypeObject *)cls)->tp_name);
1842+
#else
1843+
PyErr_SetString(PyExc_TypeError,
1844+
"Type subscription requires python >= 3.9");
18211845
#endif
1846+
return NULL;
1847+
}
18221848

18231849
/*
18241850
* casting complex numbers (that don't inherit from Python complex)
@@ -2205,11 +2231,9 @@ static PyGetSetDef inttype_getsets[] = {
22052231

22062232
static PyMethodDef numbertype_methods[] = {
22072233
/* for typing; requires python >= 3.9 */
2208-
#ifdef Py_GENERICALIASOBJECT_H
22092234
{"__class_getitem__",
2210-
(PyCFunction)Py_GenericAlias,
2235+
(PyCFunction)numbertype_class_getitem_abc,
22112236
METH_CLASS | METH_O, NULL},
2212-
#endif
22132237
{NULL, NULL, 0, NULL} /* sentinel */
22142238
};
22152239

@@ -2221,11 +2245,9 @@ static PyMethodDef @name@type_methods[] = {
22212245
(PyCFunction)@name@_complex,
22222246
METH_VARARGS | METH_KEYWORDS, NULL},
22232247
/* for typing; requires python >= 3.9 */
2224-
#ifdef Py_GENERICALIASOBJECT_H
22252248
{"__class_getitem__",
22262249
(PyCFunction)numbertype_class_getitem,
22272250
METH_CLASS | METH_O, NULL},
2228-
#endif
22292251
{NULL, NULL, 0, NULL}
22302252
};
22312253
/**end repeat**/
@@ -2264,11 +2286,9 @@ static PyMethodDef @name@type_methods[] = {
22642286
(PyCFunction)@name@_is_integer,
22652287
METH_NOARGS, NULL},
22662288
/* for typing; requires python >= 3.9 */
2267-
#ifdef Py_GENERICALIASOBJECT_H
22682289
{"__class_getitem__",
22692290
(PyCFunction)numbertype_class_getitem,
22702291
METH_CLASS | METH_O, NULL},
2271-
#endif
22722292
{NULL, NULL, 0, NULL}
22732293
};
22742294
/**end repeat**/
@@ -2279,11 +2299,9 @@ static PyMethodDef @name@type_methods[] = {
22792299
*/
22802300
static PyMethodDef @name@type_methods[] = {
22812301
/* for typing; requires python >= 3.9 */
2282-
#ifdef Py_GENERICALIASOBJECT_H
22832302
{"__class_getitem__",
22842303
(PyCFunction)numbertype_class_getitem,
22852304
METH_CLASS | METH_O, NULL},
2286-
#endif
22872305
{NULL, NULL, 0, NULL}
22882306
};
22892307
/**end repeat**/

0 commit comments

Comments
 (0)
0