diff options
author | Julian Taylor <jtaylor.debian@googlemail.com> | 2014-10-28 21:33:22 +0100 |
---|---|---|
committer | Julian Taylor <jtaylor.debian@googlemail.com> | 2014-10-28 23:08:54 +0100 |
commit | b40e686f10421099400a533b343d6d1212f786e9 (patch) | |
tree | 7e812bca620bbccf21de76220c4329c4d6a11222 /numpy/core | |
parent | 76fc3e7df95779b2a67cf40210585cc1bb776591 (diff) | |
download | numpy-b40e686f10421099400a533b343d6d1212f786e9.tar.gz |
BUG: fix not returning out array from ufuncs with subok=False set
closes gh-5240
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 15 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 14 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 30 |
3 files changed, 53 insertions, 6 deletions
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index d825f15e9..b8098531a 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -3932,18 +3932,19 @@ _find_array_wrap(PyObject *args, PyObject *kwds, PyObject *with_wrap[NPY_MAXARGS], *wraps[NPY_MAXARGS]; PyObject *obj, *wrap = NULL; - /* If a 'subok' parameter is passed and isn't True, don't wrap */ + /* + * If a 'subok' parameter is passed and isn't True, don't wrap but put None + * into slots with out arguments which means return the out argument + */ if (kwds != NULL && (obj = PyDict_GetItem(kwds, npy_um_str_subok)) != NULL) { if (obj != Py_True) { - for (i = 0; i < nout; i++) { - output_wrap[i] = NULL; - } - return; + /* skip search for wrap members */ + goto handle_out; } } - nargs = PyTuple_GET_SIZE(args); + for (i = 0; i < nin; i++) { obj = PyTuple_GET_ITEM(args, i); if (PyArray_CheckExact(obj) || PyArray_IsAnyScalar(obj)) { @@ -4001,6 +4002,8 @@ _find_array_wrap(PyObject *args, PyObject *kwds, * exact ndarray so that no PyArray_Return is * done in that case. */ +handle_out: + nargs = PyTuple_GET_SIZE(args); for (i = 0; i < nout; i++) { int j = nin + i; int incref = 1; diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index 40bbe5aec..100875469 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -1686,6 +1686,20 @@ class TestStdVar(TestCase): assert_almost_equal(std(self.A, ddof=2)**2, self.real_var*len(self.A)/float(len(self.A)-2)) + def test_out_scalar(self): + d = np.arange(10) + out = np.array(0.) + r = np.std(d, out=out) + assert_(r is out) + assert_array_equal(r, out) + r = np.var(d, out=out) + assert_(r is out) + assert_array_equal(r, out) + r = np.mean(d, out=out) + assert_(r is out) + assert_array_equal(r, out) + + class TestStdVarComplex(TestCase): def test_basic(self): A = array([1, 1.j, -1, -1.j]) diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index b3ddc2398..29ed66aeb 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -36,6 +36,36 @@ class TestConstants(TestCase): def test_euler_gamma(self): assert_allclose(ncu.euler_gamma, 0.5772156649015329, 1e-15) +class TestOut(TestCase): + def test_out_subok(self): + for b in (True, False): + aout = np.array(0.5) + + r = np.add(aout, 2, out=aout) + assert_(r is aout) + assert_array_equal(r, aout) + + r = np.add(aout, 2, out=aout, subok=b) + assert_(r is aout) + assert_array_equal(r, aout) + + r = np.add(aout, 2, aout, subok=False) + assert_(r is aout) + assert_array_equal(r, aout) + + d = np.ones(5) + o1 = np.zeros(5) + o2 = np.zeros(5, dtype=np.int32) + r1, r2 = np.frexp(d, o1, o2, subok=b) + assert_(r1 is o1) + assert_array_equal(r1, o1) + assert_(r2 is o2) + assert_array_equal(r2, o2) + + r1, r2 = np.frexp(d, out=o1, subok=b) + assert_(r1 is o1) + assert_array_equal(r1, o1) + class TestDivision(TestCase): def test_division_int(self): |