Skip to content

Commit aac516a

Browse files
author
Bas van Beek
committed
TST: Account for the platform-specific mapping of numpy- to ctypes-types
1 parent a2b4bb7 commit aac516a

File tree

2 files changed

+74
-37
lines changed

2 files changed

+74
-37
lines changed

numpy/typing/tests/data/reveal/ctypeslib.pyi

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ AR_int: npt.NDArray[np.int_]
1717
AR_longlong: npt.NDArray[np.longlong]
1818
AR_single: npt.NDArray[np.single]
1919
AR_double: npt.NDArray[np.double]
20+
AR_longdouble: npt.NDArray[np.longdouble]
2021
AR_void: npt.NDArray[np.void]
2122

2223
pointer: ctypes.pointer[Any]
@@ -31,51 +32,54 @@ reveal_type(np.ctypeslib.ndpointer(np.int64, shape=(10, 3))) # E: Type[numpy.ct
3132
reveal_type(np.ctypeslib.ndpointer(int, shape=(1,))) # E: Type[numpy.ctypeslib._concrete_ndptr[numpy.dtype[Any]]]
3233

3334
reveal_type(np.ctypeslib.as_ctypes_type(np.bool_)) # E: Type[ctypes.c_bool]
34-
reveal_type(np.ctypeslib.as_ctypes_type(np.ubyte)) # E: Type[ctypes.c_ubyte]
35-
reveal_type(np.ctypeslib.as_ctypes_type(np.ushort)) # E: Type[ctypes.c_ushort]
36-
reveal_type(np.ctypeslib.as_ctypes_type(np.uintc)) # E: Type[ctypes.c_uint]
37-
reveal_type(np.ctypeslib.as_ctypes_type(np.uint)) # E: Type[ctypes.c_ulong]
38-
reveal_type(np.ctypeslib.as_ctypes_type(np.ulonglong)) # E: Type[ctypes.c_ulong]
39-
reveal_type(np.ctypeslib.as_ctypes_type(np.byte)) # E: Type[ctypes.c_byte]
40-
reveal_type(np.ctypeslib.as_ctypes_type(np.short)) # E: Type[ctypes.c_short]
41-
reveal_type(np.ctypeslib.as_ctypes_type(np.intc)) # E: Type[ctypes.c_int]
42-
reveal_type(np.ctypeslib.as_ctypes_type(np.int_)) # E: Type[ctypes.c_long]
43-
reveal_type(np.ctypeslib.as_ctypes_type(np.longlong)) # E: Type[ctypes.c_long]
44-
reveal_type(np.ctypeslib.as_ctypes_type(np.single)) # E: Type[ctypes.c_float]
45-
reveal_type(np.ctypeslib.as_ctypes_type(np.double)) # E: Type[ctypes.c_double]
46-
reveal_type(np.ctypeslib.as_ctypes_type(ctypes.c_double)) # E: Type[ctypes.c_double]
35+
reveal_type(np.ctypeslib.as_ctypes_type(np.ubyte)) # E: Type[{c_ubyte}]
36+
reveal_type(np.ctypeslib.as_ctypes_type(np.ushort)) # E: Type[{c_ushort}]
37+
reveal_type(np.ctypeslib.as_ctypes_type(np.uintc)) # E: Type[{c_uint}]
38+
reveal_type(np.ctypeslib.as_ctypes_type(np.uint)) # E: Type[{c_ulong}]
39+
reveal_type(np.ctypeslib.as_ctypes_type(np.ulonglong)) # E: Type[{c_ulonglong}]
40+
reveal_type(np.ctypeslib.as_ctypes_type(np.byte)) # E: Type[{c_byte}]
41+
reveal_type(np.ctypeslib.as_ctypes_type(np.short)) # E: Type[{c_short}]
42+
reveal_type(np.ctypeslib.as_ctypes_type(np.intc)) # E: Type[{c_int}]
43+
reveal_type(np.ctypeslib.as_ctypes_type(np.int_)) # E: Type[{c_long}]
44+
reveal_type(np.ctypeslib.as_ctypes_type(np.longlong)) # E: Type[{c_longlong}]
45+
reveal_type(np.ctypeslib.as_ctypes_type(np.single)) # E: Type[{c_float}]
46+
reveal_type(np.ctypeslib.as_ctypes_type(np.double)) # E: Type[{c_double}]
47+
reveal_type(np.ctypeslib.as_ctypes_type(np.longdouble)) # E: Type[{c_longdouble}]
48+
reveal_type(np.ctypeslib.as_ctypes_type(ctypes.c_double)) # E: Type[{c_double}]
4749
reveal_type(np.ctypeslib.as_ctypes_type("q")) # E: Type[ctypes.c_longlong]
4850
reveal_type(np.ctypeslib.as_ctypes_type([("i8", np.int64), ("f8", np.float64)])) # E: Type[Any]
4951
reveal_type(np.ctypeslib.as_ctypes_type("i8")) # E: Type[Any]
5052
reveal_type(np.ctypeslib.as_ctypes_type("f8")) # E: Type[Any]
5153

