summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2018-11-09 20:07:16 -0600
committerGitHub <noreply@github.com>2018-11-09 20:07:16 -0600
commitd0e2f1ac0c0fb4aaf791c9082cff1d6b04545410 (patch)
treef8df1a80711770626f8953b218aefa6b773e1d43 /numpy/core
parentd50484a0c936a6ad3fdc9a0ee08b03e1f4cdc2db (diff)
parent08a2e4503de155f2e202bc154287b34220ad1025 (diff)
downloadnumpy-d0e2f1ac0c0fb4aaf791c9082cff1d6b04545410.tar.gz
Merge pull request #11916 from mattip/deprecate-set_numeric_ops
DEP: deprecate np.set_numeric_ops and friends
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/_add_newdocs.py24
-rw-r--r--numpy/core/code_generators/cversions.txt6
-rw-r--r--numpy/core/setup.py1
-rw-r--r--numpy/core/src/multiarray/_multiarray_tests.c.src13
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c6
-rw-r--r--numpy/core/src/multiarray/number.c39
-rw-r--r--numpy/core/src/multiarray/number.h4
-rw-r--r--numpy/core/src/multiarray/temp_elide.c2
-rw-r--r--numpy/core/src/umath/umathmodule.c3
-rw-r--r--numpy/core/tests/test_deprecations.py11
10 files changed, 83 insertions, 26 deletions
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index ea472f1b3..f67964d84 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -1320,6 +1320,12 @@ add_newdoc('numpy.core.multiarray', 'set_numeric_ops',
Set numerical operators for array objects.
+ .. deprecated:: 1.16
+
+ For the general case, use :c:func:`PyUFunc_ReplaceLoopBySignature`.
+ For ndarray subclasses, define the ``__array_ufunc__`` method and
+ override the relevant ufunc.
+
Parameters
----------
op1, op2, ... : callable
@@ -1597,7 +1603,7 @@ add_newdoc('numpy.core.multiarray', 'c_einsum',
"""
c_einsum(subscripts, *operands, out=None, dtype=None, order='K',
casting='safe')
-
+
*This documentation shadows that of the native python implementation of the `einsum` function,
except all references and examples related to the `optimize` argument (v 0.12.0) have been removed.*
@@ -2113,7 +2119,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('ctypes',
-----
Below are the public attributes of this object which were documented
in "Guide to NumPy" (we have omitted undocumented public attributes,
- as well as documented private attributes):
+ as well as documented private attributes):
.. autoattribute:: numpy.core._internal._ctypes.data
@@ -2455,7 +2461,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('size',
Notes
-----
- `a.size` returns a standard arbitrary precision Python integer. This
+ `a.size` returns a standard arbitrary precision Python integer. This
may not be the case with other methods of obtaining the same value
(like the suggested ``np.prod(a.shape)``, which returns an instance
of ``np.int_``), and may be relevant if the value is used further in
@@ -4090,7 +4096,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('tofile',
machines with different endianness. Some of these problems can be overcome
by outputting the data as text files, at the expense of speed and file
size.
-
+
When fid is a file object, array contents are directly written to the
file, bypassing the file object's ``write`` method. As a result, tofile
cannot be used with files objects supporting compression (e.g., GzipFile)
@@ -5200,7 +5206,7 @@ add_newdoc('numpy.core', 'ufunc', ('reduce',
to None - otherwise it defaults to ufunc.identity.
If ``None`` is given, the first element of the reduction is used,
and an error is thrown if the reduction is empty.
-
+
.. versionadded:: 1.15.0
Returns
@@ -5233,18 +5239,18 @@ add_newdoc('numpy.core', 'ufunc', ('reduce',
>>> np.add.reduce(X, 2)
array([[ 1, 5],
[ 9, 13]])
-
+
You can use the ``initial`` keyword argument to initialize the reduction with a
different value.
-
+
>>> np.add.reduce([10], initial=5)
15
>>> np.add.reduce(np.ones((2, 2, 2)), axis=(0, 2), initializer=10)
array([14., 14.])
-
+
Allows reductions of empty arrays where they would normally fail, i.e.
for ufuncs without an identity.
-
+
>>> np.minimum.reduce([], initial=np.inf)
inf
>>> np.minimum.reduce([])
diff --git a/numpy/core/code_generators/cversions.txt b/numpy/core/code_generators/cversions.txt
index c8b998bfc..73cd8ddd6 100644
--- a/numpy/core/code_generators/cversions.txt
+++ b/numpy/core/code_generators/cversions.txt
@@ -39,9 +39,11 @@
0x0000000b = edb1ba83730c650fd9bc5772a919cda7
# Version 12 (NumPy 1.14) Added PyArray_ResolveWritebackIfCopy,
-# Version 12 (NumPy 1.15) No change.
# PyArray_SetWritebackIfCopyBase and deprecated PyArray_SetUpdateIfCopyBase.
+# Version 12 (NumPy 1.15) No change.
0x0000000c = a1bc756c5782853ec2e3616cf66869d8
-# Version 13 (Numpy 1.16) Added fields core_dim_flags and core_dim_sizes to PyUFuncObject
+# Version 13 (NumPy 1.16) Deprecate PyArray_SetNumericOps and
+# PyArray_GetNumericOps, Added fields core_dim_flags and core_dim_sizes
+# to PyUFuncObject
0x0000000d = a1bc756c5782853ec2e3616cf66869d8
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index a4429cee2..9c74ae6e4 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -903,6 +903,7 @@ def configuration(parent_package='',top_path=None):
join('include', 'numpy', 'npy_math.h'),
join('include', 'numpy', 'halffloat.h'),
join('src', 'multiarray', 'common.h'),
+ join('src', 'multiarray', 'number.h'),
join('src', 'common', 'templ_common.h.src'),
join('src', 'umath', 'simd.inc.src'),
join('src', 'umath', 'override.h'),
diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src
index 6c4d49bd1..b98c3afb3 100644
--- a/numpy/core/src/multiarray/_multiarray_tests.c.src
+++ b/numpy/core/src/multiarray/_multiarray_tests.c.src
@@ -1855,6 +1855,16 @@ printf_float_g(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
return PrintFloat_Printf_g(obj, precision);
}
+static PyObject *
+getset_numericops(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
+{
+ PyObject * ops = PyArray_GetNumericOps();
+ if (ops == NULL) {
+ return NULL;
+ }
+ return PyLong_FromLong(PyArray_SetNumericOps(ops));
+}
+
static PyMethodDef Multiarray_TestsMethods[] = {
{"IsPythonScalar",
IsPythonScalar,
@@ -1963,6 +1973,9 @@ static PyMethodDef Multiarray_TestsMethods[] = {
{"get_fpu_mode",
get_fpu_mode,
METH_VARARGS, get_fpu_mode_doc},
+ {"getset_numericops",
+ getset_numericops,
+ METH_NOARGS, NULL},
/**begin repeat
* #name = cabs, carg#
*/
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 8f782cff6..8db1a1951 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -2990,7 +2990,7 @@ array_set_ops_function(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args),
{
PyObject *oldops = NULL;
- if ((oldops = PyArray_GetNumericOps()) == NULL) {
+ if ((oldops = _PyArray_GetNumericOps()) == NULL) {
return NULL;
}
/*
@@ -3000,8 +3000,10 @@ array_set_ops_function(PyObject *NPY_UNUSED(self), PyObject *NPY_UNUSED(args),
*/
if (kwds && PyArray_SetNumericOps(kwds) == -1) {
Py_DECREF(oldops);
- PyErr_SetString(PyExc_ValueError,
+ if (PyErr_Occurred() == NULL) {
+ PyErr_SetString(PyExc_ValueError,
"one or more objects not callable");
+ }
return NULL;
}
return oldops;
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index dabbae064..57702a0ca 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -71,12 +71,8 @@ array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo
n_ops.op = temp; \
}
-
-/*NUMPY_API
- *Set internal structure with number functions that all arrays will use
- */
NPY_NO_EXPORT int
-PyArray_SetNumericOps(PyObject *dict)
+_PyArray_SetNumericOps(PyObject *dict)
{
PyObject *temp = NULL;
SET(add);
@@ -119,16 +115,28 @@ PyArray_SetNumericOps(PyObject *dict)
return 0;
}
+/*NUMPY_API
+ *Set internal structure with number functions that all arrays will use
+ */
+NPY_NO_EXPORT int
+PyArray_SetNumericOps(PyObject *dict)
+{
+ /* 2018-09-09, 1.16 */
+ if (DEPRECATE("PyArray_SetNumericOps is deprecated. Use "
+ "PyUFunc_ReplaceLoopBySignature to replace ufunc inner loop functions "
+ "instead.") < 0) {
+ return -1;
+ }
+ return _PyArray_SetNumericOps(dict);
+}
+
/* Note - macro contains goto */
#define GET(op) if (n_ops.op && \
(PyDict_SetItemString(dict, #op, n_ops.op)==-1)) \
goto fail;
-/*NUMPY_API
- Get dictionary showing number functions that all arrays will use
-*/
NPY_NO_EXPORT PyObject *
-PyArray_GetNumericOps(void)
+_PyArray_GetNumericOps(void)
{
PyObject *dict;
if ((dict = PyDict_New())==NULL)
@@ -176,6 +184,19 @@ PyArray_GetNumericOps(void)
return NULL;
}
+/*NUMPY_API
+ Get dictionary showing number functions that all arrays will use
+*/
+NPY_NO_EXPORT PyObject *
+PyArray_GetNumericOps(void)
+{
+ /* 2018-09-09, 1.16 */
+ if (DEPRECATE("PyArray_GetNumericOps is deprecated.") < 0) {
+ return NULL;
+ }
+ return _PyArray_GetNumericOps();
+}
+
static PyObject *
_get_keywords(int rtype, PyArrayObject *out)
{
diff --git a/numpy/core/src/multiarray/number.h b/numpy/core/src/multiarray/number.h
index 99a2a722b..fbdfe6f94 100644
--- a/numpy/core/src/multiarray/number.h
+++ b/numpy/core/src/multiarray/number.h
@@ -48,10 +48,10 @@ NPY_NO_EXPORT PyObject *
array_int(PyArrayObject *v);
NPY_NO_EXPORT int
-PyArray_SetNumericOps(PyObject *dict);
+_PyArray_SetNumericOps(PyObject *dict);
NPY_NO_EXPORT PyObject *
-PyArray_GetNumericOps(void);
+_PyArray_GetNumericOps(void);
NPY_NO_EXPORT PyObject *
PyArray_GenericBinaryFunction(PyArrayObject *m1, PyObject *m2, PyObject *op);
diff --git a/numpy/core/src/multiarray/temp_elide.c b/numpy/core/src/multiarray/temp_elide.c
index 3d2f976f2..09b948218 100644
--- a/numpy/core/src/multiarray/temp_elide.c
+++ b/numpy/core/src/multiarray/temp_elide.c
@@ -166,7 +166,7 @@ check_callers(int * cannot)
return 0;
}
/* get multiarray base address */
- if (dladdr(&PyArray_SetNumericOps, &info)) {
+ if (dladdr(&PyArray_INCREF, &info)) {
pos_ma_start = info.dli_fbase;
pos_ma_end = info.dli_fbase;
}
diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c
index 20bd2b0a8..8277ad6cc 100644
--- a/numpy/core/src/umath/umathmodule.c
+++ b/numpy/core/src/umath/umathmodule.c
@@ -29,6 +29,7 @@
#include "abstract.h"
#include "numpy/npy_math.h"
+#include "number.h"
static PyUFuncGenericFunction pyfunc_functions[] = {PyUFunc_On_Om};
@@ -325,7 +326,7 @@ int initumath(PyObject *m)
s2 = PyDict_GetItemString(d, "remainder");
/* Setup the array object's numerical structures with appropriate
ufuncs in d*/
- PyArray_SetNumericOps(d);
+ _PyArray_SetNumericOps(d);
PyDict_SetItemString(d, "conj", s);
PyDict_SetItemString(d, "mod", s2);
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index 10ef16800..7e6e256fe 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -523,3 +523,14 @@ class TestFromstring(_DeprecationTestCase):
# 2017-10-19, 1.14
def test_fromstring(self):
self.assert_deprecated(np.fromstring, args=('\x00'*80,))
+
+class Test_GetSet_NumericOps(_DeprecationTestCase):
+ # 2018-09-20, 1.16.0
+ def test_get_numeric_ops(self):
+ from numpy.core._multiarray_tests import getset_numericops
+ self.assert_deprecated(getset_numericops, num=2)
+
+ # empty kwargs prevents any state actually changing which would break
+ # other tests.
+ self.assert_deprecated(np.set_numeric_ops, kwargs={})
+ assert_raises(ValueError, np.set_numeric_ops, add='abc')