Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b3ddf2f

Browse filesBrowse files
authored
MAINT: Remove any promotion-state switching logic (#27156)
This is the first level, no following code simplifications, just straight up deletions of any branching. I kept a UserWarning, in case someone had the bad idea to permanently set the environment variable and think they can rely on it. Although would be happy to just delete that as well. * DOC: Add release note for promotion state removal I think we can just do that, but maybe it's prudent to just point it out anyway... * DOC: Mention semi-private removed functions and tweak docs * Adress Marten's last comment
1 parent cfeed27 commit b3ddf2f
Copy full SHA for b3ddf2f

27 files changed

+132
-894
lines changed
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
NEP 50 promotion state option removed
2+
-------------------------------------
3+
The NEP 50 promotion state settings are now removed. They were always
4+
meant as temporary means for testing.
5+
A warning will be given if the environment variable is set to anything
6+
but ``NPY_PROMOTION_STATE=weak`` wile ``_set_promotion_state``
7+
and ``_get_promotion_state`` are removed.
8+
In case code used ``_no_nep50_warning``, a ``contextlib.nullcontext``
9+
could be used to replace it when not available.

‎doc/source/reference/c-api/array.rst

Copy file name to clipboardExpand all lines: doc/source/reference/c-api/array.rst
+12-26Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,14 +1089,13 @@ Converting data types
10891089
returned when the value will not overflow or be truncated to
10901090
an integer when converting to a smaller type.
10911091
1092-
This is almost the same as the result of
1093-
PyArray_CanCastTypeTo(PyArray_MinScalarType(arr), totype, casting),
1094-
but it also handles a special case arising because the set
1095-
of uint values is not a subset of the int values for types with the
1096-
same number of bits.
1097-
10981092
.. c:function:: PyArray_Descr* PyArray_MinScalarType(PyArrayObject* arr)
10991093
1094+
.. note::
1095+
With the adoption of NEP 50 in NumPy 2, this function is not used
1096+
internally. It is currently provided for backwards compatibility,
1097+
but expected to be eventually deprecated.
1098+
11001099
.. versionadded:: 1.6
11011100
11021101
If *arr* is an array, returns its data type descriptor, but if
@@ -1134,8 +1133,7 @@ Converting data types
11341133
11351134
.. c:function:: int PyArray_ObjectType(PyObject* op, int mintype)
11361135
1137-
This function is superseded by :c:func:`PyArray_MinScalarType` and/or
1138-
:c:func:`PyArray_ResultType`.
1136+
This function is superseded by :c:func:`PyArray_ResultType`.
11391137
11401138
This function is useful for determining a common type that two or
11411139
more arrays can be converted to. It only works for non-flexible
@@ -3250,30 +3248,18 @@ Array scalars
32503248
.. c:function:: NPY_SCALARKIND PyArray_ScalarKind( \
32513249
int typenum, PyArrayObject** arr)
32523250
3253-
See the function :c:func:`PyArray_MinScalarType` for an alternative
3254-
mechanism introduced in NumPy 1.6.0.
3251+
Legacy way to query special promotion for scalar values. This is not
3252+
used in NumPy itself anymore and is expected to be deprecated eventually.
32553253
3256-
Return the kind of scalar represented by *typenum* and the array
3257-
in *\*arr* (if *arr* is not ``NULL`` ). The array is assumed to be
3258-
rank-0 and only used if *typenum* represents a signed integer. If
3259-
*arr* is not ``NULL`` and the first element is negative then
3260-
:c:data:`NPY_INTNEG_SCALAR` is returned, otherwise
3261-
:c:data:`NPY_INTPOS_SCALAR` is returned. The possible return values
3262-
are the enumerated values in :c:type:`NPY_SCALARKIND`.
3254+
New DTypes can define promotion rules specific to Python scalars.
32633255
32643256
.. c:function:: int PyArray_CanCoerceScalar( \
32653257
char thistype, char neededtype, NPY_SCALARKIND scalar)
32663258
3267-
See the function :c:func:`PyArray_ResultType` for details of
3268-
NumPy type promotion, updated in NumPy 1.6.0.
3259+
Legacy way to query special promotion for scalar values. This is not
3260+
used in NumPy itself anymore and is expected to be deprecated eventually.
32693261
3270-
Implements the rules for scalar coercion. Scalars are only
3271-
silently coerced from thistype to neededtype if this function
3272-
returns nonzero. If scalar is :c:data:`NPY_NOSCALAR`, then this
3273-
function is equivalent to :c:func:`PyArray_CanCastSafely`. The rule is
3274-
that scalars of the same KIND can be coerced into arrays of the
3275-
same KIND. This rule means that high-precision scalars will never
3276-
cause low-precision arrays of the same KIND to be upcast.
3262+
Use ``PyArray_ResultType`` for similar purposes.
32773263
32783264
32793265
Data-type descriptors

‎numpy/__init__.py

Copy file name to clipboardExpand all lines: numpy/__init__.py
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@
120120

121121
from . import _core
122122
from ._core import (
123-
False_, ScalarType, True_, _get_promotion_state, _no_nep50_warning,
124-
_set_promotion_state, abs, absolute, acos, acosh, add, all, allclose,
123+
False_, ScalarType, True_,
124+
abs, absolute, acos, acosh, add, all, allclose,
125125
amax, amin, any, arange, arccos, arccosh, arcsin, arcsinh,
126126
arctan, arctan2, arctanh, argmax, argmin, argpartition, argsort,
127127
argwhere, around, array, array2string, array_equal, array_equiv,
@@ -531,8 +531,11 @@ def hugepage_setup():
531531
_core.multiarray._multiarray_umath._reload_guard()
532532

533533
# TODO: Remove the environment variable entirely now that it is "weak"
534-
_core._set_promotion_state(
535-
os.environ.get("NPY_PROMOTION_STATE", "weak"))
534+
if (os.environ.get("NPY_PROMOTION_STATE", "weak") != "weak"):
535+
warnings.warn(
536+
"NPY_PROMOTION_STATE was a temporary feature for NumPy 2.0 "
537+
"transition and is ignored after NumPy 2.2.",
538+
UserWarning, stacklevel=2)
536539

537540
# Tell PyInstaller where to find hook-numpy.py
538541
def _pyinstaller_hooks_dir():

‎numpy/__init__.pyi

Copy file name to clipboardExpand all lines: numpy/__init__.pyi
-5Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3891,11 +3891,6 @@ class errstate:
38913891
) -> None: ...
38923892
def __call__(self, func: _CallType) -> _CallType: ...
38933893

3894-
@contextmanager
3895-
def _no_nep50_warning() -> Generator[None, None, None]: ...
3896-
def _get_promotion_state() -> str: ...
3897-
def _set_promotion_state(state: str, /) -> None: ...
3898-
38993894
_ScalarType_co = TypeVar("_ScalarType_co", bound=generic, covariant=True)
39003895

39013896
class ndenumerate(Generic[_ScalarType_co]):

‎numpy/_core/_methods.py

Copy file name to clipboardExpand all lines: numpy/_core/_methods.py
+6-10Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from numpy._core.multiarray import asanyarray
1515
from numpy._core import numerictypes as nt
1616
from numpy._core import _exceptions
17-
from numpy._core._ufunc_config import _no_nep50_warning
1817
from numpy._globals import _NoValue
1918

2019
# save those O(100) nanoseconds!
@@ -135,9 +134,8 @@ def _mean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
135134

136135
ret = umr_sum(arr, axis, dtype, out, keepdims, where=where)
137136
if isinstance(ret, mu.ndarray):
138-
with _no_nep50_warning():
139-
ret = um.true_divide(
140-
ret, rcount, out=ret, casting='unsafe', subok=False)
137+
ret = um.true_divide(
138+
ret, rcount, out=ret, casting='unsafe', subok=False)
141139
if is_float16_result and out is None:
142140
ret = arr.dtype.type(ret)
143141
elif hasattr(ret, 'dtype'):
@@ -180,9 +178,8 @@ def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
180178
# matching rcount to arrmean when where is specified as array
181179
div = rcount.reshape(arrmean.shape)
182180
if isinstance(arrmean, mu.ndarray):
183-
with _no_nep50_warning():
184-
arrmean = um.true_divide(arrmean, div, out=arrmean,
185-
casting='unsafe', subok=False)
181+
arrmean = um.true_divide(arrmean, div, out=arrmean,
182+
casting='unsafe', subok=False)
186183
elif hasattr(arrmean, "dtype"):
187184
arrmean = arrmean.dtype.type(arrmean / rcount)
188185
else:
@@ -212,9 +209,8 @@ def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
212209

213210
# divide by degrees of freedom
214211
if isinstance(ret, mu.ndarray):
215-
with _no_nep50_warning():
216-
ret = um.true_divide(
217-
ret, rcount, out=ret, casting='unsafe', subok=False)
212+
ret = um.true_divide(
213+
ret, rcount, out=ret, casting='unsafe', subok=False)
218214
elif hasattr(ret, 'dtype'):
219215
ret = ret.dtype.type(ret / rcount)
220216
else:

‎numpy/_core/_ufunc_config.py

Copy file name to clipboardExpand all lines: numpy/_core/_ufunc_config.py
+1-20Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
__all__ = [
1515
"seterr", "geterr", "setbufsize", "getbufsize", "seterrcall", "geterrcall",
16-
"errstate", '_no_nep50_warning'
16+
"errstate"
1717
]
1818

1919

@@ -481,22 +481,3 @@ def inner(*args, **kwargs):
481481
_extobj_contextvar.reset(_token)
482482

483483
return inner
484-
485-
486-
NO_NEP50_WARNING = contextvars.ContextVar("_no_nep50_warning", default=False)
487-
488-
@set_module('numpy')
489-
@contextlib.contextmanager
490-
def _no_nep50_warning():
491-
"""
492-
Context manager to disable NEP 50 warnings. This context manager is
493-
only relevant if the NEP 50 warnings are enabled globally (which is not
494-
thread/context safe).
495-
496-
This warning context manager itself is fully safe, however.
497-
"""
498-
token = NO_NEP50_WARNING.set(True)
499-
try:
500-
yield
501-
finally:
502-
NO_NEP50_WARNING.reset(token)

‎numpy/_core/multiarray.py

Copy file name to clipboardExpand all lines: numpy/_core/multiarray.py
+1-5Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
_flagdict, from_dlpack, _place, _reconstruct,
1818
_vec_string, _ARRAY_API, _monotonicity, _get_ndarray_c_version,
1919
_get_madvise_hugepage, _set_madvise_hugepage,
20-
_get_promotion_state, _set_promotion_state
2120
)
2221