5254
reveal_type(np.ctypeslib.as_ctypes(AR_bool.take(0))) # E: ctypes.c_bool
53-
reveal_type(np.ctypeslib.as_ctypes(AR_ubyte.take(0))) # E: ctypes.c_ubyte
54-
reveal_type(np.ctypeslib.as_ctypes(AR_ushort.take(0))) # E: ctypes.c_ushort
55-
reveal_type(np.ctypeslib.as_ctypes(AR_uintc.take(0))) # E: ctypes.c_uint
56-
reveal_type(np.ctypeslib.as_ctypes(AR_uint.take(0))) # E: ctypes.c_ulong
57-
reveal_type(np.ctypeslib.as_ctypes(AR_ulonglong.take(0))) # E: ctypes.c_ulong
58-
reveal_type(np.ctypeslib.as_ctypes(AR_byte.take(0))) # E: ctypes.c_byte
59-
reveal_type(np.ctypeslib.as_ctypes(AR_short.take(0))) # E: ctypes.c_short
60-
reveal_type(np.ctypeslib.as_ctypes(AR_intc.take(0))) # E: ctypes.c_int
61-
reveal_type(np.ctypeslib.as_ctypes(AR_int.take(0))) # E: ctypes.c_long
62-
reveal_type(np.ctypeslib.as_ctypes(AR_longlong.take(0))) # E: ctypes.c_long
63-
reveal_type(np.ctypeslib.as_ctypes(AR_single.take(0))) # E: ctypes.c_float
64-
reveal_type(np.ctypeslib.as_ctypes(AR_double.take(0))) # E: ctypes.c_double
55+
reveal_type(np.ctypeslib.as_ctypes(AR_ubyte.take(0))) # E: {c_ubyte}
56+
reveal_type(np.ctypeslib.as_ctypes(AR_ushort.take(0))) # E: {c_ushort}
57+
reveal_type(np.ctypeslib.as_ctypes(AR_uintc.take(0))) # E: {c_uint}
58+
reveal_type(np.ctypeslib.as_ctypes(AR_uint.take(0))) # E: {c_ulong}
59+
reveal_type(np.ctypeslib.as_ctypes(AR_ulonglong.take(0))) # E: {c_ulonglong}
60+
reveal_type(np.ctypeslib.as_ctypes(AR_byte.take(0))) # E: {c_byte}
61+
reveal_type(np.ctypeslib.as_ctypes(AR_short.take(0))) # E: {c_short}
62+
reveal_type(np.ctypeslib.as_ctypes(AR_intc.take(0))) # E: {c_int}
63+
reveal_type(np.ctypeslib.as_ctypes(AR_int.take(0))) # E: {c_long}
64+
reveal_type(np.ctypeslib.as_ctypes(AR_longlong.take(0))) # E: {c_longlong}
65+
reveal_type(np.ctypeslib.as_ctypes(AR_single.take(0))) # E: {c_float}
66+
reveal_type(np.ctypeslib.as_ctypes(AR_double.take(0))) # E: {c_double}
67+
reveal_type(np.ctypeslib.as_ctypes(AR_longdouble.take(0))) # E: {c_longdouble}
6568
reveal_type(np.ctypeslib.as_ctypes(AR_void.take(0))) # E: Any
6669
reveal_type(np.ctypeslib.as_ctypes(AR_bool)) # E: ctypes.Array[ctypes.c_bool]
67-
reveal_type(np.ctypeslib.as_ctypes(AR_ubyte)) # E: ctypes.Array[ctypes.c_ubyte]
68-
reveal_type(np.ctypeslib.as_ctypes(AR_ushort)) # E: ctypes.Array[ctypes.c_ushort]
69-
reveal_type(np.ctypeslib.as_ctypes(AR_uintc)) # E: ctypes.Array[ctypes.c_uint]
70-
reveal_type(np.ctypeslib.as_ctypes(AR_uint)) # E: ctypes.Array[ctypes.c_ulong]
71-
reveal_type(np.ctypeslib.as_ctypes(AR_ulonglong)) # E: ctypes.Array[ctypes.c_ulong]
72-
reveal_type(np.ctypeslib.as_ctypes(AR_byte)) # E: ctypes.Array[ctypes.c_byte]
73-
reveal_type(np.ctypeslib.as_ctypes(AR_short)) # E: ctypes.Array[ctypes.c_short]
74-
reveal_type(np.ctypeslib.as_ctypes(AR_intc)) # E: ctypes.Array[ctypes.c_int]
75-
reveal_type(np.ctypeslib.as_ctypes(AR_int)) # E: ctypes.Array[ctypes.c_long]
76-
reveal_type(np.ctypeslib.as_ctypes(AR_longlong)) # E: ctypes.Array[ctypes.c_long]
77-
reveal_type(np.ctypeslib.as_ctypes(AR_single)) # E: ctypes.Array[ctypes.c_float]
78-
reveal_type(np.ctypeslib.as_ctypes(AR_double)) # E: ctypes.Array[ctypes.c_double]
70+
reveal_type(np.ctypeslib.as_ctypes(AR_ubyte)) # E: ctypes.Array[{c_ubyte}]
71+
reveal_type(np.ctypeslib.as_ctypes(AR_ushort)) # E: ctypes.Array[{c_ushort}]
72+
reveal_type(np.ctypeslib.as_ctypes(AR_uintc)) # E: ctypes.Array[{c_uint}]
73+
reveal_type(np.ctypeslib.as_ctypes(AR_uint)) # E: ctypes.Array[{c_ulong}]
74+
reveal_type(np.ctypeslib.as_ctypes(AR_ulonglong)) # E: ctypes.Array[{c_ulonglong}]
75+
reveal_type(np.ctypeslib.as_ctypes(AR_byte)) # E: ctypes.Array[{c_byte}]
76+
reveal_type(np.ctypeslib.as_ctypes(AR_short)) # E: ctypes.Array[{c_short}]
77+
reveal_type(np.ctypeslib.as_ctypes(AR_intc)) # E: ctypes.Array[{c_int}]
78+
reveal_type(np.ctypeslib.as_ctypes(AR_int)) # E: ctypes.Array[{c_long}]
79+
reveal_type(np.ctypeslib.as_ctypes(AR_longlong)) # E: ctypes.Array[{c_longlong}]
80+
reveal_type(np.ctypeslib.as_ctypes(AR_single)) # E: ctypes.Array[{c_float}]
81+
reveal_type(np.ctypeslib.as_ctypes(AR_double)) # E: ctypes.Array[{c_double}]
82+
reveal_type(np.ctypeslib.as_ctypes(AR_longdouble)) # E: ctypes.Array[{c_longdouble}]
7983
reveal_type(np.ctypeslib.as_ctypes(AR_void)) # E: ctypes.Array[Any]
8084

