__init__.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. """
  2. ============================
  3. Typing (:mod:`numpy.typing`)
  4. ============================
  5. .. versionadded:: 1.20
  6. Large parts of the NumPy API have :pep:`484`-style type annotations. In
  7. addition a number of type aliases are available to users, most prominently
  8. the two below:
  9. - `ArrayLike`: objects that can be converted to arrays
  10. - `DTypeLike`: objects that can be converted to dtypes
  11. .. _typing-extensions: https://pypi.org/project/typing-extensions/
  12. Mypy plugin
  13. -----------
  14. .. versionadded:: 1.21
  15. .. automodule:: numpy.typing.mypy_plugin
  16. .. currentmodule:: numpy.typing
  17. Differences from the runtime NumPy API
  18. --------------------------------------
  19. NumPy is very flexible. Trying to describe the full range of
  20. possibilities statically would result in types that are not very
  21. helpful. For that reason, the typed NumPy API is often stricter than
  22. the runtime NumPy API. This section describes some notable
  23. differences.
  24. ArrayLike
  25. ~~~~~~~~~
  26. The `ArrayLike` type tries to avoid creating object arrays. For
  27. example,
  28. .. code-block:: python
  29. >>> np.array(x**2 for x in range(10))
  30. array(<generator object <genexpr> at ...>, dtype=object)
  31. is valid NumPy code which will create a 0-dimensional object
  32. array. Type checkers will complain about the above example when using
  33. the NumPy types however. If you really intended to do the above, then
  34. you can either use a ``# type: ignore`` comment:
  35. .. code-block:: python
  36. >>> np.array(x**2 for x in range(10)) # type: ignore
  37. or explicitly type the array like object as `~typing.Any`:
  38. .. code-block:: python
  39. >>> from typing import Any
  40. >>> array_like: Any = (x**2 for x in range(10))
  41. >>> np.array(array_like)
  42. array(<generator object <genexpr> at ...>, dtype=object)
  43. ndarray
  44. ~~~~~~~
  45. It's possible to mutate the dtype of an array at runtime. For example,
  46. the following code is valid:
  47. .. code-block:: python
  48. >>> x = np.array([1, 2])
  49. >>> x.dtype = np.bool_
  50. This sort of mutation is not allowed by the types. Users who want to
  51. write statically typed code should instead use the `numpy.ndarray.view`
  52. method to create a view of the array with a different dtype.
  53. DTypeLike
  54. ~~~~~~~~~
  55. The `DTypeLike` type tries to avoid creation of dtype objects using
  56. dictionary of fields like below:
  57. .. code-block:: python
  58. >>> x = np.dtype({"field1": (float, 1), "field2": (int, 3)})
  59. Although this is valid NumPy code, the type checker will complain about it,
  60. since its usage is discouraged.
  61. Please see : :ref:`Data type objects <arrays.dtypes>`
  62. Number precision
  63. ~~~~~~~~~~~~~~~~
  64. The precision of `numpy.number` subclasses is treated as a covariant generic
  65. parameter (see :class:`~NBitBase`), simplifying the annotating of processes
  66. involving precision-based casting.
  67. .. code-block:: python
  68. >>> from typing import TypeVar
  69. >>> import numpy as np
  70. >>> import numpy.typing as npt
  71. >>> T = TypeVar("T", bound=npt.NBitBase)
  72. >>> def func(a: "np.floating[T]", b: "np.floating[T]") -> "np.floating[T]":
  73. ... ...
  74. Consequently, the likes of `~numpy.float16`, `~numpy.float32` and
  75. `~numpy.float64` are still sub-types of `~numpy.floating`, but, contrary to
  76. runtime, they're not necessarily considered as sub-classes.
  77. Timedelta64
  78. ~~~~~~~~~~~
  79. The `~numpy.timedelta64` class is not considered a subclass of
  80. `~numpy.signedinteger`, the former only inheriting from `~numpy.generic`
  81. while static type checking.
  82. 0D arrays
  83. ~~~~~~~~~
  84. During runtime numpy aggressively casts any passed 0D arrays into their
  85. corresponding `~numpy.generic` instance. Until the introduction of shape
  86. typing (see :pep:`646`) it is unfortunately not possible to make the
  87. necessary distinction between 0D and >0D arrays. While thus not strictly
  88. correct, all operations are that can potentially perform a 0D-array -> scalar
  89. cast are currently annotated as exclusively returning an `ndarray`.
  90. If it is known in advance that an operation _will_ perform a
  91. 0D-array -> scalar cast, then one can consider manually remedying the
  92. situation with either `typing.cast` or a ``# type: ignore`` comment.
  93. Record array dtypes
  94. ~~~~~~~~~~~~~~~~~~~
  95. The dtype of `numpy.recarray`, and the `numpy.rec` functions in general,
  96. can be specified in one of two ways:
  97. * Directly via the ``dtype`` argument.
  98. * With up to five helper arguments that operate via `numpy.format_parser`:
  99. ``formats``, ``names``, ``titles``, ``aligned`` and ``byteorder``.
  100. These two approaches are currently typed as being mutually exclusive,
  101. *i.e.* if ``dtype`` is specified than one may not specify ``formats``.
  102. While this mutual exclusivity is not (strictly) enforced during runtime,
  103. combining both dtype specifiers can lead to unexpected or even downright
  104. buggy behavior.
  105. API
  106. ---
  107. """
  108. # NOTE: The API section will be appended with additional entries
  109. # further down in this file
  110. from numpy._typing import (
  111. ArrayLike,
  112. DTypeLike,
  113. NBitBase,
  114. NDArray,
  115. )
  116. __all__ = ["ArrayLike", "DTypeLike", "NBitBase", "NDArray"]
  117. if __doc__ is not None:
  118. from numpy._typing._add_docstring import _docstrings
  119. __doc__ += _docstrings
  120. __doc__ += '\n.. autoclass:: numpy.typing.NBitBase\n'
  121. del _docstrings
  122. from numpy._pytesttester import PytestTester
  123. test = PytestTester(__name__)
  124. del PytestTester