2322
__all__ = [
@@ -40,8 +39,7 @@
4039
'normalize_axis_index', 'packbits', 'promote_types', 'putmask',
4140
'ravel_multi_index', 'result_type', 'scalar', 'set_datetimeparse_function',
4241
'set_typeDict', 'shares_memory', 'typeinfo',
43-
'unpackbits', 'unravel_index', 'vdot', 'where', 'zeros',
44-
'_get_promotion_state', '_set_promotion_state']
42+
'unpackbits', 'unravel_index', 'vdot', 'where', 'zeros']
4543

4644
# For backward compatibility, make sure pickle imports
4745
# these functions from here
@@ -67,8 +65,6 @@
6765
nested_iters.__module__ = 'numpy'
6866
promote_types.__module__ = 'numpy'
6967
zeros.__module__ = 'numpy'
70-
_get_promotion_state.__module__ = 'numpy'
71-
_set_promotion_state.__module__ = 'numpy'
7268
normalize_axis_index.__module__ = 'numpy.lib.array_utils'
7369

7470

‎numpy/_core/numeric.py

Copy file name to clipboardExpand all lines: numpy/_core/numeric.py
+4-5Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
empty, empty_like, flatiter, frombuffer, from_dlpack, fromfile, fromiter,
1818
fromstring, inner, lexsort, matmul, may_share_memory, min_scalar_type,
1919
ndarray, nditer, nested_iters, promote_types, putmask, result_type,
20-
shares_memory, vdot, where, zeros, normalize_axis_index,
21-
_get_promotion_state, _set_promotion_state, vecdot
20+
shares_memory, vdot, where, zeros, normalize_axis_index, vecdot
2221
)
2322

