summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2021-07-16 18:42:32 -0600
committerGitHub <noreply@github.com>2021-07-16 18:42:32 -0600
commit94de9f7007b9264328dfa16dcf60a8c34a2c8ec0 (patch)
treefb05c8ffa0df99ff6dae920f8d0647f1e17cc2ed /numpy
parente9fb9335399580aaef1e5fa01e6f7afc79b82792 (diff)
parente7cd1e78ce728e3b745cea5a34c7fdea0f5c378e (diff)
downloadnumpy-94de9f7007b9264328dfa16dcf60a8c34a2c8ec0.tar.gz
Merge pull request #19468 from BvB93/ctypes_dtype
MAINT: Add missing `dtype` overloads for object- and ctypes-based inputs
Diffstat (limited to 'numpy')
-rw-r--r--numpy/__init__.pyi76
-rw-r--r--numpy/typing/tests/data/fail/dtype.py2
-rw-r--r--numpy/typing/tests/data/reveal/dtype.py10
3 files changed, 54 insertions, 34 deletions
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index ca0c79b17..47ab53ef3 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -2,6 +2,7 @@ import builtins
import os
import sys
import mmap
+import ctypes as ct
import array as _array
import datetime as dt
from abc import abstractmethod
@@ -911,7 +912,7 @@ class dtype(Generic[_DTypeScalar_co]):
# other special cases. Order is sometimes important because of the
# subtype relationships
#
- # bool < int < float < complex
+ # bool < int < float < complex < object
#
# so we have to make sure the overloads for the narrowest type is
# first.
@@ -929,51 +930,54 @@ class dtype(Generic[_DTypeScalar_co]):
@overload
def __new__(cls, dtype: Type[bytes], align: bool = ..., copy: bool = ...) -> dtype[bytes_]: ...
- # `unsignedinteger` string-based representations
+ # `unsignedinteger` string-based representations and ctypes
@overload
- def __new__(cls, dtype: _UInt8Codes, align: bool = ..., copy: bool = ...) -> dtype[uint8]: ...
+ def __new__(cls, dtype: _UInt8Codes | Type[ct.c_uint8], align: bool = ..., copy: bool = ...) -> dtype[uint8]: ...
@overload
- def __new__(cls, dtype: _UInt16Codes, align: bool = ..., copy: bool = ...) -> dtype[uint16]: ...
+ def __new__(cls, dtype: _UInt16Codes | Type[ct.c_uint16], align: bool = ..., copy: bool = ...) -> dtype[uint16]: ...
@overload
- def __new__(cls, dtype: _UInt32Codes, align: bool = ..., copy: bool = ...) -> dtype[uint32]: ...
+ def __new__(cls, dtype: _UInt32Codes | Type[ct.c_uint32], align: bool = ..., copy: bool = ...) -> dtype[uint32]: ...
@overload
- def __new__(cls, dtype: _UInt64Codes, align: bool = ..., copy: bool = ...) -> dtype[uint64]: ...
+ def __new__(cls, dtype: _UInt64Codes | Type[ct.c_uint64], align: bool = ..., copy: bool = ...) -> dtype[uint64]: ...
@overload
- def __new__(cls, dtype: _UByteCodes, align: bool = ..., copy: bool = ...) -> dtype[ubyte]: ...
+ def __new__(cls, dtype: _UByteCodes | Type[ct.c_ubyte], align: bool = ..., copy: bool = ...) -> dtype[ubyte]: ...
@overload
- def __new__(cls, dtype: _UShortCodes, align: bool = ..., copy: bool = ...) -> dtype[ushort]: ...
+ def __new__(cls, dtype: _UShortCodes | Type[ct.c_ushort], align: bool = ..., copy: bool = ...) -> dtype[ushort]: ...
@overload
- def __new__(cls, dtype: _UIntCCodes, align: bool = ..., copy: bool = ...) -> dtype[uintc]: ...
+ def __new__(cls, dtype: _UIntCCodes | Type[ct.c_uint], align: bool = ..., copy: bool = ...) -> dtype[uintc]: ...
+
+ # NOTE: We're assuming here that `uint_ptr_t == size_t`,
+ # an assumption that does not hold in rare cases (same for `ssize_t`)
@overload
- def __new__(cls, dtype: _UIntPCodes, align: bool = ..., copy: bool = ...) -> dtype[uintp]: ...
+ def __new__(cls, dtype: _UIntPCodes | Type[ct.c_void_p] | Type[ct.c_size_t], align: bool = ..., copy: bool = ...) -> dtype[uintp]: ...
@overload
- def __new__(cls, dtype: _UIntCodes, align: bool = ..., copy: bool = ...) -> dtype[uint]: ...
+ def __new__(cls, dtype: _UIntCodes | Type[ct.c_ulong], align: bool = ..., copy: bool = ...) -> dtype[uint]: ...
@overload
- def __new__(cls, dtype: _ULongLongCodes, align: bool = ..., copy: bool = ...) -> dtype[ulonglong]: ...
+ def __new__(cls, dtype: _ULongLongCodes | Type[ct.c_ulonglong], align: bool = ..., copy: bool = ...) -> dtype[ulonglong]: ...
- # `signedinteger` string-based representations
+ # `signedinteger` string-based representations and ctypes
@overload
- def __new__(cls, dtype: _Int8Codes, align: bool = ..., copy: bool = ...) -> dtype[int8]: ...
+ def __new__(cls, dtype: _Int8Codes | Type[ct.c_int8], align: bool = ..., copy: bool = ...) -> dtype[int8]: ...
@overload
- def __new__(cls, dtype: _Int16Codes, align: bool = ..., copy: bool = ...) -> dtype[int16]: ...
+ def __new__(cls, dtype: _Int16Codes | Type[ct.c_int16], align: bool = ..., copy: bool = ...) -> dtype[int16]: ...
@overload
- def __new__(cls, dtype: _Int32Codes, align: bool = ..., copy: bool = ...) -> dtype[int32]: ...
+ def __new__(cls, dtype: _Int32Codes | Type[ct.c_int32], align: bool = ..., copy: bool = ...) -> dtype[int32]: ...
@overload
- def __new__(cls, dtype: _Int64Codes, align: bool = ..., copy: bool = ...) -> dtype[int64]: ...
+ def __new__(cls, dtype: _Int64Codes | Type[ct.c_int64], align: bool = ..., copy: bool = ...) -> dtype[int64]: ...
@overload
- def __new__(cls, dtype: _ByteCodes, align: bool = ..., copy: bool = ...) -> dtype[byte]: ...
+ def __new__(cls, dtype: _ByteCodes | Type[ct.c_byte], align: bool = ..., copy: bool = ...) -> dtype[byte]: ...
@overload
- def __new__(cls, dtype: _ShortCodes, align: bool = ..., copy: bool = ...) -> dtype[short]: ...
+ def __new__(cls, dtype: _ShortCodes | Type[ct.c_short], align: bool = ..., copy: bool = ...) -> dtype[short]: ...
@overload
- def __new__(cls, dtype: _IntCCodes, align: bool = ..., copy: bool = ...) -> dtype[intc]: ...
+ def __new__(cls, dtype: _IntCCodes | Type[ct.c_int], align: bool = ..., copy: bool = ...) -> dtype[intc]: ...
@overload
- def __new__(cls, dtype: _IntPCodes, align: bool = ..., copy: bool = ...) -> dtype[intp]: ...
+ def __new__(cls, dtype: _IntPCodes | Type[ct.c_ssize_t], align: bool = ..., copy: bool = ...) -> dtype[intp]: ...
@overload
- def __new__(cls, dtype: _IntCodes, align: bool = ..., copy: bool = ...) -> dtype[int_]: ...
+ def __new__(cls, dtype: _IntCodes | Type[ct.c_long], align: bool = ..., copy: bool = ...) -> dtype[int_]: ...
@overload
- def __new__(cls, dtype: _LongLongCodes, align: bool = ..., copy: bool = ...) -> dtype[longlong]: ...
+ def __new__(cls, dtype: _LongLongCodes | Type[ct.c_longlong], align: bool = ..., copy: bool = ...) -> dtype[longlong]: ...
- # `floating` string-based representations
+ # `floating` string-based representations and ctypes
@overload
def __new__(cls, dtype: _Float16Codes, align: bool = ..., copy: bool = ...) -> dtype[float16]: ...
@overload
@@ -983,11 +987,11 @@ class dtype(Generic[_DTypeScalar_co]):
@overload
def __new__(cls, dtype: _HalfCodes, align: bool = ..., copy: bool = ...) -> dtype[half]: ...
@overload
- def __new__(cls, dtype: _SingleCodes, align: bool = ..., copy: bool = ...) -> dtype[single]: ...
+ def __new__(cls, dtype: _SingleCodes | Type[ct.c_float], align: bool = ..., copy: bool = ...) -> dtype[single]: ...
@overload
- def __new__(cls, dtype: _DoubleCodes, align: bool = ..., copy: bool = ...) -> dtype[double]: ...
+ def __new__(cls, dtype: _DoubleCodes | Type[ct.c_double], align: bool = ..., copy: bool = ...) -> dtype[double]: ...
@overload
- def __new__(cls, dtype: _LongDoubleCodes, align: bool = ..., copy: bool = ...) -> dtype[longdouble]: ...
+ def __new__(cls, dtype: _LongDoubleCodes | Type[ct.c_longdouble], align: bool = ..., copy: bool = ...) -> dtype[longdouble]: ...
# `complexfloating` string-based representations
@overload
@@ -1001,9 +1005,9 @@ class dtype(Generic[_DTypeScalar_co]):
@overload
def __new__(cls, dtype: _CLongDoubleCodes, align: bool = ..., copy: bool = ...) -> dtype[clongdouble]: ...
- # Miscellaneous string-based representations
+ # Miscellaneous string-based representations and ctypes
@overload
- def __new__(cls, dtype: _BoolCodes, align: bool = ..., copy: bool = ...) -> dtype[bool_]: ...
+ def __new__(cls, dtype: _BoolCodes | Type[ct.c_bool], align: bool = ..., copy: bool = ...) -> dtype[bool_]: ...
@overload
def __new__(cls, dtype: _TD64Codes, align: bool = ..., copy: bool = ...) -> dtype[timedelta64]: ...
@overload
@@ -1011,11 +1015,11 @@ class dtype(Generic[_DTypeScalar_co]):
@overload
def __new__(cls, dtype: _StrCodes, align: bool = ..., copy: bool = ...) -> dtype[str_]: ...
@overload
- def __new__(cls, dtype: _BytesCodes, align: bool = ..., copy: bool = ...) -> dtype[bytes_]: ...
+ def __new__(cls, dtype: _BytesCodes | Type[ct.c_char], align: bool = ..., copy: bool = ...) -> dtype[bytes_]: ...
@overload
def __new__(cls, dtype: _VoidCodes, align: bool = ..., copy: bool = ...) -> dtype[void]: ...
@overload
- def __new__(cls, dtype: _ObjectCodes, align: bool = ..., copy: bool = ...) -> dtype[object_]: ...
+ def __new__(cls, dtype: _ObjectCodes | Type[ct.py_object], align: bool = ..., copy: bool = ...) -> dtype[object_]: ...
# dtype of a dtype is the same dtype
@overload
@@ -1040,7 +1044,7 @@ class dtype(Generic[_DTypeScalar_co]):
align: bool = ...,
copy: bool = ...,
) -> dtype[Any]: ...
- # Catchall overload
+ # Catchall overload for void-likes
@overload
def __new__(
cls,
@@ -1048,6 +1052,14 @@ class dtype(Generic[_DTypeScalar_co]):
align: bool = ...,
copy: bool = ...,
) -> dtype[void]: ...
+ # Catchall overload for object-likes
+ @overload
+ def __new__(
+ cls,
+ dtype: Type[object],
+ align: bool = ...,
+ copy: bool = ...,
+ ) -> dtype[object_]: ...
@overload
def __getitem__(self: dtype[void], key: List[str]) -> dtype[void]: ...
diff --git a/numpy/typing/tests/data/fail/dtype.py b/numpy/typing/tests/data/fail/dtype.py
index 7d419a1d1..0f3810f3c 100644
--- a/numpy/typing/tests/data/fail/dtype.py
+++ b/numpy/typing/tests/data/fail/dtype.py
@@ -18,5 +18,3 @@ np.dtype( # E: No overload variant of "dtype" matches
"field2": (int, 3),
}
)
-
-np.dtype[np.float64](np.int64) # E: Argument 1 to "dtype" has incompatible type
diff --git a/numpy/typing/tests/data/reveal/dtype.py b/numpy/typing/tests/data/reveal/dtype.py
index eb1489bf3..364d1dcab 100644
--- a/numpy/typing/tests/data/reveal/dtype.py
+++ b/numpy/typing/tests/data/reveal/dtype.py
@@ -1,3 +1,4 @@
+import ctypes as ct
import numpy as np
dtype_U: np.dtype[np.str_]
@@ -23,6 +24,15 @@ reveal_type(np.dtype(int)) # E: numpy.dtype[{int_}]
reveal_type(np.dtype(bool)) # E: numpy.dtype[numpy.bool_]
reveal_type(np.dtype(str)) # E: numpy.dtype[numpy.str_]
reveal_type(np.dtype(bytes)) # E: numpy.dtype[numpy.bytes_]
+reveal_type(np.dtype(object)) # E: numpy.dtype[numpy.object_]
+
+# ctypes
+reveal_type(np.dtype(ct.c_double)) # E: numpy.dtype[{double}]
+reveal_type(np.dtype(ct.c_longlong)) # E: numpy.dtype[{longlong}]
+reveal_type(np.dtype(ct.c_uint32)) # E: numpy.dtype[{uint32}]
+reveal_type(np.dtype(ct.c_bool)) # E: numpy.dtype[numpy.bool_]
+reveal_type(np.dtype(ct.c_char)) # E: numpy.dtype[numpy.bytes_]
+reveal_type(np.dtype(ct.py_object)) # E: numpy.dtype[numpy.object_]
# Special case for None
reveal_type(np.dtype(None)) # E: numpy.dtype[{double}]