summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/code_generators/generate_umath.py2
-rw-r--r--numpy/core/numeric.py7
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c46
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.h7
-rw-r--r--numpy/core/tests/test_defchararray.py6
-rw-r--r--numpy/core/tests/test_deprecations.py23
-rw-r--r--numpy/core/tests/test_regression.py5
7 files changed, 88 insertions, 8 deletions
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index e02cb8709..e3c9cf28b 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -369,7 +369,7 @@ defdict = {
'negative':
Ufunc(1, 1, None,
docstrings.get('numpy.core.umath.negative'),
- 'PyUFunc_SimpleUnaryOperationTypeResolver',
+ 'PyUFunc_NegativeTypeResolver',
TD(bints+flts+timedeltaonly),
TD(cmplx, f='neg'),
TD(O, f='PyNumber_Negative'),
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index 39e5a4cd5..6b078ae31 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -2154,7 +2154,12 @@ def allclose(a, b, rtol=1.e-5, atol=1.e-8):
# ignore invalid fpe's
with errstate(invalid='ignore'):
- r = all(less_equal(abs(x-y), atol + rtol * abs(y)))
+ if not x.dtype.kind == 'b' and not y.dtype.kind == 'b':
+ diff = abs(x - y)
+ else:
+ diff = x ^ y
+
+ r = all(less_equal(diff, atol + rtol * abs(y)))
return r
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c
index 12d8e406b..ffdb15bbe 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.c
+++ b/numpy/core/src/umath/ufunc_type_resolution.c
@@ -367,6 +367,34 @@ PyUFunc_SimpleUnaryOperationTypeResolver(PyUFuncObject *ufunc,
return 0;
}
+
+NPY_NO_EXPORT int
+PyUFunc_NegativeTypeResolver(PyUFuncObject *ufunc,
+ NPY_CASTING casting,
+ PyArrayObject **operands,
+ PyObject *type_tup,
+ PyArray_Descr **out_dtypes)
+{
+ int ret;
+ ret = PyUFunc_SimpleUnaryOperationTypeResolver(ufunc, casting, operands,
+ type_tup, out_dtypes);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* The type resolver would have upcast already */
+ if (out_dtypes[0]->type_num == NPY_BOOL) {
+ if (DEPRECATE("numpy boolean negative (the unary `-` operator) is "
+ "deprecated, use the bitwise_xor (the `^` operator) "
+ "or the logical_xor function instead.") < 0) {
+ return -1;
+ }
+ }
+
+ return ret;
+}
+
+
/*
* The ones_like function shouldn't really be a ufunc, but while it
* still is, this provides type resolution that always forces UNSAFE
@@ -762,8 +790,22 @@ PyUFunc_SubtractionTypeResolver(PyUFuncObject *ufunc,
/* Use the default when datetime and timedelta are not involved */
if (!PyTypeNum_ISDATETIME(type_num1) && !PyTypeNum_ISDATETIME(type_num2)) {
- return PyUFunc_SimpleBinaryOperationTypeResolver(ufunc, casting,
- operands, type_tup, out_dtypes);
+ int ret;
+ ret = PyUFunc_SimpleBinaryOperationTypeResolver(ufunc, casting,
+ operands, type_tup, out_dtypes);
+ if (ret < 0) {
+ return ret;
+ }
+
+ /* The type resolver would have upcast already */
+ if (out_dtypes[0]->type_num == NPY_BOOL) {
+ if (DEPRECATE("numpy boolean subtract (the binary `-` operator) is "
+ "deprecated, use the bitwise_xor (the `^` operator) "
+ "or the logical_xor function instead.") < 0) {
+ return -1;
+ }
+ }
+ return ret;
}
if (type_num1 == NPY_TIMEDELTA) {
diff --git a/numpy/core/src/umath/ufunc_type_resolution.h b/numpy/core/src/umath/ufunc_type_resolution.h
index a1241827e..a1e28d75b 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.h
+++ b/numpy/core/src/umath/ufunc_type_resolution.h
@@ -16,6 +16,13 @@ PyUFunc_SimpleUnaryOperationTypeResolver(PyUFuncObject *ufunc,
PyArray_Descr **out_dtypes);
NPY_NO_EXPORT int
+PyUFunc_NegativeTypeResolver(PyUFuncObject *ufunc,
+ NPY_CASTING casting,
+ PyArrayObject **operands,
+ PyObject *type_tup,
+ PyArray_Descr **out_dtypes);
+
+NPY_NO_EXPORT int
PyUFunc_OnesLikeTypeResolver(PyUFuncObject *ufunc,
NPY_CASTING casting,
PyArrayObject **operands,
diff --git a/numpy/core/tests/test_defchararray.py b/numpy/core/tests/test_defchararray.py
index 09fcff0d0..c210f8bf6 100644
--- a/numpy/core/tests/test_defchararray.py
+++ b/numpy/core/tests/test_defchararray.py
@@ -128,9 +128,9 @@ class TestWhitespace(TestCase):
assert_(all(self.A == self.B))
assert_(all(self.A >= self.B))
assert_(all(self.A <= self.B))
- assert_(all(negative(self.A > self.B)))
- assert_(all(negative(self.A < self.B)))
- assert_(all(negative(self.A != self.B)))
+ assert_(not any(self.A > self.B))
+ assert_(not any(self.A < self.B))
+ assert_(not any(self.A != self.B))
class TestChar(TestCase):
def setUp(self):
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index 41f1cf744..f7fbb94e5 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -343,5 +343,28 @@ class TestMultipleEllipsisDeprecation(_DeprecationTestCase):
assert_raises(IndexError, a.__getitem__, ((Ellipsis, ) * 3,))
+class TestBooleanSubtractDeprecations(_DeprecationTestCase):
+ """Test deprecation of boolean `-`. While + and * are well
+ defined, - is not and even a corrected form seems to have
+ no real uses.
+
+ The deprecation process was started in NumPy 1.9.
+ """
+ message = r"numpy boolean .* \(the .* `-` operator\) is deprecated, " \
+ "use the bitwise"
+
+ def test_operator_deprecation(self):
+ array = np.array([True])
+ generic = np.bool_(True)
+
+ # Minus operator/subtract ufunc:
+ self.assert_deprecated(operator.sub, args=(array, array))
+ self.assert_deprecated(operator.sub, args=(generic, generic))
+
+ # Unary minus/negative ufunc:
+ self.assert_deprecated(operator.neg, args=(array,))
+ self.assert_deprecated(operator.neg, args=(generic,))
+
+
if __name__ == "__main__":
run_module_suite()
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 9f2abc5c0..cb3791daf 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -447,7 +447,10 @@ class TestRegression(TestCase):
res1 = getattr(arr, func_meth)()
res2 = getattr(np, func)(arr2)
if res1 is None:
- assert_(abs(arr-res2).max() < 1e-8, func)
+ res1 = arr
+
+ if res1.dtype.kind in 'uib':
+ assert_((res1 == res2).all(), func)
else:
assert_(abs(res1-res2).max() < 1e-8, func)