Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/numpy/typing/__init__.py: 78%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

23 statements  

1""" 

2============================ 

3Typing (:mod:`numpy.typing`) 

4============================ 

5 

6.. versionadded:: 1.20 

7 

8Large parts of the NumPy API have :pep:`484`-style type annotations. In 

9addition a number of type aliases are available to users, most prominently 

10the two below: 

11 

12- `ArrayLike`: objects that can be converted to arrays 

13- `DTypeLike`: objects that can be converted to dtypes 

14 

15.. _typing-extensions: https://pypi.org/project/typing-extensions/ 

16 

17Mypy plugin 

18----------- 

19 

20.. versionadded:: 1.21 

21 

22.. automodule:: numpy.typing.mypy_plugin 

23 

24.. currentmodule:: numpy.typing 

25 

26Differences from the runtime NumPy API 

27-------------------------------------- 

28 

29NumPy is very flexible. Trying to describe the full range of 

30possibilities statically would result in types that are not very 

31helpful. For that reason, the typed NumPy API is often stricter than 

32the runtime NumPy API. This section describes some notable 

33differences. 

34 

35ArrayLike 

36~~~~~~~~~ 

37 

38The `ArrayLike` type tries to avoid creating object arrays. For 

39example, 

40 

41.. code-block:: python 

42 

43 >>> np.array(x**2 for x in range(10)) 

44 array(<generator object <genexpr> at ...>, dtype=object) 

45 

46is valid NumPy code which will create a 0-dimensional object 

47array. Type checkers will complain about the above example when using 

48the NumPy types however. If you really intended to do the above, then 

49you can either use a ``# type: ignore`` comment: 

50 

51.. code-block:: python 

52 

53 >>> np.array(x**2 for x in range(10)) # type: ignore 

54 

55or explicitly type the array like object as `~typing.Any`: 

56 

57.. code-block:: python 

58 

59 >>> from typing import Any 

60 >>> array_like: Any = (x**2 for x in range(10)) 

61 >>> np.array(array_like) 

62 array(<generator object <genexpr> at ...>, dtype=object) 

63 

64ndarray 

65~~~~~~~ 

66 

67It's possible to mutate the dtype of an array at runtime. For example, 

68the following code is valid: 

69 

70.. code-block:: python 

71 

72 >>> x = np.array([1, 2]) 

73 >>> x.dtype = np.bool 

74 

75This sort of mutation is not allowed by the types. Users who want to 

76write statically typed code should instead use the `numpy.ndarray.view` 

77method to create a view of the array with a different dtype. 

78 

79DTypeLike 

80~~~~~~~~~ 

81 

82The `DTypeLike` type tries to avoid creation of dtype objects using 

83dictionary of fields like below: 

84 

85.. code-block:: python 

86 

87 >>> x = np.dtype({"field1": (float, 1), "field2": (int, 3)}) 

88 

89Although this is valid NumPy code, the type checker will complain about it, 

90since its usage is discouraged. 

91Please see : :ref:`Data type objects <arrays.dtypes>` 

92 

93Number precision 

94~~~~~~~~~~~~~~~~ 

95 

96The precision of `numpy.number` subclasses is treated as a invariant generic 

97parameter (see :class:`~NBitBase`), simplifying the annotating of processes 

98involving precision-based casting. 

99 

100.. code-block:: python 

101 

102 >>> from typing import TypeVar 

103 >>> import numpy as np 

104 >>> import numpy.typing as npt 

105 

106 >>> T = TypeVar("T", bound=npt.NBitBase) 

107 >>> def func(a: np.floating[T], b: np.floating[T]) -> np.floating[T]: 

108 ... ... 

109 

110Consequently, the likes of `~numpy.float16`, `~numpy.float32` and 

111`~numpy.float64` are still sub-types of `~numpy.floating`, but, contrary to 

112runtime, they're not necessarily considered as sub-classes. 

113 

114.. deprecated:: 2.3 

115 The :class:`~numpy.typing.NBitBase` helper is deprecated and will be 

116 removed in a future release. Prefer expressing precision relationships via 

117 ``typing.overload`` or ``TypeVar`` definitions bounded by concrete scalar 

118 classes. For example: 

119 

120 .. code-block:: python 

121 

122 from typing import TypeVar 

123 import numpy as np 

124 

125 S = TypeVar("S", bound=np.floating) 

126 

127 def func(a: S, b: S) -> S: 

128 ... 

129 

130 or in the case of different input types mapping to different output types: 

131 

132 .. code-block:: python 

133 

134 from typing import overload 

135 import numpy as np 

136 

137 @overload 

138 def phase(x: np.complex64) -> np.float32: ... 

139 @overload 

140 def phase(x: np.complex128) -> np.float64: ... 

141 @overload 

142 def phase(x: np.clongdouble) -> np.longdouble: ... 

143 def phase(x: np.complexfloating) -> np.floating: 

144 ... 

145 

146Timedelta64 

147~~~~~~~~~~~ 

148 

149The `~numpy.timedelta64` class is not considered a subclass of 

150`~numpy.signedinteger`, the former only inheriting from `~numpy.generic` 

151while static type checking. 

152 

1530D arrays 

154~~~~~~~~~ 

155 

156During runtime numpy aggressively casts any passed 0D arrays into their 

157corresponding `~numpy.generic` instance. Until the introduction of shape 

158typing (see :pep:`646`) it is unfortunately not possible to make the 

159necessary distinction between 0D and >0D arrays. While thus not strictly 

160correct, all operations that can potentially perform a 0D-array -> scalar 

161cast are currently annotated as exclusively returning an `~numpy.ndarray`. 

162 

163If it is known in advance that an operation *will* perform a 

1640D-array -> scalar cast, then one can consider manually remedying the 

165situation with either `typing.cast` or a ``# type: ignore`` comment. 

166 

167Record array dtypes 

168~~~~~~~~~~~~~~~~~~~ 

169 

170The dtype of `numpy.recarray`, and the :ref:`routines.array-creation.rec` 

171functions in general, can be specified in one of two ways: 

172 

173* Directly via the ``dtype`` argument. 

174* With up to five helper arguments that operate via `numpy.rec.format_parser`: 

175 ``formats``, ``names``, ``titles``, ``aligned`` and ``byteorder``. 

176 

177These two approaches are currently typed as being mutually exclusive, 

178*i.e.* if ``dtype`` is specified than one may not specify ``formats``. 

179While this mutual exclusivity is not (strictly) enforced during runtime, 

180combining both dtype specifiers can lead to unexpected or even downright 

181buggy behavior. 

182 

183API 

184--- 

185 

186""" 

