8000 TYP: add missing annotations for `numpy.object_.__new__` · numpy/numpy@b72d0c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit b72d0c7

Browse files
committed
TYP: add missing annotations for numpy.object_.__new__
1 parent 42b22a2 commit b72d0c7

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

numpy/__init__.pyi

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,8 +2620,6 @@ _NBit1 = TypeVar("_NBit1", bound=NBitBase)
26202620
_NBit2 = TypeVar("_NBit2", bound=NBitBase)
26212621

26222622
class generic(_ArrayOrScalarCommon):
2623-
@abstractmethod
2624-
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
26252623
# TODO: use `tuple[()]` as shape type once covariant (#26081)
26262624
@overload
26272625
def __array__(self: _ScalarType, dtype: None = ..., /) -> NDArray[_ScalarType]: ...
@@ -2848,12 +2846,41 @@ class bool(generic):
28482846

28492847
bool_: TypeAlias = bool
28502848

2849+
_StringType = TypeVar("_StringType", bound=str | bytes)
2850+
_StringType = TypeVar("_StringType", bound=str | bytes)
2851+
_ShapeType = TypeVar("_ShapeType", bound=Any)
2852+
_ObjectType = TypeVar("_ObjectType", bound=object)
2853+
2854+
# A sequence-like interface like `collections.abc.Sequence`, but without the
2855+
# irrelevant methods.
2856+
class _SimpleSequence(Protocol):
2857+
def __len__(self, /) -> int: ...
2858+
def __getitem__(self, index: int, /) -> Any: ...
2859+
2860+
# The `object_` constructor returns the passed object, so instances with type
2861+
# `object_` cannot exists (at runtime).
28512862
class object_(generic):
2852-
def __init__(self, value: object = ..., /) -> None: ...
2863+
@overload
2864+
def __new__(cls, nothing_to_see_here: None = ..., /) -> None: ...
2865+
@overload
2866+
def __new__(cls, stringy: _StringType, /) -> _StringType: ...
2867+
@overload
2868+
def __new__(
2869+
cls,
2870+
array: ndarray[_ShapeType, Any], /,
2871+
) -> ndarray[_ShapeType, dtype[object_]]: ...
2872+
@overload
2873+
def __new__(cls, sequence: _SimpleSequence, /) -> NDArray[object_]: ...
2874+
@overload
2875+
def __new__(cls, value: _ObjectType, /) -> _ObjectType: ...
2876+
# catch-all
2877+
@overload
2878+
def __new__(cls, value: Any = ..., /) -> object | NDArray[object_]: ...
2879+
28532880
@property
2854-
def real(self: _ArraySelf) -> _ArraySelf: ...
2881+
def real(self) -> object_: ...
28552882
@property
2856-
def imag(self: _ArraySelf) -> _ArraySelf: ...
2883+
def imag(self) -> object_: ...
28572884
# The 3 protocols below may or may not raise,
28582885
# depending on the underlying object
28592886
def __int__(self) -> int: ...

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ m: np.timedelta64
1919
U: np.str_
2020
S: np.bytes_
2121
V: np.void
22+
O: np.object_ # cannot exists at runtime
23+
24+
array_nd: np.ndarray[Any, Any]
25+
array_0d: np.ndarray[tuple[()], Any]
26+
array_2d_2x2: np.ndarray[tuple[Literal[2], Literal[2]], Any]
2227

2328
assert_type(c8.real, np.float32)
2429
assert_type(c8.imag, np.float32)
@@ -156,3 +161,27 @@ assert_type(f8.__ceil__(), int)
156161
assert_type(f8.__floor__(), int)
157162

158163
assert_type(i8.is_integer(), Literal[True])
164+
165+
assert_type(O.real, np.object_)
166+
assert_type(O.imag, np.object_)
167+
assert_type(int(O), int)
168+
assert_type(float(O), float)
169+
assert_type(complex(O), complex)
170+
171+
# These fail fail because of a mypy __new__ bug:
172+
# https://github.com/python/mypy/issues/15182
173+
# According to the typing spec, the following statements are valid, see
174+
# https://typing.readthedocs.io/en/latest/spec/constructors.html#new-method
175+
176+
# assert_type(np.object_(), None)
177+
# assert_type(np.object_(None), None)
178+
# assert_type(np.object_(array_nd), np.ndarray[Any, np.dtype[np.object_]])
179+
# assert_type(np.object_([]), npt.NDArray[np.object_])
180+
# assert_type(np.object_(()), npt.NDArray[np.object_])
181+
# assert_type(np.object_(range(4)), npt.NDArray[np.object_])
182+
# assert_type(np.object_(+42), int)
183+
# assert_type(np.object_(1 / 137), float)
184+
# assert_type(np.object_('Developers! ' * (1 << 6)), str)
185+
# assert_type(np.object_(object()), object)
186+
# assert_type(np.object_({False, True, NotADirectoryError}), set[Any])
187+
# assert_type(np.object_({'spam': 'food', 'ham': 'food'}), dict[str, str])

0 commit comments

Comments
 (0)
0