From 7a205df72ca94563351442f2f2eeb16a0b8833e8 Mon Sep 17 00:00:00 2001 From: Antareep Sarkar Date: Thu, 12 Feb 2026 03:33:03 +0530 Subject: [PATCH] DEP: deprecate numpy.typename (#30774) --- .../upcoming_changes/30774.deprecation.rst | 4 ++++ numpy/_core/tests/test_deprecations.py | 8 +++++++ numpy/conftest.py | 1 + numpy/lib/_type_check_impl.py | 10 ++++++++ numpy/lib/_type_check_impl.pyi | 23 +++++++++++++++++++ numpy/typing/tests/data/reveal/type_check.pyi | 8 +++---- 6 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 doc/release/upcoming_changes/30774.deprecation.rst diff --git a/doc/release/upcoming_changes/30774.deprecation.rst b/doc/release/upcoming_changes/30774.deprecation.rst new file mode 100644 index 000000000000..00b941ef3a8c --- /dev/null +++ b/doc/release/upcoming_changes/30774.deprecation.rst @@ -0,0 +1,4 @@ +``typename`` is deprecated +-------------------------- +``numpy.typename`` is deprecated because the names returned by it were outdated and inconsistent. +``numpy.dtype.name`` can be used as a replacement. diff --git a/numpy/_core/tests/test_deprecations.py b/numpy/_core/tests/test_deprecations.py index 6c52aea84e5d..8507d369fe29 100644 --- a/numpy/_core/tests/test_deprecations.py +++ b/numpy/_core/tests/test_deprecations.py @@ -347,3 +347,11 @@ class TestTooManyArgsExtremum(_DeprecationTestCase): @pytest.mark.parametrize("ufunc", [np.minimum, np.maximum]) def test_extremem_3_args(self, ufunc): self.assert_deprecated(ufunc, args=(np.ones(1), np.zeros(1), np.empty(1))) + + +class TestTypenameDeprecation(_DeprecationTestCase): + # Deprecation in Numpy 2.5, 2026-02 + + def test_typename_emits_deprecation_warning(self): + self.assert_deprecated(lambda: np.typename("S1")) + self.assert_deprecated(lambda: np.typename("h")) diff --git a/numpy/conftest.py b/numpy/conftest.py index 30625d90c69c..d260225568da 100644 --- a/numpy/conftest.py +++ b/numpy/conftest.py @@ -185,6 +185,7 @@ def warnings_errors_and_rng(test=None): "NumPy warning suppression and assertion utilities are deprecated.", "numpy.fix is deprecated", # fix -> trunc "The chararray class is deprecated", # char.chararray + "numpy.typename is deprecated", # typename -> dtype.name ] msg = "|".join(msgs) diff --git a/numpy/lib/_type_check_impl.py b/numpy/lib/_type_check_impl.py index 37192043513f..e3c942be0d99 100644 --- a/numpy/lib/_type_check_impl.py +++ b/numpy/lib/_type_check_impl.py @@ -2,6 +2,7 @@ """ import functools +import warnings __all__ = ['iscomplexobj', 'isrealobj', 'imag', 'iscomplex', 'isreal', 'nan_to_num', 'real', 'real_if_close', @@ -587,6 +588,9 @@ def typename(char): """ Return a description for the given data type code. + .. deprecated:: 2.5 + `numpy.typename` is deprecated. Use `numpy.dtype.name` instead. + Parameters ---------- char : str @@ -633,6 +637,12 @@ def typename(char): q : long long integer """ + # Deprecated in NumPy 2.5, 2026-02-03 + warnings.warn( + "numpy.typename is deprecated. Use numpy.dtype.name instead.", + DeprecationWarning, + stacklevel=2 + ) return _namefromtype[char] #----------------------------------------------------------------------------- diff --git a/numpy/lib/_type_check_impl.pyi b/numpy/lib/_type_check_impl.pyi index dbef0ca87280..d23123f80c8e 100644 --- a/numpy/lib/_type_check_impl.pyi +++ b/numpy/lib/_type_check_impl.pyi @@ -1,6 +1,7 @@ from _typeshed import Incomplete from collections.abc import Container, Iterable from typing import Any, Literal as L, Protocol, overload, type_check_only +from typing_extensions import deprecated import numpy as np from numpy._typing import ( @@ -148,48 +149,70 @@ def real_if_close(a: ArrayLike, tol: float = 100) -> NDArray[Any]: ... # @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["S1"]) -> L["character"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["?"]) -> L["bool"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["b"]) -> L["signed char"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["B"]) -> L["unsigned char"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["h"]) -> L["short"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["H"]) -> L["unsigned short"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["i"]) -> L["integer"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["I"]) -> L["unsigned integer"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["l"]) -> L["long integer"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["L"]) -> L["unsigned long integer"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["q"]) -> L["long long integer"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["Q"]) -> L["unsigned long long integer"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["f"]) -> L["single precision"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["d"]) -> L["double precision"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["g"]) -> L["long precision"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["F"]) -> L["complex single precision"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["D"]) -> L["complex double precision"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["G"]) -> L["complex long double precision"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["S"]) -> L["string"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["U"]) -> L["unicode"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["V"]) -> L["void"]: ... @overload +@deprecated("numpy.typename is deprecated. Use numpy.dtype.name instead.") def typename(char: L["O"]) -> L["object"]: ... # NOTE: The [overload-overlap] mypy errors are false positives diff --git a/numpy/typing/tests/data/reveal/type_check.pyi b/numpy/typing/tests/data/reveal/type_check.pyi index df95da78ffb7..22eed7493689 100644 --- a/numpy/typing/tests/data/reveal/type_check.pyi +++ b/numpy/typing/tests/data/reveal/type_check.pyi @@ -54,10 +54,10 @@ assert_type(np.real_if_close(AR_c16), npt.NDArray[np.float64 | np.complex128]) assert_type(np.real_if_close(AR_c8), npt.NDArray[np.float32 | np.complex64]) assert_type(np.real_if_close(AR_LIKE_f), npt.NDArray[Any]) -assert_type(np.typename("h"), Literal["short"]) -assert_type(np.typename("B"), Literal["unsigned char"]) -assert_type(np.typename("V"), Literal["void"]) -assert_type(np.typename("S1"), Literal["character"]) +assert_type(np.typename("h"), Literal["short"]) # type: ignore[deprecated] +assert_type(np.typename("B"), Literal["unsigned char"]) # type: ignore[deprecated] +assert_type(np.typename("V"), Literal["void"]) # type: ignore[deprecated] +assert_type(np.typename("S1"), Literal["character"]) # type: ignore[deprecated] assert_type(np.common_type(AR_i4), type[np.float64]) assert_type(np.common_type(AR_f2), type[np.float16])