2423
from . import overrides
@@ -28,7 +27,7 @@
2827
from .umath import (multiply, invert, sin, PINF, NAN)
2928
from . import numerictypes
3029
from ..exceptions import AxisError
31-
from ._ufunc_config import errstate, _no_nep50_warning
30+
from ._ufunc_config import errstate
3231

3332
bitwise_not = invert
3433
ufunc = type(sin)
@@ -53,7 +52,7 @@
5352
'identity', 'allclose', 'putmask',
5453
'flatnonzero', 'inf', 'nan', 'False_', 'True_', 'bitwise_not',
5554
'full', 'full_like', 'matmul', 'vecdot', 'shares_memory',
56-
'may_share_memory', '_get_promotion_state', '_set_promotion_state']
55+
'may_share_memory']
5756

5857

5958
def _zeros_like_dispatcher(
@@ -2457,7 +2456,7 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
24572456
elif isinstance(y, int):
24582457
y = float(y)
24592458

2460-
with errstate(invalid='ignore'), _no_nep50_warning():
2459+
with errstate(invalid='ignore'):
24612460
result = (less_equal(abs(x-y), atol + rtol * abs(y))
24622461
& isfinite(y)
24632462
| (x == y))

‎numpy/_core/src/multiarray/arraytypes.c.src

Copy file name to clipboardExpand all lines: numpy/_core/src/multiarray/arraytypes.c.src
+4-35Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -275,41 +275,10 @@ static int
275275
#endif
276276
) {
277277
PyArray_Descr *descr = PyArray_DescrFromType(NPY_@TYPE@);
278-
int promotion_state = get_npy_promotion_state();
279-
if (promotion_state == NPY_USE_LEGACY_PROMOTION || (
280-
promotion_state == NPY_USE_WEAK_PROMOTION_AND_WARN
281-
&& !npy_give_promotion_warnings())) {
282-
/*
283-
* This path will be taken both for the "promotion" case such as
284-
* `uint8_arr + 123` as well as the assignment case.
285-
* The "legacy" path should only ever be taken for assignment
286-
* (legacy promotion will prevent overflows by promoting up)
287-
* so a normal deprecation makes sense.
288-
* When weak promotion is active, we use "future" behavior unless
289-
* warnings were explicitly opt-in.
290-
*/
291-
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
292-
"NumPy will stop allowing conversion of out-of-bound "
293-
"Python integers to integer arrays. The conversion "
294-
"of %.100R to %S will fail in the future.\n"
295-
"For the old behavior, usually:\n"
296-
" np.array(value).astype(dtype)\n"
297-
"will give the desired result (the cast overflows).",
298-
obj, descr) < 0) {
299-
Py_DECREF(descr);
300-
return -1;
301-
}
302-
Py_DECREF(descr);
303-
return 0;
304-
}
305-
else {
306-
/* Live in the future, outright error: */
307-
PyErr_Format(PyExc_OverflowError,
308-
"Python integer %R out of bounds for %S", obj, descr);
309-
Py_DECREF(descr);
310-
return -1;
311-
}
312-
assert(0);
278+
PyErr_Format(PyExc_OverflowError,
279+
"Python integer %R out of bounds for %S", obj, descr);
280+
Py_DECREF(descr);
281+
return -1;
313282
}
314283
return 0;
315284
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.