187# NOTE: The API section will be appended with additional entries 

188# further down in this file 

189 

190# pyright: reportDeprecated=false 

191 

192from numpy._typing import ArrayLike, DTypeLike, NBitBase, NDArray 

193 

194__all__ = ["ArrayLike", "DTypeLike", "NBitBase", "NDArray"] 

195 

196 

197__DIR = __all__ + [k for k in globals() if k.startswith("__") and k.endswith("__")] 

198__DIR_SET = frozenset(__DIR) 

199 

200 

201def __dir__() -> list[str]: 

202 return __DIR 

203 

204def __getattr__(name: str) -> object: 

205 if name == "NBitBase": 

206 import warnings 

207 

208 # Deprecated in NumPy 2.3, 2025-05-01 

209 warnings.warn( 

210 "`NBitBase` is deprecated and will be removed from numpy.typing in the " 

211 "future. Use `@typing.overload` or a `TypeVar` with a scalar-type as upper " 

212 "bound, instead. (deprecated in NumPy 2.3)", 

213 DeprecationWarning, 

214 stacklevel=2, 

215 ) 

216 return NBitBase 

217 

218 if name in __DIR_SET: 

219 return globals()[name] 

220 

221 raise AttributeError(f"module {__name__!r} has no attribute {name!r}") 

222 

223 

224if __doc__ is not None: 

225 from numpy._typing._add_docstring import _docstrings 

226 __doc__ += _docstrings 

227 __doc__ += '\n.. autoclass:: numpy.typing.NBitBase\n' 

228 del _docstrings 

229 

230from numpy._pytesttester import PytestTester 

231 

232test = PytestTester(__name__) 

233del PytestTester