🌐 AI搜索 & 代理 主页
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions doc/release/upcoming_changes/28884.deprecation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
``numpy.typing.NBitBase`` deprecation
-------------------------------------
The ``numpy.typing.NBitBase`` type has been deprecated and will be removed in a future version.

This type was previously intended to be used as a generic upper bound for type-parameters, for example:

.. code-block:: python

import numpy as np
import numpy.typing as npt

def f[NT: npt.NBitBase](x: np.complexfloating[NT]) -> np.floating[NT]: ...

But in NumPy 2.2.0, ``float64`` and ``complex128`` were changed to concrete subtypes, causing static type-checkers to reject ``x: np.float64 = f(np.complex128(42j))``.

So instead, the better approach is to use ``typing.overload``:

.. code-block:: python

import numpy as np
from typing import overload

@overload
def f(x: np.complex64) -> np.float32: ...
@overload
def f(x: np.complex128) -> np.float64: ...
@overload
def f(x: np.clongdouble) -> np.longdouble: ...
2 changes: 1 addition & 1 deletion numpy/_typing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
_NestedSequence as _NestedSequence,
)
from ._nbit_base import (
NBitBase as NBitBase,
NBitBase as NBitBase, # pyright: ignore[reportDeprecated]
_8Bit as _8Bit,
_16Bit as _16Bit,
_32Bit as _32Bit,
Expand Down
7 changes: 6 additions & 1 deletion numpy/_typing/_nbit_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ class NBitBase:
"""
A type representing `numpy.number` precision during static type checking.

Used exclusively for the purpose static type checking, `NBitBase`
Used exclusively for the purpose of static type checking, `NBitBase`
represents the base of a hierarchical set of subclasses.
Each subsequent subclass is herein used for representing a lower level
of precision, *e.g.* ``64Bit > 32Bit > 16Bit``.

.. versionadded:: 1.20

.. deprecated:: 2.3
Use ``@typing.overload`` or a ``TypeVar`` with a scalar-type as upper
bound, instead.

Examples
--------
Below is a typical usage example: `NBitBase` is herein used for annotating
Expand Down Expand Up @@ -48,6 +52,7 @@ class NBitBase:
... # note: out: numpy.floating[numpy.typing._64Bit*]

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

def __init_subclass__(cls) -> None:
allowed_names = {
Expand Down
40 changes: 40 additions & 0 deletions numpy/_typing/_nbit_base.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# pyright: reportDeprecated=false
# pyright: reportGeneralTypeIssues=false
# mypy: disable-error-code=misc

from typing import final

from typing_extensions import deprecated

# Deprecated in NumPy 2.3, 2025-05-01
@deprecated(
"`NBitBase` is deprecated and will be removed from numpy.typing in the "
"future. Use `@typing.overload` or a `TypeVar` with a scalar-type as upper "
"bound, instead. (deprecated in NumPy 2.3)",
)
@final
class NBitBase: ...

@final
class _256Bit(NBitBase): ...

@final
class _128Bit(_256Bit): ...

@final
class _96Bit(_128Bit): ...

@final
class _80Bit(_96Bit): ...

@final
class _64Bit(_80Bit): ...

@final
class _32Bit(_64Bit): ...

@final
class _16Bit(_32Bit): ...

@final
class _8Bit(_16Bit): ...
37 changes: 31 additions & 6 deletions numpy/typing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,40 @@
# NOTE: The API section will be appended with additional entries
# further down in this file

from numpy._typing import (
ArrayLike,
DTypeLike,
NBitBase,
NDArray,
)
# pyright: reportDeprecated=false

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

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


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


def __dir__() -> list[str]:
return __DIR

def __getattr__(name: str):
if name == "NBitBase":
import warnings

# Deprecated in NumPy 2.3, 2025-05-01
warnings.warn(
"`NBitBase` is deprecated and will be removed from numpy.typing in the "
"future. Use `@typing.overload` or a `TypeVar` with a scalar-type as upper "
"bound, instead. (deprecated in NumPy 2.3)",
DeprecationWarning,
stacklevel=2,
)
return NBitBase

if name in __DIR_SET:
return globals()[name]

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


if __doc__ is not None:
from numpy._typing._add_docstring import _docstrings
__doc__ += _docstrings
Expand Down
Loading