diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/code_generators/generate_umath.py | 2 | ||||
-rw-r--r-- | numpy/core/numeric.py | 7 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.c | 46 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_type_resolution.h | 7 | ||||
-rw-r--r-- | numpy/core/tests/test_defchararray.py | 6 | ||||
-rw-r--r-- | numpy/core/tests/test_deprecations.py | 23 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 5 |
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) |