Skip to content

Commit 2fb0af9

Browse files
authored
🎨 prefer _numtype.Shape* over int tuples as shape type (#532)
1 parent be3486c commit 2fb0af9

24 files changed

+371
-416
lines changed

‎src/_numtype/__init__.pyi

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -684,10 +684,18 @@ ToObject_2nd = TypeAliasType("ToObject_2nd", _ToArray2_2nd[np.object_, _PyObject
684684
ToObject_3nd = TypeAliasType("ToObject_3nd", _ToArray2_3nd[np.object_, _PyObject])
685685

686686
# StringDType
687-
ToString_nd = TypeAliasType("ToString_nd", _CanStringArray[Shape, _NaT0], type_params=(_NaT0,))
687+
ToString_nd = TypeAliasType("ToString_nd", SequenceND[_CanStringArray[Shape, _NaT0]], type_params=(_NaT0,))
688688
ToString_1ds = TypeAliasType("ToString_1ds", _CanStringArray[Shape1, _NaT0], type_params=(_NaT0,))
689-
ToString_2ds = TypeAliasType("ToString_2ds", _CanStringArray[Shape2, _NaT0], type_params=(_NaT0,))
690-
ToString_3ds = TypeAliasType("ToString_3ds", _CanStringArray[Shape3, _NaT0], type_params=(_NaT0,))
689+
ToString_2ds = TypeAliasType(
690+
"ToString_2ds",
691+
_CanStringArray[Shape2, _NaT0] | Sequence[ToString_1ds[_NaT0]],
692+
type_params=(_NaT0,),
693+
)
694+
ToString_3ds = TypeAliasType(
695+
"ToString_3ds",
696+
_CanStringArray[Shape3, _NaT0] | Sequence[ToString_2ds[_NaT0]],
697+
type_params=(_NaT0,),
698+
)
691699
ToString_1nd = TypeAliasType("ToString_1nd", _CanStringArray[Shape1_, _NaT0], type_params=(_NaT0,))
692700
ToString_2nd = TypeAliasType("ToString_2nd", _CanStringArray[Shape2_, _NaT0], type_params=(_NaT0,))
693701
ToString_3nd = TypeAliasType("ToString_3nd", _CanStringArray[Shape3_, _NaT0], type_params=(_NaT0,))

‎src/numpy-stubs/@test/runtime/legacy/arrayterator.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from __future__ import annotations
22

33
import numpy as np
4+
import numpy.typing as npt
45

5-
AR_i8: np.ndarray[tuple[int, ...], np.dtype[np.int_]] = np.arange(10)
6+
AR_i8: npt.NDArray[np.int_] = np.arange(10)
67
ar_iter = np.lib.Arrayterator(AR_i8)
78

89
ar_iter.var

‎src/numpy-stubs/@test/runtime/legacy/lib_user_array.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@
22

33
from __future__ import annotations
44

5+
from typing import TYPE_CHECKING
6+
57
import numpy as np
68
from numpy.lib.user_array import container
79

10+
if TYPE_CHECKING:
11+
import _numtype as _nt
12+
813
N = 10_000
914
W = H = int(N**0.5)
1015

11-
a: np.ndarray[tuple[int, int], np.dtype[np.int32]]
12-
ua: container[tuple[int, int], np.dtype[np.int32]]
16+
a: np.ndarray[_nt.Shape2, np.dtype[np.int32]]
17+
ua: container[_nt.Shape2, np.dtype[np.int32]]
1318

1419
a = np.arange(N, dtype=np.int32).reshape(W, H)
1520
ua = container(a)
1621

17-
ua_small: container[tuple[int, int], np.dtype[np.int32]] = ua[:3, :5]
22+
ua_small: container[_nt.Shape2, np.dtype[np.int32]] = ua[:3, :5]
1823
ua_small[0, 0] = 10
1924

20-
ua_bool: container[tuple[int, int], np.dtype[np.bool]] = ua_small > 1
25+
ua_bool: container[_nt.Shape2, np.dtype[np.bool]] = ua_small > 1
2126

2227
# shape: tuple[int, int] = np.shape(ua)

‎src/numpy-stubs/@test/runtime/legacy/ndarray_shape_manipulation.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
from typing import cast
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING, cast
24

35
import numpy as np
46

5-
nd1 = cast("np.ndarray[tuple[int, int], np.dtype[np.intp]]", np.array([[1, 2], [3, 4]]))
7+
if TYPE_CHECKING:
8+
import _numtype as _nt
9+
10+
nd1 = cast("np.ndarray[_nt.Shape2, np.dtype[np.intp]]", np.array([[1, 2], [3, 4]]))
611

712
# reshape
813
nd1.reshape(4)

‎src/numpy-stubs/@test/runtime/legacy/recfunctions.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
"""These tests are based on the doctests from `numpy/lib/recfunctions.py`."""
22

3-
from typing import Any
3+
from typing import TYPE_CHECKING, Any
44
from typing_extensions import assert_type
55

66
import numpy as np
77
import numpy.typing as npt
88
from numpy.lib import recfunctions as rfn
99

10+
if TYPE_CHECKING:
11+
import _numtype as _nt # noqa: F401, PLC2701
12+
1013

1114
def test_recursive_fill_fields() -> None:
1215
a: npt.NDArray[np.void] = np.array(
@@ -15,7 +18,7 @@ def test_recursive_fill_fields() -> None:
1518
)
1619
b = np.zeros((int(3),), dtype=a.dtype)
1720
out = rfn.recursive_fill_fields(a, b)
18-
assert_type(out, np.ndarray[tuple[int], np.dtype[np.void]])
21+
assert_type(out, "np.ndarray[_nt.Shape1, np.dtype[np.void]]")
1922

2023

2124
def test_get_names() -> None:
@@ -57,7 +60,7 @@ def test_merge_arrays() -> None:
5760
np.ones((int(2),), np.int_),
5861
np.ones((int(3),), np.float64),
5962
)),
60-
np.recarray[tuple[int], np.dtype[np.void]],
63+
"np.recarray[_nt.Shape1, np.dtype[np.void]]",
6164
)
6265

