diff options
author | Ralf Gommers <ralf.gommers@gmail.com> | 2023-03-12 22:01:22 +0000 |
---|---|---|
committer | Ralf Gommers <ralf.gommers@gmail.com> | 2023-03-12 22:31:28 +0000 |
commit | 1da1663196c95b3811ca84d9e335f32cfeb05e32 (patch) | |
tree | e6d432a66dd5c16051a4e1a400567b100200639a | |
parent | ac6233b03df6562453ebda984f565f603e726710 (diff) | |
download | numpy-1da1663196c95b3811ca84d9e335f32cfeb05e32.tar.gz |
MAINT: remove `NUMPY_EXPERIMENTAL_ARRAY_FUNCTION` env var
As discussed in
https://mail.python.org/archives/list/numpy-discussion@python.org/thread/UKZJACAP5FUG7KP2AQDPE4P5ADNWLOHZ/
This flag was always meant to be temporary, and cleaning it up is
long overdue.
-rw-r--r-- | .github/workflows/build_test.yml | 6 | ||||
-rw-r--r-- | doc/source/reference/arrays.classes.rst | 9 | ||||
-rw-r--r-- | doc/source/reference/global_state.rst | 13 | ||||
-rw-r--r-- | numpy/core/fromnumeric.py | 20 | ||||
-rw-r--r-- | numpy/core/overrides.py | 14 | ||||
-rw-r--r-- | numpy/core/shape_base.py | 11 | ||||
-rw-r--r-- | numpy/core/tests/test_overrides.py | 19 | ||||
-rw-r--r-- | numpy/lib/function_base.py | 33 | ||||
-rw-r--r-- | numpy/lib/shape_base.py | 8 | ||||
-rw-r--r-- | numpy/lib/tests/test_twodim_base.py | 11 | ||||
-rw-r--r-- | numpy/testing/tests/test_utils.py | 3 |
11 files changed, 22 insertions, 125 deletions
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index ff74cdf61..57a22b124 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -272,13 +272,11 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - uses: ./.github/actions - numpy2_flag_and_no_array_func: + numpy2_flag: needs: [smoke_test] runs-on: ubuntu-latest env: - NUMPY_EXPERIMENTAL_ARRAY_FUNCTION: 0 - # Array func and numpy-2 should be involved, so use this - # to have a test for feature flagged behavior. + # Test for numpy-2.0 feature-flagged behavior. NPY_NUMPY_2_BEHAVIOR: 1 # Using the future "weak" state doesn't pass tests # currently unfortunately diff --git a/doc/source/reference/arrays.classes.rst b/doc/source/reference/arrays.classes.rst index 2f40423ee..2cce595e0 100644 --- a/doc/source/reference/arrays.classes.rst +++ b/doc/source/reference/arrays.classes.rst @@ -162,15 +162,6 @@ NumPy provides several hooks that classes can customize: .. versionadded:: 1.16 - .. note:: - - - In NumPy 1.17, the protocol is enabled by default, but can be disabled - with ``NUMPY_EXPERIMENTAL_ARRAY_FUNCTION=0``. - - In NumPy 1.16, you need to set the environment variable - ``NUMPY_EXPERIMENTAL_ARRAY_FUNCTION=1`` before importing NumPy to use - NumPy function overrides. - - Eventually, expect to ``__array_function__`` to always be enabled. - - ``func`` is an arbitrary callable exposed by NumPy's public API, which was called in the form ``func(*args, **kwargs)``. - ``types`` is a collection :py:class:`collections.abc.Collection` diff --git a/doc/source/reference/global_state.rst b/doc/source/reference/global_state.rst index a110ce7c1..d73da4244 100644 --- a/doc/source/reference/global_state.rst +++ b/doc/source/reference/global_state.rst @@ -55,19 +55,6 @@ SIMD feature selection Setting ``NPY_DISABLE_CPU_FEATURES`` will exclude simd features at runtime. See :ref:`runtime-simd-dispatch`. -Interoperability-Related Options -================================ - -The array function protocol which allows array-like objects to -hook into the NumPy API is currently enabled by default. -This option exists since NumPy 1.16 and is enabled by default since -NumPy 1.17. It can be disabled using:: - - NUMPY_EXPERIMENTAL_ARRAY_FUNCTION=0 - -See also :py:meth:`numpy.class.__array_function__` for more information. -This flag is checked at import time. - Debugging-Related Options ========================= diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 196ba5ea7..b36667427 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -3830,10 +3830,6 @@ def round_(a, decimals=0, out=None): -------- around : equivalent function; see for details. """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # call dispatch helper explicitly, as it emits a deprecation warning - _round__dispatcher(a, decimals=decimals, out=out) - return around(a, decimals=decimals, out=out) @@ -3859,10 +3855,6 @@ def product(*args, **kwargs): -------- prod : equivalent function; see for details. """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # call dispatch helper explicitly, as it emits a deprecation warning - _product_dispatcher(*args, **kwargs) - return prod(*args, **kwargs) @@ -3887,10 +3879,6 @@ def cumproduct(*args, **kwargs): -------- cumprod : equivalent function; see for details. """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # call dispatch helper explicitly, as it emits a deprecation warning - _cumproduct_dispatcher(*args, **kwargs) - return cumprod(*args, **kwargs) @@ -3918,10 +3906,6 @@ def sometrue(*args, **kwargs): -------- any : equivalent function; see for details. """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # call dispatch helper explicitly, as it emits a deprecation warning - _sometrue_dispatcher(*args, **kwargs) - return any(*args, **kwargs) @@ -3946,8 +3930,4 @@ def alltrue(*args, **kwargs): -------- numpy.all : Equivalent function; see for details. """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # call dispatch helper explicitly, as it emits a deprecation warning - _alltrue_dispatcher(*args, **kwargs) - return all(*args, **kwargs) diff --git a/numpy/core/overrides.py b/numpy/core/overrides.py index e93ef5d88..6403e65b0 100644 --- a/numpy/core/overrides.py +++ b/numpy/core/overrides.py @@ -11,9 +11,6 @@ from numpy.core._multiarray_umath import ( ARRAY_FUNCTIONS = set() -ARRAY_FUNCTION_ENABLED = bool( - int(os.environ.get('NUMPY_EXPERIMENTAL_ARRAY_FUNCTION', 1))) - array_function_like_doc = ( """like : array_like, optional Reference object to allow the creation of arrays which are not @@ -140,17 +137,8 @@ def array_function_dispatch(dispatcher=None, module=None, verify=True, Returns ------- Function suitable for decorating the implementation of a NumPy function. - """ - - if not ARRAY_FUNCTION_ENABLED: - def decorator(implementation): - if docs_from_dispatcher: - add_docstring(implementation, dispatcher.__doc__) - if module is not None: - implementation.__module__ = module - return implementation - return decorator + """ def decorator(implementation): if verify: if dispatcher is not None: diff --git a/numpy/core/shape_base.py b/numpy/core/shape_base.py index 56c5a70f2..250fffd42 100644 --- a/numpy/core/shape_base.py +++ b/numpy/core/shape_base.py @@ -283,9 +283,6 @@ def vstack(tup, *, dtype=None, casting="same_kind"): [6]]) """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # reject non-sequences (and make tuple) - tup = _arrays_for_stack_dispatcher(tup) arrs = atleast_2d(*tup) if not isinstance(arrs, list): arrs = [arrs] @@ -352,10 +349,6 @@ def hstack(tup, *, dtype=None, casting="same_kind"): [3, 6]]) """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # reject non-sequences (and make tuple) - tup = _arrays_for_stack_dispatcher(tup) - arrs = atleast_1d(*tup) if not isinstance(arrs, list): arrs = [arrs] @@ -447,10 +440,6 @@ def stack(arrays, axis=0, out=None, *, dtype=None, casting="same_kind"): [3, 6]]) """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # reject non-sequences (and make tuple) - arrays = _arrays_for_stack_dispatcher(arrays) - arrays = [asanyarray(arr) for arr in arrays] if not arrays: raise ValueError('need at least one array to stack') diff --git a/numpy/core/tests/test_overrides.py b/numpy/core/tests/test_overrides.py index 90d917701..ae4cddb0e 100644 --- a/numpy/core/tests/test_overrides.py +++ b/numpy/core/tests/test_overrides.py @@ -10,16 +10,11 @@ from numpy.testing import ( assert_, assert_equal, assert_raises, assert_raises_regex) from numpy.core.overrides import ( _get_implementing_args, array_function_dispatch, - verify_matching_signatures, ARRAY_FUNCTION_ENABLED) + verify_matching_signatures) from numpy.compat import pickle import pytest -requires_array_function = pytest.mark.skipif( - not ARRAY_FUNCTION_ENABLED, - reason="__array_function__ dispatch not enabled.") - - def _return_not_implemented(self, *args, **kwargs): return NotImplemented @@ -150,7 +145,6 @@ class TestGetImplementingArgs: class TestNDArrayArrayFunction: - @requires_array_function def test_method(self): class Other: @@ -209,7 +203,6 @@ class TestNDArrayArrayFunction: args=(array,), kwargs={}) -@requires_array_function class TestArrayFunctionDispatch: def test_pickle(self): @@ -249,7 +242,6 @@ class TestArrayFunctionDispatch: dispatched_one_arg(array) -@requires_array_function class TestVerifyMatchingSignatures: def test_verify_matching_signatures(self): @@ -302,7 +294,6 @@ def _new_duck_type_and_implements(): return (MyArray, implements) -@requires_array_function class TestArrayFunctionImplementation: def test_one_arg(self): @@ -472,7 +463,6 @@ class TestNumPyFunctions: signature = inspect.signature(np.sum) assert_('axis' in signature.parameters) - @requires_array_function def test_override_sum(self): MyArray, implements = _new_duck_type_and_implements() @@ -482,7 +472,6 @@ class TestNumPyFunctions: assert_equal(np.sum(MyArray()), 'yes') - @requires_array_function def test_sum_on_mock_array(self): # We need a proxy for mocks because __array_function__ is only looked @@ -503,7 +492,6 @@ class TestNumPyFunctions: np.sum, (ArrayProxy,), (proxy,), {}) proxy.value.__array__.assert_not_called() - @requires_array_function def test_sum_forwarding_implementation(self): class MyArray(np.ndarray): @@ -555,7 +543,6 @@ class TestArrayLike: def func_args(*args, **kwargs): return args, kwargs - @requires_array_function def test_array_like_not_implemented(self): self.add_method('array', self.MyArray) @@ -588,7 +575,6 @@ class TestArrayLike: @pytest.mark.parametrize('function, args, kwargs', _array_tests) @pytest.mark.parametrize('numpy_ref', [True, False]) - @requires_array_function def test_array_like(self, function, args, kwargs, numpy_ref): self.add_method('array', self.MyArray) self.add_method(function, self.MyArray) @@ -621,7 +607,6 @@ class TestArrayLike: @pytest.mark.parametrize('function, args, kwargs', _array_tests) @pytest.mark.parametrize('ref', [1, [1], "MyNoArrayFunctionArray"]) - @requires_array_function def test_no_array_function_like(self, function, args, kwargs, ref): self.add_method('array', self.MyNoArrayFunctionArray) self.add_method(function, self.MyNoArrayFunctionArray) @@ -663,7 +648,6 @@ class TestArrayLike: assert type(array_like) is self.MyArray assert array_like.function is self.MyArray.fromfile - @requires_array_function def test_exception_handling(self): self.add_method('array', self.MyArray, enable_value_error=True) @@ -692,7 +676,6 @@ class TestArrayLike: assert_equal(array_like, expected) -@requires_array_function def test_function_like(): # We provide a `__get__` implementation, make sure it works assert type(np.mean) is np.core._multiarray_umath._ArrayFunctionDispatcher diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index 405790025..f0f374f97 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -4910,23 +4910,22 @@ def trapz(y, x=None, dx=1.0, axis=-1): return ret -if overrides.ARRAY_FUNCTION_ENABLED: - # If array-function is enabled (normal), we wrap everything into a C - # callable, which has no __code__ or other attributes normal Python funcs - # have. SciPy however, tries to "clone" `trapz` into a new Python function - # which requires `__code__` and a few other attributes. - # So we create a dummy clone and copy over its attributes allowing - # SciPy <= 1.10 to work: https://github.com/scipy/scipy/issues/17811 - assert not hasattr(trapz, "__code__") - - def _fake_trapz(y, x=None, dx=1.0, axis=-1): - return trapz(y, x=x, dx=dx, axis=axis) - - trapz.__code__ = _fake_trapz.__code__ - trapz.__globals__ = _fake_trapz.__globals__ - trapz.__defaults__ = _fake_trapz.__defaults__ - trapz.__closure__ = _fake_trapz.__closure__ - trapz.__kwdefaults__ = _fake_trapz.__kwdefaults__ +# __array_function__ has no __code__ or other attributes normal Python funcs we +# wrap everything into a C callable. SciPy however, tries to "clone" `trapz` +# into a new Python function which requires `__code__` and a few other +# attributes. So we create a dummy clone and copy over its attributes allowing +# SciPy <= 1.10 to work: https://github.com/scipy/scipy/issues/17811 +assert not hasattr(trapz, "__code__") + +def _fake_trapz(y, x=None, dx=1.0, axis=-1): + return trapz(y, x=x, dx=dx, axis=axis) + + +trapz.__code__ = _fake_trapz.__code__ +trapz.__globals__ = _fake_trapz.__globals__ +trapz.__defaults__ = _fake_trapz.__defaults__ +trapz.__closure__ = _fake_trapz.__closure__ +trapz.__kwdefaults__ = _fake_trapz.__kwdefaults__ def _meshgrid_dispatcher(*xi, copy=None, sparse=None, indexing=None): diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py index 154faa1dd..5d8a41bfe 100644 --- a/numpy/lib/shape_base.py +++ b/numpy/lib/shape_base.py @@ -643,10 +643,6 @@ def column_stack(tup): [3, 4]]) """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # reject non-sequences (and make tuple) - tup = _arrays_for_stack_dispatcher(tup) - arrays = [] for v in tup: arr = asanyarray(v) @@ -713,10 +709,6 @@ def dstack(tup): [[3, 4]]]) """ - if not overrides.ARRAY_FUNCTION_ENABLED: - # reject non-sequences (and make tuple) - tup = _arrays_for_stack_dispatcher(tup) - arrs = atleast_3d(*tup) if not isinstance(arrs, list): arrs = [arrs] diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py index 141f508fd..eb008c600 100644 --- a/numpy/lib/tests/test_twodim_base.py +++ b/numpy/lib/tests/test_twodim_base.py @@ -4,20 +4,14 @@ from numpy.testing import ( assert_equal, assert_array_equal, assert_array_max_ulp, assert_array_almost_equal, assert_raises, assert_ - ) - +) from numpy import ( arange, add, fliplr, flipud, zeros, ones, eye, array, diag, histogram2d, tri, mask_indices, triu_indices, triu_indices_from, tril_indices, tril_indices_from, vander, - ) - +) import numpy as np - -from numpy.core.tests.test_overrides import requires_array_function - - import pytest @@ -283,7 +277,6 @@ class TestHistogram2d: assert_array_equal(H, answer) assert_array_equal(xe, array([0., 0.25, 0.5, 0.75, 1])) - @requires_array_function def test_dispatch(self): class ShouldDispatch: def __array_function__(self, function, types, args, kwargs): diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py index 8f4912fab..0aaa508ee 100644 --- a/numpy/testing/tests/test_utils.py +++ b/numpy/testing/tests/test_utils.py @@ -14,7 +14,6 @@ from numpy.testing import ( clear_and_catch_warnings, suppress_warnings, assert_string_equal, assert_, tempdir, temppath, assert_no_gc_cycles, HAS_REFCOUNT ) -from numpy.core.overrides import ARRAY_FUNCTION_ENABLED class _GenericTest: @@ -191,8 +190,6 @@ class TestArrayEqual(_GenericTest): self._test_not_equal(a, b) self._test_not_equal(b, a) - @pytest.mark.skipif( - not ARRAY_FUNCTION_ENABLED, reason='requires __array_function__') def test_subclass_that_does_not_implement_npall(self): class MyArray(np.ndarray): def __array_function__(self, *args, **kwargs): |