diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/fromnumeric.py | 4 | ||||
-rw-r--r-- | numpy/core/include/numpy/ufuncobject.h | 5 | ||||
-rw-r--r-- | numpy/core/numeric.py | 2 | ||||
-rw-r--r-- | numpy/core/setup_common.py | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.h | 46 | ||||
-rw-r--r-- | numpy/core/src/multiarray/convert_datatype.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarraymodule.c | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/nditer_constr.c | 38 | ||||
-rw-r--r-- | numpy/core/src/multiarray/number.c | 20 | ||||
-rw-r--r-- | numpy/core/src/umath/test_rational.c.src | 3 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 15 | ||||
-rw-r--r-- | numpy/core/src/umath/umathmodule.c | 1 | ||||
-rw-r--r-- | numpy/core/tests/test_api.py | 24 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 2 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 19 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 10 |
16 files changed, 118 insertions, 75 deletions
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index abfa99e80..152cceb1b 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -615,7 +615,7 @@ def partition(a, kth, axis=-1, kind='introselect', order=None): a = asanyarray(a).flatten() axis = 0 else: - a = asanyarray(a).copy() + a = asanyarray(a).copy(order="K") a.partition(kth, axis=axis, kind=kind, order=order) return a @@ -784,7 +784,7 @@ def sort(a, axis=-1, kind='quicksort', order=None): a = asanyarray(a).flatten() axis = 0 else: - a = asanyarray(a).copy() + a = asanyarray(a).copy(order="K") a.sort(axis, kind, order) return a diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h index 423fbc279..a6307df91 100644 --- a/numpy/core/include/numpy/ufuncobject.h +++ b/numpy/core/include/numpy/ufuncobject.h @@ -258,14 +258,11 @@ typedef struct _tagPyUFuncObject { #define UFUNC_FPE_UNDERFLOW 4 #define UFUNC_FPE_INVALID 8 -/* Error mode that avoids look-up (no checking) */ -#define UFUNC_ERR_DEFAULT 0 - #define UFUNC_OBJ_ISOBJECT 1 #define UFUNC_OBJ_NEEDS_API 2 /* Default user error mode */ -#define UFUNC_ERR_DEFAULT2 \ +#define UFUNC_ERR_DEFAULT \ (UFUNC_ERR_WARN << UFUNC_SHIFT_DIVIDEBYZERO) + \ (UFUNC_ERR_WARN << UFUNC_SHIFT_OVERFLOW) + \ (UFUNC_ERR_WARN << UFUNC_SHIFT_INVALID) diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index f43f93d64..1ed339401 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -2741,7 +2741,7 @@ class errstate(object): def _setdef(): - defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT2, None] + defval = [UFUNC_BUFSIZE_DEFAULT, ERR_DEFAULT, None] umath.seterrobj(defval) # set the default values diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py index 4633aef84..bad3607fa 100644 --- a/numpy/core/setup_common.py +++ b/numpy/core/setup_common.py @@ -116,7 +116,6 @@ OPTIONAL_INTRINSICS = [("__builtin_isnan", '5.'), ("__builtin_bswap32", '5u'), ("__builtin_bswap64", '5u'), ("__builtin_expect", '5, 0'), - ("__builtin_ctz", '5'), ("_mm_load_ps", '(float*)0', "xmmintrin.h"), # SSE ("_mm_load_pd", '(double*)0', "emmintrin.h"), # SSE2 ] diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h index 4b23b9442..5d77170ea 100644 --- a/numpy/core/src/multiarray/common.h +++ b/numpy/core/src/multiarray/common.h @@ -119,20 +119,10 @@ npy_is_aligned(const void * p, const npy_uintp alignment) */ static NPY_INLINE char * npy_memchr(char * haystack, char needle, - npy_intp stride, npy_intp size, npy_intp * subloopsize, int invert) + npy_intp stride, npy_intp size, npy_intp * psubloopsize, int invert) { char * p = haystack; - char * const end = haystack + size; - if (stride == 0) { - if (!invert) { - p = (*p != needle) ? end : haystack; - } - else { - p = (*p == needle) ? end : haystack; - } - *subloopsize = (p - haystack); - return haystack; - } + npy_intp subloopsize = 0; if (!invert) { /* @@ -140,38 +130,36 @@ npy_memchr(char * haystack, char needle, * performance less important here. * memchr has large setup cost if 0 byte is close to start. */ - while (p < end && *p != needle) { + while (subloopsize < size && *p != needle) { + subloopsize++; p += stride; } } else { /* usually find elements to skip path */ -#if (defined HAVE___BUILTIN_CTZ && defined NPY_CPU_HAVE_UNALIGNED_ACCESS) +#if defined NPY_CPU_HAVE_UNALIGNED_ACCESS if (needle == 0 && stride == 1) { - while (p < end - (size % sizeof(unsigned int))) { + /* iterate until last multiple of 4 */ + char * block_end = haystack + size - (size % sizeof(unsigned int)); + while (p < block_end) { unsigned int v = *(unsigned int*)p; - if (v == 0) { - p += sizeof(unsigned int); - continue; + if (v != 0) { + break; } - p += __builtin_ctz(v) / 8; - *subloopsize = (p - haystack) / stride; - return p; + p += sizeof(unsigned int); } + /* handle rest */ + subloopsize = (p - haystack); } #endif - while (p < end && *p == needle) { + while (subloopsize < size && *p == needle) { + subloopsize++; p += stride; } } - /* division is very expensive */ - if (NPY_LIKELY(stride == 1)) { - *subloopsize = (p - haystack); - } - else { - *subloopsize = (p - haystack) / stride; - } + *psubloopsize = subloopsize; + return p; } diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index a75a1c22e..4f0202ffb 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -1396,7 +1396,7 @@ static int min_scalar_type_num(char *valueptr, int type_num, break; } case NPY_CLONGDOUBLE: { - npy_cdouble value = *(npy_cdouble *)valueptr; + npy_clongdouble value = *(npy_clongdouble *)valueptr; /* if (value.imag == 0) { return min_scalar_type_num((char *)&value.real, diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index ea879c226..a89e27595 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -1548,6 +1548,7 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order) PyArray_FLAGS(arr), (PyObject *)arr); if (ret == NULL) { + Py_DECREF(arr); return NULL; } /* steals a reference to arr --- so don't increment here */ diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c index 053777f6a..a12457a1e 100644 --- a/numpy/core/src/multiarray/nditer_constr.c +++ b/numpy/core/src/multiarray/nditer_constr.c @@ -1161,11 +1161,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in, /* Check the readonly/writeonly flags, and fill in op_itflags */ if (!npyiter_check_per_op_flags(op_flags[iop], &op_itflags[iop])) { - for (i = 0; i <= iop; ++i) { - Py_XDECREF(op[i]); - Py_XDECREF(op_dtype[i]); - } - return 0; + goto fail_iop; } /* Extract the operand which is for masked iteration */ @@ -1174,11 +1170,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in, PyErr_SetString(PyExc_ValueError, "Only one iterator operand may receive an " "ARRAYMASK flag"); - for (i = 0; i <= iop; ++i) { - Py_XDECREF(op[i]); - Py_XDECREF(op_dtype[i]); - } - return 0; + goto fail_iop; } maskop = iop; @@ -1199,11 +1191,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in, &op_dtype[iop], flags, op_flags[iop], &op_itflags[iop])) { - for (i = 0; i <= iop; ++i) { - Py_XDECREF(op[i]); - Py_XDECREF(op_dtype[i]); - } - return 0; + goto fail_iop; } } @@ -1217,13 +1205,9 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in, } } if (all_null) { - for (i = 0; i < nop; ++i) { - Py_XDECREF(op[i]); - Py_XDECREF(op_dtype[i]); - } PyErr_SetString(PyExc_ValueError, "At least one iterator operand must be non-NULL"); - return 0; + goto fail_nop; } } @@ -1232,17 +1216,26 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in, "An iterator operand was flagged as WRITEMASKED, " "but no ARRAYMASK operand was given to supply " "the mask"); - return 0; + goto fail_nop; } else if (!any_writemasked_ops && maskop >= 0) { PyErr_SetString(PyExc_ValueError, "An iterator operand was flagged as the ARRAYMASK, " "but no WRITEMASKED operands were given to use " "the mask"); - return 0; + goto fail_nop; } return 1; + + fail_nop: + iop = nop; + fail_iop: + for (i = 0; i < iop; ++i) { + Py_XDECREF(op[i]); + Py_XDECREF(op_dtype[i]); + } + return 0; } static const char * @@ -1565,6 +1558,7 @@ npyiter_fill_axisdata(NpyIter *iter, npy_uint32 flags, npyiter_opitflags *op_itf NAD_SHAPE(axisdata) = 1; NAD_INDEX(axisdata) = 0; memcpy(NAD_PTRS(axisdata), op_dataptr, NPY_SIZEOF_INTP*nop); + memset(NAD_STRIDES(axisdata), 0, NPY_SIZEOF_INTP*nop); } /* Now process the operands, filling in the axisdata */ diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c index 2ad65bbe8..bb281835b 100644 --- a/numpy/core/src/multiarray/number.c +++ b/numpy/core/src/multiarray/number.c @@ -771,6 +771,7 @@ array_int(PyArrayObject *v) PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) { PyErr_SetString(PyExc_TypeError, "object array may be self-referencing"); + Py_DECREF(pv); return NULL; } @@ -812,6 +813,7 @@ array_float(PyArrayObject *v) PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) { PyErr_SetString(PyExc_TypeError, "object array may be self-referencing"); + Py_DECREF(pv); return NULL; } pv2 = Py_TYPE(pv)->tp_as_number->nb_float(pv); @@ -831,14 +833,19 @@ array_long(PyArrayObject *v) return NULL; } pv = PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v); + if (pv == NULL) { + return NULL; + } if (Py_TYPE(pv)->tp_as_number == 0) { PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\ "scalar object is not a number"); + Py_DECREF(pv); return NULL; } if (Py_TYPE(pv)->tp_as_number->nb_long == 0) { PyErr_SetString(PyExc_TypeError, "don't know how to convert "\ "scalar number to long"); + Py_DECREF(pv); return NULL; } /* @@ -849,6 +856,7 @@ array_long(PyArrayObject *v) PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) { PyErr_SetString(PyExc_TypeError, "object array may be self-referencing"); + Py_DECREF(pv); return NULL; } pv2 = Py_TYPE(pv)->tp_as_number->nb_long(pv); @@ -866,14 +874,19 @@ array_oct(PyArrayObject *v) return NULL; } pv = PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v); + if (pv == NULL) { + return NULL; + } if (Py_TYPE(pv)->tp_as_number == 0) { PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\ "scalar object is not a number"); + Py_DECREF(pv); return NULL; } if (Py_TYPE(pv)->tp_as_number->nb_oct == 0) { PyErr_SetString(PyExc_TypeError, "don't know how to convert "\ "scalar number to oct"); + Py_DECREF(pv); return NULL; } /* @@ -884,6 +897,7 @@ array_oct(PyArrayObject *v) PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) { PyErr_SetString(PyExc_TypeError, "object array may be self-referencing"); + Py_DECREF(pv); return NULL; } pv2 = Py_TYPE(pv)->tp_as_number->nb_oct(pv); @@ -901,14 +915,19 @@ array_hex(PyArrayObject *v) return NULL; } pv = PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v); + if (pv == NULL) { + return NULL; + } if (Py_TYPE(pv)->tp_as_number == 0) { PyErr_SetString(PyExc_TypeError, "cannot convert to an int; "\ "scalar object is not a number"); + Py_DECREF(pv); return NULL; } if (Py_TYPE(pv)->tp_as_number->nb_hex == 0) { PyErr_SetString(PyExc_TypeError, "don't know how to convert "\ "scalar number to hex"); + Py_DECREF(pv); return NULL; } /* @@ -919,6 +938,7 @@ array_hex(PyArrayObject *v) PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) { PyErr_SetString(PyExc_TypeError, "object array may be self-referencing"); + Py_DECREF(pv); return NULL; } pv2 = Py_TYPE(pv)->tp_as_number->nb_hex(pv); diff --git a/numpy/core/src/umath/test_rational.c.src b/numpy/core/src/umath/test_rational.c.src index 1650dd1d3..d8f90f9e5 100644 --- a/numpy/core/src/umath/test_rational.c.src +++ b/numpy/core/src/umath/test_rational.c.src @@ -1242,12 +1242,15 @@ PyMODINIT_FUNC inittest_rational(void) { PyErr_Format(PyExc_AssertionError, \ "ufunc %s takes %d arguments, our loop takes %ld", \ #name, ufunc->nargs, sizeof(_types)/sizeof(int)); \ + Py_DECREF(ufunc); \ goto fail; \ } \ if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc, npy_rational, \ rational_ufunc_##name, _types, 0) < 0) { \ + Py_DECREF(ufunc); \ goto fail; \ } \ + Py_DECREF(ufunc); \ } #define REGISTER_UFUNC_BINARY_RATIONAL(name) \ REGISTER_UFUNC(name, {npy_rational, npy_rational, npy_rational}) diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index e419a6611..a47d9a96c 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -432,10 +432,17 @@ _extract_pyvals(PyObject *ref, char *name, int *bufsize, { PyObject *retval; + /* default errobj case, skips dictionary lookup */ if (ref == NULL) { - *errmask = UFUNC_ERR_DEFAULT; - *errobj = Py_BuildValue("NO", PyBytes_FromString(name), Py_None); - *bufsize = NPY_BUFSIZE; + if (errmask) { + *errmask = UFUNC_ERR_DEFAULT; + } + if (errobj) { + *errobj = Py_BuildValue("NO", PyBytes_FromString(name), Py_None); + } + if (bufsize) { + *bufsize = NPY_BUFSIZE; + } return 0; } @@ -5076,7 +5083,7 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args) } else { Py_INCREF(PyArray_DESCR(op1_array)); - array_operands[2] = new_array_op(op1_array, iter->dataptr); + array_operands[1] = new_array_op(op1_array, iter->dataptr); array_operands[2] = NULL; } diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c index 0b789de26..8c95cebf5 100644 --- a/numpy/core/src/umath/umathmodule.c +++ b/numpy/core/src/umath/umathmodule.c @@ -403,7 +403,6 @@ PyMODINIT_FUNC initumath(void) ADDCONST(ERR_PRINT); ADDCONST(ERR_LOG); ADDCONST(ERR_DEFAULT); - ADDCONST(ERR_DEFAULT2); ADDCONST(SHIFT_DIVIDEBYZERO); ADDCONST(SHIFT_OVERFLOW); diff --git a/numpy/core/tests/test_api.py b/numpy/core/tests/test_api.py index d642a2237..a1a3f896c 100644 --- a/numpy/core/tests/test_api.py +++ b/numpy/core/tests/test_api.py @@ -122,13 +122,13 @@ def test_array_array(): # Try with lists... assert_equal(np.array([None] * 10, dtype=np.float64), - np.empty((10,), dtype=np.float64) + np.nan) + np.full((10,), np.nan, dtype=np.float64)) assert_equal(np.array([[None]] * 10, dtype=np.float64), - np.empty((10, 1), dtype=np.float64) + np.nan) + np.full((10, 1), np.nan, dtype=np.float64)) assert_equal(np.array([[None] * 10], dtype=np.float64), - np.empty((1, 10), dtype=np.float64) + np.nan) + np.full((1, 10), np.nan, dtype=np.float64)) assert_equal(np.array([[None] * 10] * 10, dtype=np.float64), - np.empty((10, 10), dtype=np.float64) + np.nan) + np.full((10, 10), np.nan, dtype=np.float64)) assert_equal(np.array([1.0] * 10, dtype=np.float64), np.ones((10,), dtype=np.float64)) @@ -141,13 +141,13 @@ def test_array_array(): # Try with tuples assert_equal(np.array((None,) * 10, dtype=np.float64), - np.empty((10,), dtype=np.float64) + np.nan) + np.full((10,), np.nan, dtype=np.float64)) assert_equal(np.array([(None,)] * 10, dtype=np.float64), - np.empty((10, 1), dtype=np.float64) + np.nan) + np.full((10, 1), np.nan, dtype=np.float64)) assert_equal(np.array([(None,) * 10], dtype=np.float64), - np.empty((1, 10), dtype=np.float64) + np.nan) + np.full((1, 10), np.nan, dtype=np.float64)) assert_equal(np.array([(None,) * 10] * 10, dtype=np.float64), - np.empty((10, 10), dtype=np.float64) + np.nan) + np.full((10, 10), np.nan, dtype=np.float64)) assert_equal(np.array((1.0,) * 10, dtype=np.float64), np.ones((10,), dtype=np.float64)) @@ -332,6 +332,14 @@ def test_copyto(): assert_raises(TypeError, np.copyto, [1, 2, 3], [2, 3, 4]) def test_copyto_permut(): + # test explicit overflow case + pad = 500 + l = [True] * pad + [True, True, True, True] + r = np.zeros(len(l)-pad) + d = np.ones(len(l)-pad) + mask = np.array(l)[pad:] + np.copyto(r, d, where=mask[::-1]) + # test all permutation of possible masks, 9 should be sufficient for # current 4 byte unrolled code power = 9 diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 9f333a4a2..9d191da35 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -1624,7 +1624,7 @@ class TestBinop(object): # Check behavior against both bare ndarray objects and a # ndarray subclasses with and without their own override - obj = cls((1,)) + obj = cls((1,), buffer=np.ones(1,)) arr_objs = [np.array([1]), np.array([2]).view(OtherNdarraySubclass), diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index 5a3de8edd..ac341468c 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -8,6 +8,7 @@ import itertools import numpy as np from numpy.core import * +from numpy.core import umath from numpy.random import rand, randint, randn from numpy.testing import * from numpy.core.multiarray import dot as dot_ @@ -439,6 +440,24 @@ class TestSeterr(TestCase): np.seterrobj(olderrobj) del self.called + def test_errobj_noerrmask(self): + # errmask = 0 has a special code path for the default + olderrobj = np.geterrobj() + try: + # set errobj to something non default + np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, + umath.ERR_DEFAULT + 1, None]) + #call a ufunc + np.isnan(np.array([6])) + # same with the default, lots of times to get rid of possible + # pre-existing stack in the code + for i in range(10000): + np.seterrobj([umath.UFUNC_BUFSIZE_DEFAULT, umath.ERR_DEFAULT, + None]) + np.isnan(np.array([6])) + finally: + np.seterrobj(olderrobj) + class TestFloatExceptions(TestCase): def assert_raises_fpe(self, fpeerr, flop, x, y): diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 02cf1b8df..b98746e1b 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1654,6 +1654,14 @@ class TestRegression(TestCase): assert_raises(TypeError, oct, a) assert_raises(TypeError, hex, a) + # Test the same for a circular reference. + b = np.array(a, dtype=object) + a[()] = b + assert_raises(TypeError, int, a) + # Numpy has no tp_traverse currently, so circular references + # cannot be detected. So resolve it: + a[()] = 0 + # This was causing a to become like the above a = np.array(0, dtype=object) a[...] += 1 @@ -1661,7 +1669,7 @@ class TestRegression(TestCase): def test_object_array_self_copy(self): # An object array being copied into itself DECREF'ed before INCREF'ing - # causing segmentation faults (gh-3787) + # causing segmentation faults (gh-3787) a = np.array(object(), dtype=object) np.copyto(a, a) assert_equal(sys.getrefcount(a[()]), 2) |