1"""A module with the precisions of generic `~numpy.number` types."""
2from typing import final
3
4from numpy._utils import set_module
5
6
7@final # Disallow the creation of arbitrary `NBitBase` subclasses
8@set_module("numpy.typing")
9class NBitBase:
10 """
11 A type representing `numpy.number` precision during static type checking.
12
13 Used exclusively for the purpose of static type checking, `NBitBase`
14 represents the base of a hierarchical set of subclasses.
15 Each subsequent subclass is herein used for representing a lower level
16 of precision, *e.g.* ``64Bit > 32Bit > 16Bit``.
17
18 .. versionadded:: 1.20
19
20 .. deprecated:: 2.3
21 Use ``@typing.overload`` or a ``TypeVar`` with a scalar-type as upper
22 bound, instead.
23
24 Examples
25 --------
26 Below is a typical usage example: `NBitBase` is herein used for annotating
27 a function that takes a float and integer of arbitrary precision
28 as arguments and returns a new float of whichever precision is largest
29 (*e.g.* ``np.float16 + np.int64 -> np.float64``).
30
31 .. code-block:: python
32
33 >>> from typing import TypeVar, TYPE_CHECKING
34 >>> import numpy as np
35 >>> import numpy.typing as npt
36
37 >>> S = TypeVar("S", bound=npt.NBitBase)
38 >>> T = TypeVar("T", bound=npt.NBitBase)
39
40 >>> def add(a: np.floating[S], b: np.integer[T]) -> np.floating[S | T]:
41 ... return a + b
42
43 >>> a = np.float16()
44 >>> b = np.int64()
45 >>> out = add(a, b)
46
47 >>> if TYPE_CHECKING:
48 ... reveal_locals()
49 ... # note: Revealed local types are:
50 ... # note: a: numpy.floating[numpy.typing._16Bit*]
51 ... # note: b: numpy.signedinteger[numpy.typing._64Bit*]
52 ... # note: out: numpy.floating[numpy.typing._64Bit*]
53
54 """
55 # Deprecated in NumPy 2.3, 2025-05-01
56
57 def __init_subclass__(cls) -> None:
58 allowed_names = {
59 "NBitBase", "_128Bit", "_96Bit", "_64Bit", "_32Bit", "_16Bit", "_8Bit"
60 }
61 if cls.__name__ not in allowed_names:
62 raise TypeError('cannot inherit from final class "NBitBase"')
63 super().__init_subclass__()
64
65@final
66@set_module("numpy._typing")
67# Silence errors about subclassing a `@final`-decorated class
68class _128Bit(NBitBase): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
69 pass
70
71@final
72@set_module("numpy._typing")
73class _96Bit(_128Bit): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
74 pass
75
76@final
77@set_module("numpy._typing")
78class _64Bit(_96Bit): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
79 pass
80
81@final
82@set_module("numpy._typing")
83class _32Bit(_64Bit): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
84 pass
85
86@final
87@set_module("numpy._typing")
88class _16Bit(_32Bit): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
89 pass
90
91@final
92@set_module("numpy._typing")
93class _8Bit(_16Bit): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
94 pass