6366

@@ -67,15 +70,15 @@ def test_drop_fields() -> None:
6770

6871
assert_type(
6972
rfn.drop_fields(a, "a"),
70-
np.ndarray[tuple[int], np.dtype[np.void]],
73+
"np.ndarray[_nt.Shape1, np.dtype[np.void]]",
7174
)
7275
assert_type(
7376
rfn.drop_fields(a, "a", asrecarray=True),
74-
np.rec.recarray[tuple[int], np.dtype[np.void]],
77+
"np.rec.recarray[_nt.Shape1, np.dtype[np.void]]",
7578
)
7679
assert_type(
7780
rfn.rec_drop_fields(a, "a"),
78-
np.rec.recarray[tuple[int], np.dtype[np.void]],
81+
"np.rec.recarray[_nt.Shape1, np.dtype[np.void]]",
7982
)
8083

8184

@@ -85,7 +88,7 @@ def test_rename_fields() -> None:
8588

8689
assert_type(
8790
rfn.rename_fields(a, {"a": "A", "b_b": "B_B"}),
88-
np.ndarray[tuple[int], np.dtype[np.void]],
91+
"np.ndarray[_nt.Shape1, np.dtype[np.void]]",
8992
)
9093

9194

@@ -96,7 +99,7 @@ def test_repack_fields() -> None:
9699
assert_type(rfn.repack_fields(dt.type(0)), np.void)
97100
assert_type(
98101
rfn.repack_fields(np.ones((3,), dtype=dt)),
99-
np.ndarray[tuple[int], np.dtype[np.void]],
102+
"np.ndarray[_nt.Shape1, np.dtype[np.void]]",
100103
)
101104

102105

@@ -115,38 +118,38 @@ def test_apply_along_fields() -> None:
115118
b = np.ones(4, dtype=[("x", "i4"), ("y", "f4"), ("z", "f8")])
116119
assert_type(
117120
rfn.apply_along_fields(np.mean, b),
118-
np.ndarray[tuple[int], np.dtype[np.void]],
121+
"np.ndarray[_nt.Shape1, np.dtype[np.void]]",
119122
)
120123

121124

122125
def test_assign_fields_by_name() -> None:
123126
b = np.ones(4, dtype=[("x", "i4"), ("y", "f4"), ("z", "f8")])
124127
assert_type(
125128
rfn.apply_along_fields(np.mean, b),
126-
np.ndarray[tuple[int], np.dtype[np.void]],
129+
"np.ndarray[_nt.Shape1, np.dtype[np.void]]",
127130
)
128131

129132

130133
def test_require_fields() -> None:
131134
a = np.ones(4, dtype=[("a", "i4"), ("b", "f8"), ("c", "u1")])
132135
assert_type(
133136
rfn.require_fields(a, [("b", "f4"), ("c", "u1")]),
134-
np.ndarray[tuple[int], np.dtype[np.void]],
137+
"np.ndarray[_nt.Shape1, np.dtype[np.void]]",
135138
)
136139

137140

138141
def test_stack_arrays() -> None:
139142
x = np.zeros((int(2),), np.int32)
140143
assert_type(
141144
rfn.stack_arrays(x),
142-
np.ndarray[tuple[int], np.dtype[np.int32]],
145+
"np.ndarray[_nt.Shape1, np.dtype[np.int32]]",
143146
)
144147

145148
z = np.ones((int(2),), [("A", "|S3"), ("B", float)])
146149
zz = np.ones((int(2),), [("A", "|S3"), ("B", np.float64), ("C", np.float64)])
147150
assert_type(
148151
rfn.stack_arrays((z, zz)),
149-
np.ma.MaskedArray[tuple[int, ...], np.dtype[np.void]],
152+
"np.ma.MaskedArray[_nt.Shape, np.dtype[np.void]]",
150153
)
151154

152155

‎src/numpy-stubs/@test/runtime/legacy/shape.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
from typing import Any, NamedTuple
1+
from typing import TYPE_CHECKING, Any, NamedTuple
22

33
import numpy as np
44

5+
if TYPE_CHECKING:
6+
import _numtype as _nt
7+
58

69
# Subtype of tuple[int, int]
710
class XYGrid(NamedTuple):
@@ -10,7 +13,7 @@ class XYGrid(NamedTuple):
1013

1114

1215
# Test variance of _ShapeType_co
13-
def accepts_2d(a: np.ndarray[tuple[int, int], Any]) -> None:
16+
def accepts_2d(a: "np.ndarray[_nt.Shape2, Any]") -> None:
1417
return None
1518

1619

0 commit comments

Comments
 (0)