From 9117213924c579414ec9176f7b56dc0ac7871ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Sok=C3=B3=C5=82?= Date: Mon, 21 Aug 2023 14:33:24 +0200 Subject: [PATCH 1/2] MAINT: Remove deprecated functions --- numpy/__init__.py | 6 +- numpy/__init__.pyi | 1 - numpy/core/_add_newdocs.py | 3 - numpy/core/fromnumeric.py | 29 +--- numpy/core/numerictypes.py | 150 +----------------- numpy/core/numerictypes.pyi | 1 - numpy/core/tests/test_deprecations.py | 4 - numpy/core/tests/test_numerictypes.py | 25 --- numpy/core/tests/test_regression.py | 6 - numpy/ma/core.py | 6 +- numpy/typing/tests/data/pass/numerictypes.py | 4 - .../typing/tests/data/reveal/numerictypes.pyi | 6 +- 12 files changed, 14 insertions(+), 227 deletions(-) diff --git a/numpy/__init__.py b/numpy/__init__.py index 4c43fd3fbc65..987574c3830c 100644 --- a/numpy/__init__.py +++ b/numpy/__init__.py @@ -136,7 +136,7 @@ cumprod, cumproduct, cumsum, datetime64, datetime_as_string, datetime_data, deg2rad, degrees, diagonal, divide, divmod, dot, double, dtype, e, einsum, einsum_path, empty, empty_like, equal, - errstate, euler_gamma, exp, exp2, expm1, fabs, find_common_type, + errstate, euler_gamma, exp, exp2, expm1, fabs, flatiter, flatnonzero, flexible, float_power, floating, floor, floor_divide, fmax, fmin, fmod, format_float_positional, format_float_scientific, format_parser, @@ -152,13 +152,13 @@ logical_or, logical_xor, logspace, longdouble, longlong, matmul, max, maximum, may_share_memory, mean, min, min_scalar_type, minimum, mod, - modf, moveaxis, multiply, nan, nbytes, ndarray, ndim, nditer, + modf, moveaxis, multiply, nan, ndarray, ndim, nditer, negative, nested_iters, newaxis, nextafter, nonzero, not_equal, number, object_, ones, ones_like, outer, partition, pi, positive, power, printoptions, prod, product, promote_types, ptp, put, putmask, rad2deg, radians, ravel, rec, recarray, reciprocal, record, remainder, repeat, require, reshape, resize, result_type, - right_shift, rint, roll, rollaxis, round, round_, + right_shift, rint, roll, rollaxis, round, searchsorted, set_printoptions, setbufsize, seterr, seterrcall, shape, shares_memory, short, sign, signbit, signedinteger, sin, single, diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 8e101ffa5671..a29cd6522608 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -377,7 +377,6 @@ from numpy.core.numeric import ( from numpy.core.numerictypes import ( issubdtype as issubdtype, - nbytes as nbytes, cast as cast, ScalarType as ScalarType, typecodes as typecodes, diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py index 999e8e7bd811..d4a45352e5ea 100644 --- a/numpy/core/_add_newdocs.py +++ b/numpy/core/_add_newdocs.py @@ -6644,9 +6644,6 @@ def refer_to_array_attribute(attr, method=True): add_newdoc('numpy.core.numerictypes', 'generic', ('itemsize', """The length of one element in bytes.""")) -add_newdoc('numpy.core.numerictypes', 'generic', ('nbytes', - """The length of the scalar in bytes.""")) - add_newdoc('numpy.core.numerictypes', 'generic', ('ndim', """The number of array dimensions.""")) diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 53471cb614c7..a226de84c757 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -23,7 +23,7 @@ 'compress', 'cumprod', 'cumproduct', 'cumsum', 'diagonal', 'mean', 'max', 'min', 'ndim', 'nonzero', 'partition', 'prod', 'product', 'ptp', 'put', - 'ravel', 'repeat', 'reshape', 'resize', 'round', 'round_', + 'ravel', 'repeat', 'reshape', 'resize', 'round', 'searchsorted', 'shape', 'size', 'sometrue', 'sort', 'squeeze', 'std', 'sum', 'swapaxes', 'take', 'trace', 'transpose', 'var', ] @@ -3843,33 +3843,6 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue, *, # avoid using them. -def _round__dispatcher(a, decimals=None, out=None): - # 2023-02-28, 1.25.0 - warnings.warn("`round_` is deprecated as of NumPy 1.25.0, and will be " - "removed in NumPy 2.0. Please use `round` instead.", - DeprecationWarning, stacklevel=3) - return (a, out) - - -@array_function_dispatch(_round__dispatcher) -def round_(a, decimals=0, out=None): - """ - Round an array to the given number of decimals. - - `~numpy.round_` is a disrecommended backwards-compatibility - alias of `~numpy.around` and `~numpy.round`. - - .. deprecated:: 1.25.0 - ``round_`` is deprecated as of NumPy 1.25.0, and will be - removed in NumPy 2.0. Please use `round` instead. - - See Also - -------- - around : equivalent function; see for details. - """ - return around(a, decimals=decimals, out=out) - - def _product_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None, initial=None, where=None): # 2023-03-02, 1.25.0 diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py index fb32f9dc720e..a817e656d57b 100644 --- a/numpy/core/numerictypes.py +++ b/numpy/core/numerictypes.py @@ -86,10 +86,11 @@ from .._utils import set_module # we add more at the bottom -__all__ = ['ScalarType', 'nbytes', 'typecodes', 'find_common_type', - 'issubdtype', 'datetime_data', 'datetime_as_string', - 'busday_offset', 'busday_count', 'is_busday', 'busdaycalendar', - ] +__all__ = [ + 'ScalarType', 'typecodes', 'issubdtype', 'datetime_data', + 'datetime_as_string', 'busday_offset', 'busday_count', + 'is_busday', 'busdaycalendar' +] # we don't need all these imports, but we need to keep them for compatibility # for users using np.core.numerictypes.UPPER_TABLE @@ -443,13 +444,11 @@ class _typedict(dict): def __getitem__(self, obj): return dict.__getitem__(self, obj2sctype(obj)) -nbytes = _typedict() _maxvals = _typedict() _minvals = _typedict() def _construct_lookups(): - for name, info in _concrete_typeinfo.items(): + for info in _concrete_typeinfo.values(): obj = info.type - nbytes[obj] = info.bits // 8 if len(info) > 5: _maxvals[obj] = info.max _minvals[obj] = info.min @@ -545,49 +544,6 @@ def _scalar_type_key(typ): # Formal deprecation: Numpy 1.20.0, 2020-10-19 (see numpy/__init__.py) typeDict = sctypeDict -# b -> boolean -# u -> unsigned integer -# i -> signed integer -# f -> floating point -# c -> complex -# M -> datetime -# m -> timedelta -# S -> string -# U -> Unicode string -# V -> record -# O -> Python object -_kind_list = ['b', 'u', 'i', 'f', 'c', 'S', 'U', 'V', 'O', 'M', 'm'] - -__test_types = '?'+typecodes['AllInteger'][:-2]+typecodes['AllFloat']+'O' -__len_test_types = len(__test_types) - -# Keep incrementing until a common type both can be coerced to -# is found. Otherwise, return None -def _find_common_coerce(a, b): - if a > b: - return a - try: - thisind = __test_types.index(a.char) - except ValueError: - return None - return _can_coerce_all([a, b], start=thisind) - -# Find a data-type that all data-types in a list can be coerced to -def _can_coerce_all(dtypelist, start=0): - N = len(dtypelist) - if N == 0: - return None - if N == 1: - return dtypelist[0] - thisind = start - while thisind < __len_test_types: - newdtype = dtype(__test_types[thisind]) - numcoerce = len([x for x in dtypelist if newdtype >= x]) - if numcoerce == N: - return newdtype - thisind += 1 - return None - def _register_types(): numbers.Integral.register(integer) numbers.Complex.register(inexact) @@ -595,97 +551,3 @@ def _register_types(): numbers.Number.register(number) _register_types() - - -@set_module('numpy') -def find_common_type(array_types, scalar_types): - """ - Determine common type following standard coercion rules. - - .. deprecated:: NumPy 1.25 - - This function is deprecated, use `numpy.promote_types` or - `numpy.result_type` instead. To achieve semantics for the - `scalar_types` argument, use `numpy.result_type` and pass the Python - values `0`, `0.0`, or `0j`. - This will give the same results in almost all cases. - More information and rare exception can be found in the - `NumPy 1.25 release notes `_. - - Parameters - ---------- - array_types : sequence - A list of dtypes or dtype convertible objects representing arrays. - scalar_types : sequence - A list of dtypes or dtype convertible objects representing scalars. - - Returns - ------- - datatype : dtype - The common data type, which is the maximum of `array_types` ignoring - `scalar_types`, unless the maximum of `scalar_types` is of a - different kind (`dtype.kind`). If the kind is not understood, then - None is returned. - - See Also - -------- - dtype, common_type, can_cast, mintypecode - - Examples - -------- - >>> np.find_common_type([], [np.int64, np.float32, complex]) - dtype('complex128') - >>> np.find_common_type([np.int64, np.float32], []) - dtype('float64') - - The standard casting rules ensure that a scalar cannot up-cast an - array unless the scalar is of a fundamentally different kind of data - (i.e. under a different hierarchy in the data type hierarchy) then - the array: - - >>> np.find_common_type([np.float32], [np.int64, np.float64]) - dtype('float32') - - Complex is of a different type, so it up-casts the float in the - `array_types` argument: - - >>> np.find_common_type([np.float32], [complex]) - dtype('complex128') - - Type specifier strings are convertible to dtypes and can therefore - be used instead of dtypes: - - >>> np.find_common_type(['f4', 'f4', 'i4'], ['c8']) - dtype('complex128') - - """ - # Deprecated 2022-11-07, NumPy 1.25 - warnings.warn( - "np.find_common_type is deprecated. Please use `np.result_type` " - "or `np.promote_types`.\n" - "See https://numpy.org/devdocs/release/1.25.0-notes.html and the " - "docs for more information. (Deprecated NumPy 1.25)", - DeprecationWarning, stacklevel=2) - - array_types = [dtype(x) for x in array_types] - scalar_types = [dtype(x) for x in scalar_types] - - maxa = _can_coerce_all(array_types) - maxsc = _can_coerce_all(scalar_types) - - if maxa is None: - return maxsc - - if maxsc is None: - return maxa - - try: - index_a = _kind_list.index(maxa.kind) - index_sc = _kind_list.index(maxsc.kind) - except ValueError: - return None - - if index_sc > index_a: - return _find_common_coerce(maxsc, maxa) - else: - return maxa diff --git a/numpy/core/numerictypes.pyi b/numpy/core/numerictypes.pyi index d05861b2eec6..edd8f52b8a3e 100644 --- a/numpy/core/numerictypes.pyi +++ b/numpy/core/numerictypes.pyi @@ -119,7 +119,6 @@ def issubdtype(arg1: DTypeLike, arg2: DTypeLike) -> bool: ... def sctype2char(sctype: DTypeLike) -> str: ... cast: _typedict[_CastFunc] -nbytes: _typedict[int] typecodes: _TypeCodes ScalarType: tuple[ type[int], diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index b919be97046e..bd525d288765 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -724,10 +724,6 @@ def test_deprecated_none(self): self.assert_deprecated(np.finfo, args=(None,)) class TestFromnumeric(_DeprecationTestCase): - # 2023-02-28, 1.25.0 - def test_round_(self): - self.assert_deprecated(lambda: np.round_(np.array([1.5, 2.5, 3.5]))) - # 2023-03-02, 1.25.0 def test_cumproduct(self): self.assert_deprecated(lambda: np.cumproduct(np.array([1, 2, 3]))) diff --git a/numpy/core/tests/test_numerictypes.py b/numpy/core/tests/test_numerictypes.py index 188fe7e4afb8..2d9307ceeaa6 100644 --- a/numpy/core/tests/test_numerictypes.py +++ b/numpy/core/tests/test_numerictypes.py @@ -338,31 +338,6 @@ def test_assign(self): assert_(a['int'].shape == (5, 0)) assert_(a['float'].shape == (5, 2)) -class TestCommonType: - def test_scalar_loses1(self): - with pytest.warns(DeprecationWarning, match="np.find_common_type"): - res = np.find_common_type(['f4', 'f4', 'i2'], ['f8']) - assert_(res == 'f4') - - def test_scalar_loses2(self): - with pytest.warns(DeprecationWarning, match="np.find_common_type"): - res = np.find_common_type(['f4', 'f4'], ['i8']) - assert_(res == 'f4') - - def test_scalar_wins(self): - with pytest.warns(DeprecationWarning, match="np.find_common_type"): - res = np.find_common_type(['f4', 'f4', 'i2'], ['c8']) - assert_(res == 'c8') - - def test_scalar_wins2(self): - with pytest.warns(DeprecationWarning, match="np.find_common_type"): - res = np.find_common_type(['u4', 'i4', 'i4'], ['f4']) - assert_(res == 'f8') - - def test_scalar_wins3(self): # doesn't go up to 'f16' on purpose - with pytest.warns(DeprecationWarning, match="np.find_common_type"): - res = np.find_common_type(['u8', 'i8', 'i8'], ['f8']) - assert_(res == 'f8') class TestMultipleFields: def setup_method(self): diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 0353ab4fd13c..c62f6f1049ae 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1671,12 +1671,6 @@ def test_nonzero_byteswap(self): a = a.byteswap().newbyteorder() assert_equal(a.nonzero()[0], [1]) # [0] if nonzero() ignores swap - def test_find_common_type_boolean(self): - # Ticket #1695 - with pytest.warns(DeprecationWarning, match="np.find_common_type"): - res = np.find_common_type([], ['?', '?']) - assert res == '?' - def test_empty_mul(self): a = np.array([1.]) a[1:1] *= 2 diff --git a/numpy/ma/core.py b/numpy/ma/core.py index e2db96500810..57728c3220ce 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -1209,7 +1209,7 @@ def __call__(self, a, b, *args, **kwargs): negative = _MaskedUnaryOperation(umath.negative) floor = _MaskedUnaryOperation(umath.floor) ceil = _MaskedUnaryOperation(umath.ceil) -around = _MaskedUnaryOperation(np.round_) +around = _MaskedUnaryOperation(np.around) logical_not = _MaskedUnaryOperation(umath.logical_not) # Domained unary ufuncs @@ -7871,9 +7871,9 @@ def round_(a, decimals=0, out=None): fill_value=1e+20) """ if out is None: - return np.round_(a, decimals, out) + return np.round(a, decimals, out) else: - np.round_(getdata(a), decimals, out) + np.round(getdata(a), decimals, out) if hasattr(out, '_mask'): out._mask = getmask(a) return out diff --git a/numpy/typing/tests/data/pass/numerictypes.py b/numpy/typing/tests/data/pass/numerictypes.py index 95085f86c712..4e2a6437b59d 100644 --- a/numpy/typing/tests/data/pass/numerictypes.py +++ b/numpy/typing/tests/data/pass/numerictypes.py @@ -3,10 +3,6 @@ np.issubdtype("S1", np.bytes_) np.issubdtype(np.float64, np.float32) -np.nbytes[int] -np.nbytes["i8"] -np.nbytes[np.int64] - np.ScalarType np.ScalarType[0] np.ScalarType[3] diff --git a/numpy/typing/tests/data/reveal/numerictypes.pyi b/numpy/typing/tests/data/reveal/numerictypes.pyi index a1b1f6ddc56b..4fb60caedccd 100644 --- a/numpy/typing/tests/data/reveal/numerictypes.pyi +++ b/numpy/typing/tests/data/reveal/numerictypes.pyi @@ -4,11 +4,7 @@ reveal_type(np.cast[int]) # E: _CastFunc reveal_type(np.cast["i8"]) # E: _CastFunc reveal_type(np.cast[np.int64]) # E: _CastFunc -reveal_type(np.nbytes[int]) # E: int -reveal_type(np.nbytes["i8"]) # E: int -reveal_type(np.nbytes[np.int64]) # E: int - -reveal_type(np.ScalarType) # E: tuple +reveal_type(np.ScalarType) # E: Tuple reveal_type(np.ScalarType[0]) # E: Type[builtins.int] reveal_type(np.ScalarType[3]) # E: Type[builtins.bool] reveal_type(np.ScalarType[8]) # E: Type[{csingle}] From 451e80ae41b6e882bb56bd052869119a2099e5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Sok=C3=B3=C5=82?= Date: Thu, 24 Aug 2023 23:29:41 +0200 Subject: [PATCH 2/2] Add changelog and expired attributes --- doc/release/upcoming_changes/24477.python_removal.rst | 7 +++++++ numpy/_expired_attrs_2_0.py | 9 +++++++-- numpy/typing/tests/data/reveal/numerictypes.pyi | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 doc/release/upcoming_changes/24477.python_removal.rst diff --git a/doc/release/upcoming_changes/24477.python_removal.rst b/doc/release/upcoming_changes/24477.python_removal.rst new file mode 100644 index 000000000000..81d3a7b421fc --- /dev/null +++ b/doc/release/upcoming_changes/24477.python_removal.rst @@ -0,0 +1,7 @@ +* ``np.find_common_type`` has been removed. Use ``numpy.promote_types`` or + ``numpy.result_type`` instead. To achieve semantics for the ``scalar_types`` + argument, use ``numpy.result_type`` and pass the Pythonvalues ``0``, ``0.0``, or ``0j``. + +* ``np.round_`` has been removed. Use ``np.round`` instead. + +* ``np.nbytes`` has been removed. Use ``np.dtype().itemsize`` instead. diff --git a/numpy/_expired_attrs_2_0.py b/numpy/_expired_attrs_2_0.py index c7c8e260bea9..eb5156603ffd 100644 --- a/numpy/_expired_attrs_2_0.py +++ b/numpy/_expired_attrs_2_0.py @@ -27,7 +27,6 @@ "It's an internal function and doesn't have a replacement.", "compat": "There's no replacement, as Python 2 is no longer supported.", "safe_eval": "Use `ast.literal_eval` instead.", - "float_": "Use `np.float64` instead.", "complex_": "Use `np.complex128` instead.", "longfloat": "Use `np.longdouble` instead.", @@ -41,7 +40,6 @@ "Infinity": "Use `np.inf` instead.", "NaN": "Use `np.nan` instead.", "infty": "Use `np.inf` instead.", - "issctype": "", "maximum_sctype": "", "obj2sctype": "", @@ -61,4 +59,11 @@ "deprecate": "Raise `DeprecationWarning` instead.", "deprecate_with_doc": "Raise `DeprecationWarning` instead.", "disp": "Use your own printing function instead.", + "find_common_type": + "This function is deprecated, use `numpy.promote_types` or " + "`numpy.result_type` instead. To achieve semantics for the " + "`scalar_types` argument, use `numpy.result_type` and pass the " + "Python values `0`, `0.0`, or `0j`.", + "round_": "Use `np.round` instead.", + "nbytes": "Use `np.dtype().itemsize` instead." } diff --git a/numpy/typing/tests/data/reveal/numerictypes.pyi b/numpy/typing/tests/data/reveal/numerictypes.pyi index 4fb60caedccd..fa1ad5072575 100644 --- a/numpy/typing/tests/data/reveal/numerictypes.pyi +++ b/numpy/typing/tests/data/reveal/numerictypes.pyi @@ -4,7 +4,7 @@ reveal_type(np.cast[int]) # E: _CastFunc reveal_type(np.cast["i8"]) # E: _CastFunc reveal_type(np.cast[np.int64]) # E: _CastFunc -reveal_type(np.ScalarType) # E: Tuple +reveal_type(np.ScalarType) # E: tuple reveal_type(np.ScalarType[0]) # E: Type[builtins.int] reveal_type(np.ScalarType[3]) # E: Type[builtins.bool] reveal_type(np.ScalarType[8]) # E: Type[{csingle}]