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

Skip to content

Commit e971242

Browse files
committed
TYP: Add missing annotations for numpy.object_.__new__
1 parent 89b6820 commit e971242

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

numpy/__init__.pyi

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2962,13 +2962,41 @@ class bool(generic):
29622962

29632963
bool_: TypeAlias = bool
29642964

2965+
_StringType = TypeVar("_StringType", bound=str | bytes)
2966+
_ShapeType = TypeVar("_ShapeType", bound=Any)
2967+
_ObjectType = TypeVar("_ObjectType", bound=object)
2968+
2969+
# A sequence-like interface like `collections.abc.Sequence`, but without the
2970+
# irrelevant methods.
2971+
class _SimpleSequence(Protocol):
2972+
def __len__(self, /) -> int: ...
2973+
def __getitem__(self, index: int, /) -> Any: ...
2974+
2975+
# The `object_` constructor returns the passed object, so instances with type
2976+
# `object_` cannot exists (at runtime).
29652977
@final
29662978
class object_(generic):
2967-
def __init__(self, value: object = ..., /) -> None: ...
2979+
@overload
2980+
def __new__(cls, nothing_to_see_here: None = ..., /) -> None: ...
2981+
@overload
2982+
def __new__(cls, stringy: _StringType, /) -> _StringType: ...
2983+
@overload
2984+
def __new__(
2985+
cls,
2986+
array: ndarray[_ShapeType, Any], /,
2987+
) -> ndarray[_ShapeType, dtype[object_]]: ...
2988+
@overload
2989+
def __new__(cls, sequence: _SimpleSequence, /) -> NDArray[object_]: ...
2990+
@overload
2991+
def __new__(cls, value: _ObjectType, /) -> _ObjectType: ...
2992+
# catch-all
2993+
@overload
2994+
def __new__(cls, value: Any = ..., /) -> object | NDArray[object_]: ...
2995+
29682996
@property
2969-
def real(self: _ArraySelf) -> _ArraySelf: ...
2997+
def real(self) -> object_: ...
29702998
@property
2971-
def imag(self: _ArraySelf) -> _ArraySelf: ...
2999+
def imag(self) -> object_: ...
29723000
# The 3 protocols below may or may not raise,
29733001
# depending on the underlying object
29743002
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