8185
reveal_type(np.ctypeslib.as_array(AR_ubyte)) # E: numpy.ndarray[Any, numpy.dtype[{ubyte}]]

numpy/typing/tests/test_typing.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,38 @@ def _test_fail(
187187
raise AssertionError(_FAIL_MSG2.format(lineno, expression, expected_error, error))
188188

189189

190+
def _construct_ctypes_dict() -> dict[str, str]:
191+
dct = {
192+
"ubyte": "c_ubyte",
193+
"ushort": "c_ushort",
194+
"uintc": "c_uint",
195+
"uint": "c_ulong",
196+
"ulonglong": "c_ulonglong",
197+
"byte": "c_byte",
198+
"short": "c_short",
199+
"intc": "c_int",
200+
"int_": "c_long",
201+
"longlong": "c_longlong",
202+
"single": "c_float",
203+
"double": "c_double",
204+
"longdouble": "c_longdouble",
205+
}
206+
207+
# Match `ctypes` names to the first ctypes type with a given kind and
208+
# precision, e.g. {"c_double": "c_double", "c_longdouble": "c_double"}
209+
# if both types represent 64-bit floats.
210+
# In this context "first" is defined by the order of `dct`
211+
ret = {}
212+
visited: dict[tuple[str, int], str] = {}
213+
for np_name, ct_name in dct.items():
214+
np_scalar = getattr(np, np_name)()
215+
216+
# Find the first `ctypes` type for a given `kind`/`itemsize` combo
217+
key = (np_scalar.dtype.kind, np_scalar.dtype.itemsize)
218+
ret[ct_name] = visited.setdefault(key, f"ctypes.{ct_name}")
219+
return ret
220+
221+
190222
def _construct_format_dict() -> dict[str, str]:
191223
dct = {k.split(".")[-1]: v.replace("numpy", "numpy.typing") for
192224
k, v in _PRECISION_DICT.items()}
@@ -261,6 +293,7 @@ def _construct_format_dict() -> dict[str, str]:
261293
#: A dictionary with all supported format keys (as keys)
262294
#: and matching values
263295
FORMAT_DICT: dict[str, str] = _construct_format_dict()
296+
FORMAT_DICT.update(_construct_ctypes_dict())
264297

265298

266299
def _parse_reveals(file: IO[str]) -> tuple[npt.NDArray[np.str_], list[str]]:

0 commit comments

Comments
 (0)