summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Hoyer <shoyer@google.com>2019-05-25 15:05:59 -0700
committerStephan Hoyer <shoyer@google.com>2019-05-25 15:05:59 -0700
commit766281d1bef8845407855ddf48e3d6b50668e7b7 (patch)
tree1819782e20975fd6abab3f4513d8a4c717ec4cd6
parentcf704e7f245e89c623bd82cbdba7c2dd07cf5fb4 (diff)
downloadnumpy-766281d1bef8845407855ddf48e3d6b50668e7b7.tar.gz
MAINT: revert __skip_array_function__ from NEP-18
xref GH-13624, GH-12028 TODO: update tests/CI for NUMPY_EXPERIMENTAL_ARRAY_FUNCTION=0
-rw-r--r--numpy/core/overrides.py23
-rw-r--r--numpy/core/src/multiarray/arrayfunction_override.c2
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c7
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.h2
-rw-r--r--numpy/core/tests/test_overrides.py28
5 files changed, 33 insertions, 29 deletions
diff --git a/numpy/core/overrides.py b/numpy/core/overrides.py
index ad4d1c721..347e71bd4 100644
--- a/numpy/core/overrides.py
+++ b/numpy/core/overrides.py
@@ -1,6 +1,7 @@
"""Implementation of __array_function__ overrides from NEP-18."""
import collections
import functools
+import os
import textwrap
from numpy.core._multiarray_umath import (
@@ -8,6 +9,10 @@ from numpy.core._multiarray_umath import (
from numpy.compat._inspect import getargspec
+ENABLE_ARRAY_FUNCTION = bool(
+ int(os.environ.get('NUMPY_EXPERIMENTAL_ARRAY_FUNCTION', 1)))
+
+
add_docstring(
implement_array_function,
"""
@@ -137,6 +142,22 @@ def array_function_dispatch(dispatcher, module=None, verify=True,
Function suitable for decorating the implementation of a NumPy function.
"""
+ if not ENABLE_ARRAY_FUNCTION:
+ def decorator(implementation):
+ if docs_from_dispatcher:
+ add_docstring(implementation, dispatcher.__doc__)
+
+ public_api = implementation
+
+ if module is not None:
+ public_api.__module__ = module
+
+ public_api._implementation = implementation
+
+ return public_api
+
+ return decorator
+
def decorator(implementation):
if verify:
verify_matching_signatures(implementation, dispatcher)
@@ -172,7 +193,7 @@ def array_function_dispatch(dispatcher, module=None, verify=True,
if module is not None:
public_api.__module__ = module
- public_api.__skip_array_function__ = implementation
+ public_api._implementation = implementation
return public_api
diff --git a/numpy/core/src/multiarray/arrayfunction_override.c b/numpy/core/src/multiarray/arrayfunction_override.c
index 02078306c..62e597764 100644
--- a/numpy/core/src/multiarray/arrayfunction_override.c
+++ b/numpy/core/src/multiarray/arrayfunction_override.c
@@ -173,7 +173,7 @@ array_function_method_impl(PyObject *func, PyObject *types, PyObject *args,
}
}
- implementation = PyObject_GetAttr(func, npy_ma_str_skip_array_function);
+ implementation = PyObject_GetAttr(func, npy_ma_str_implementation);
if (implementation == NULL) {
return NULL;
}
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index e15ab5172..269b5ee70 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -4498,7 +4498,7 @@ NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_prepare = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_wrap = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_finalize = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_ufunc = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_skip_array_function = NULL;
+NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_implementation = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_order = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_copy = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_dtype = NULL;
@@ -4514,8 +4514,7 @@ intern_strings(void)
npy_ma_str_array_wrap = PyUString_InternFromString("__array_wrap__");
npy_ma_str_array_finalize = PyUString_InternFromString("__array_finalize__");
npy_ma_str_ufunc = PyUString_InternFromString("__array_ufunc__");
- npy_ma_str_skip_array_function = PyUString_InternFromString(
- "__skip_array_function__");
+ npy_ma_str_implementation = PyUString_InternFromString("_implementation");
npy_ma_str_order = PyUString_InternFromString("order");
npy_ma_str_copy = PyUString_InternFromString("copy");
npy_ma_str_dtype = PyUString_InternFromString("dtype");
@@ -4525,7 +4524,7 @@ intern_strings(void)
return npy_ma_str_array && npy_ma_str_array_prepare &&
npy_ma_str_array_wrap && npy_ma_str_array_finalize &&
- npy_ma_str_ufunc && npy_ma_str_skip_array_function &&
+ npy_ma_str_ufunc && npy_ma_str_implementation &&
npy_ma_str_order && npy_ma_str_copy && npy_ma_str_dtype &&
npy_ma_str_ndmin && npy_ma_str_axis1 && npy_ma_str_axis2;
}
diff --git a/numpy/core/src/multiarray/multiarraymodule.h b/numpy/core/src/multiarray/multiarraymodule.h
index 5cf082fbb..dd437e091 100644
--- a/numpy/core/src/multiarray/multiarraymodule.h
+++ b/numpy/core/src/multiarray/multiarraymodule.h
@@ -6,7 +6,7 @@ NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_prepare;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_wrap;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_finalize;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_ufunc;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_skip_array_function;
+NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_implementation;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_order;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_copy;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_dtype;
diff --git a/numpy/core/tests/test_overrides.py b/numpy/core/tests/test_overrides.py
index 7f02399b2..8b87fba13 100644
--- a/numpy/core/tests/test_overrides.py
+++ b/numpy/core/tests/test_overrides.py
@@ -190,17 +190,13 @@ class TestNDArrayArrayFunction(object):
result = np.concatenate((array, override_sub))
assert_equal(result, expected.view(OverrideSub))
- def test_skip_array_function(self):
- assert_(dispatched_one_arg.__skip_array_function__
- is dispatched_one_arg.__wrapped__)
-
def test_no_wrapper(self):
# This shouldn't happen unless a user intentionally calls
# __array_function__ with invalid arguments, but check that we raise
# an appropriate error all the same.
array = np.array(1)
- func = dispatched_one_arg.__skip_array_function__
- with assert_raises_regex(AttributeError, '__skip_array_function__'):
+ func = dispatched_one_arg._implementation
+ with assert_raises_regex(AttributeError, '_implementation'):
array.__array_function__(func=func, types=(np.ndarray,),
args=(array,), kwargs={})
@@ -385,9 +381,6 @@ class TestNumPyFunctions(object):
assert_equal(np.sum(MyArray()), 'yes')
- def test_sum_implementation_on_list(self):
- assert_equal(np.sum.__skip_array_function__([1, 2, 3]), 6)
-
def test_sum_on_mock_array(self):
# We need a proxy for mocks because __array_function__ is only looked
@@ -408,25 +401,16 @@ class TestNumPyFunctions(object):
np.sum, (ArrayProxy,), (proxy,), {})
proxy.value.__array__.assert_not_called()
- proxy = ArrayProxy(mock.Mock(spec=ArrayProxy))
- proxy.value.__array__.return_value = np.array(2)
- result = np.sum.__skip_array_function__(proxy)
- assert_equal(result, 2)
- # TODO: switch to proxy.value.__array__.assert_called() and
- # proxy.value.__array_function__.assert_not_called() once we drop
- # Python 3.5 support.
- ((called_method_name, _, _),) = proxy.value.mock_calls
- assert_equal(called_method_name, '__array__')
-
def test_sum_forwarding_implementation(self):
- class MyArray(object):
+ class MyArray(np.ndarray):
def sum(self, axis, out):
return 'summed'
def __array_function__(self, func, types, args, kwargs):
- return func.__skip_array_function__(*args, **kwargs)
+ return super().__array_function__(func, types, args, kwargs)
# note: the internal implementation of np.sum() calls the .sum() method
- assert_equal(np.sum(MyArray()), 'summed')
+ array = np.array(1).view(MyArray)
+ assert_equal(np.sum(array), 'summed')