summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/include/numpy/ndarraytypes.h37
-rw-r--r--numpy/core/include/numpy/npy_1_7_deprecated_api.h (renamed from numpy/core/include/numpy/npy_deprecated_api.h)21
-rw-r--r--numpy/core/setup.py2
-rw-r--r--numpy/core/src/multiarray/mapping.c4
-rw-r--r--numpy/core/src/umath/ufunc_object.c4
-rw-r--r--numpy/core/tests/test_indexing.py23
-rw-r--r--numpy/lib/format.py2
-rw-r--r--numpy/lib/function_base.py7
-rw-r--r--numpy/lib/tests/test_function_base.py11
9 files changed, 82 insertions, 29 deletions
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h
index bb3f1065c..fc8dca950 100644
--- a/numpy/core/include/numpy/ndarraytypes.h
+++ b/numpy/core/include/numpy/ndarraytypes.h
@@ -627,8 +627,8 @@ typedef struct _arr_descr {
* (PyArray_DATA and friends) to access fields here for a number of
* releases. Direct access to the members themselves is deprecated.
* To ensure that your code does not use deprecated access,
- * #define NPY_NO_DEPRECATED_API NPY_1_7_VERSION
- * (or NPY_1_8_VERSION or higher as required).
+ * #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ * (or NPY_1_8_API_VERSION or higher as required).
*/
/* This struct will be moved to a private header in a future release */
typedef struct tagPyArrayObject_fields {
@@ -675,7 +675,8 @@ typedef struct tagPyArrayObject_fields {
* To hide the implementation details, we only expose
* the Python struct HEAD.
*/
-#if !(defined(NPY_NO_DEPRECATED_API) && (NPY_API_VERSION <= NPY_NO_DEPRECATED_API))
+#if !defined(NPY_NO_DEPRECATED_API) || \
+ (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
/*
* Can't put this in npy_deprecated_api.h like the others.
* PyArrayObject field access is deprecated as of NumPy 1.7.
@@ -921,6 +922,8 @@ typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
#define NPY_BEGIN_THREADS_DEF PyThreadState *_save=NULL;
#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
#define NPY_END_THREADS do {if (_save) PyEval_RestoreThread(_save);} while (0);
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
+ { _save = PyEval_SaveThread();} } while (0);
#define NPY_BEGIN_THREADS_DESCR(dtype) \
do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
@@ -1383,7 +1386,7 @@ PyArrayNeighborhoodIter_Next2D(PyArrayNeighborhoodIterObject* iter);
#define PyArray_FORTRAN_IF(m) ((PyArray_CHKFLAGS(m, NPY_ARRAY_F_CONTIGUOUS) ? \
NPY_ARRAY_F_CONTIGUOUS : 0))
-#if (defined(NPY_NO_DEPRECATED_API) && (NPY_API_VERSION <= NPY_NO_DEPRECATED_API))
+#if (defined(NPY_NO_DEPRECATED_API) && (NPY_1_7_API_VERSION <= NPY_NO_DEPRECATED_API))
/*
* Changing access macros into functions, to allow for future hiding
* of the internal memory layout. This later hiding will allow the 2.x series
@@ -1732,8 +1735,30 @@ typedef struct {
typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
void *user_data);
-#if !(defined(NPY_NO_DEPRECATED_API) && (NPY_API_VERSION <= NPY_NO_DEPRECATED_API))
-#include "npy_deprecated_api.h"
+/*
+ * Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
+ * npy_*_*_deprecated_api.h are only included from here and nowhere else.
+ */
+#ifdef NPY_DEPRECATED_INCLUDES
+#error "Do not use the reserved keyword NPY_DEPRECATED_INCLUDES."
#endif
+#define NPY_DEPRECATED_INCLUDES
+#if !defined(NPY_NO_DEPRECATED_API) || \
+ (NPY_NO_DEPRECATED_API < NPY_1_7_API_VERSION)
+#include "npy_1_7_deprecated_api.h"
+#endif
+/*
+ * There is no file npy_1_8_deprecated_api.h since there are no additional
+ * deprecated API features in NumPy 1.8.
+ *
+ * Note to maintainers: insert code like the following in future NumPy
+ * versions.
+ *
+ * #if !defined(NPY_NO_DEPRECATED_API) || \
+ * (NPY_NO_DEPRECATED_API < NPY_1_9_API_VERSION)
+ * #include "npy_1_9_deprecated_api.h"
+ * #endif
+ */
+#undef NPY_DEPRECATED_INCLUDES
#endif /* NPY_ARRAYTYPES_H */
diff --git a/numpy/core/include/numpy/npy_deprecated_api.h b/numpy/core/include/numpy/npy_1_7_deprecated_api.h
index f082d0827..6c576d138 100644
--- a/numpy/core/include/numpy/npy_deprecated_api.h
+++ b/numpy/core/include/numpy/npy_1_7_deprecated_api.h
@@ -1,28 +1,30 @@
-#ifndef _NPY_DEPRECATED_API_H
-#define _NPY_DEPRECATED_API_H
+#ifndef _NPY_1_7_DEPRECATED_API_H
+#define _NPY_1_7_DEPRECATED_API_H
+
+#ifndef NPY_DEPRECATED_INCLUDES
+#error "Should never include npy_*_*_deprecated_api directly."
+#endif
#if defined(_WIN32)
#define _WARN___STR2__(x) #x
#define _WARN___STR1__(x) _WARN___STR2__(x)
#define _WARN___LOC__ __FILE__ "("_WARN___STR1__(__LINE__)") : Warning Msg: "
#pragma message(_WARN___LOC__"Using deprecated NumPy API, disable it by " \
- "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
+ "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION")
#elif defined(__GNUC__)
-#warning "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
+#warning "Using deprecated NumPy API, disable it by " \
+ "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
#endif
/* TODO: How to do this warning message for other compilers? */
/*
- * This header exists to collect all dangerous/deprecated NumPy API.
+ * This header exists to collect all dangerous/deprecated NumPy API
+ * as of NumPy 1.7.
*
* This is an attempt to remove bad API, the proliferation of macros,
* and namespace pollution currently produced by the NumPy headers.
*/
-#if defined(NPY_NO_DEPRECATED_API)
-#error Should never include npy_deprecated_api directly.
-#endif
-
/* These array flags are deprecated as of NumPy 1.7 */
#define NPY_CONTIGUOUS NPY_ARRAY_C_CONTIGUOUS
#define NPY_FORTRAN NPY_ARRAY_F_CONTIGUOUS
@@ -125,5 +127,4 @@
*/
#include "old_defines.h"
-
#endif
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 05e20a09a..0c58abfa7 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -766,7 +766,7 @@ def configuration(parent_package='',top_path=None):
join('include', 'numpy', 'npy_cpu.h'),
join('include', 'numpy', 'numpyconfig.h'),
join('include', 'numpy', 'ndarraytypes.h'),
- join('include', 'numpy', 'npy_deprecated_api.h'),
+ join('include', 'numpy', 'npy_1_7_deprecated_api.h'),
join('include', 'numpy', '_numpyconfig.h.in'),
]
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index 8b3e5b5a9..25f3dad9b 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -806,8 +806,7 @@ array_ass_boolean_subscript(PyArrayObject *self,
}
/* Tweak the strides for 0-dim and broadcasting cases */
- if (PyArray_NDIM(v) > 0 && PyArray_DIMS(v)[0] > 1) {
- v_stride = PyArray_STRIDES(v)[0];
+ if (PyArray_NDIM(v) > 0 && PyArray_DIMS(v)[0] != 1) {
if (size != PyArray_DIMS(v)[0]) {
PyErr_Format(PyExc_ValueError,
"NumPy boolean array indexing assignment "
@@ -816,6 +815,7 @@ array_ass_boolean_subscript(PyArrayObject *self,
(int)PyArray_DIMS(v)[0], (int)size);
return -1;
}
+ v_stride = PyArray_STRIDES(v)[0];
}
else {
v_stride = 0;
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index c3d804b2a..bea15c65c 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -1098,7 +1098,7 @@ trivial_two_operand_loop(PyArrayObject **op,
NPY_UF_DBG_PRINT1("two operand loop count %d\n", (int)count[0]);
if (!needs_api) {
- NPY_BEGIN_THREADS;
+ NPY_BEGIN_THREADS_THRESHOLDED(count[0]);
}
innerloop(data, count, stride, innerloopdata);
@@ -1131,7 +1131,7 @@ trivial_three_operand_loop(PyArrayObject **op,
NPY_UF_DBG_PRINT1("three operand loop count %d\n", (int)count[0]);
if (!needs_api) {
- NPY_BEGIN_THREADS;
+ NPY_BEGIN_THREADS_THRESHOLDED(count[0]);
}
innerloop(data, count, stride, innerloopdata);
diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py
index fa44900c7..3c74bc466 100644
--- a/numpy/core/tests/test_indexing.py
+++ b/numpy/core/tests/test_indexing.py
@@ -84,7 +84,7 @@ class TestIndexing(TestCase):
assert_equal(a[np.array(False)], a[0])
def test_boolean_indexing_onedim(self):
- # Indexing a 2-dimensional array with
+ # Indexing a 2-dimensional array with
# boolean array of length one
a = np.array([[ 0., 0., 0.]])
b = np.array([ True], dtype=bool)
@@ -93,8 +93,19 @@ class TestIndexing(TestCase):
a[b] = 1.
assert_equal(a, [[1., 1., 1.]])
+ def test_boolean_assignment_value_mismatch(self):
+ # A boolean assignment should fail when the shape of the values
+ # cannot be broadcasted to the subscription. (see also gh-3458)
+ a = np.arange(4)
+ def f(a, v):
+ a[a > -1] = v
+
+ assert_raises(ValueError, f, a, [])
+ assert_raises(ValueError, f, a, [1, 2, 3])
+ assert_raises(ValueError, f, a[:1], [1, 2, 3])
+
def test_boolean_indexing_twodim(self):
- # Indexing a 2-dimensional array with
+ # Indexing a 2-dimensional array with
# 2-dimensional boolean array
a = np.array([[1, 2, 3],
[4 ,5, 6],
@@ -116,7 +127,7 @@ class TestIndexing(TestCase):
class TestMultiIndexingAutomated(TestCase):
"""
These test use code to mimic the C-Code indexing for selection.
-
+
NOTE: * This still lacks tests for complex item setting.
* If you change behavoir of indexing, you might want to modify
these tests to try more combinations.
@@ -160,7 +171,7 @@ class TestMultiIndexingAutomated(TestCase):
def _get_multi_index(self, arr, indices):
"""Mimic multi dimensional indexing.
-
+
Parameters
----------
arr : ndarray
@@ -185,7 +196,7 @@ class TestMultiIndexingAutomated(TestCase):
in_indices = list(indices)
indices = []
# if False, this is a fancy or boolean index
- no_copy = True
+ no_copy = True
# number of fancy/scalar indexes that are not consecutive
num_fancy = 0
# number of dimensions indexed by a "fancy" index
@@ -487,7 +498,7 @@ class TestMultiIndexingAutomated(TestCase):
self._check_multi_index(self.b, index)
# Check very simple item getting:
self._check_multi_index(self.a, (0,0,0,0))
- self._check_multi_index(self.b, (0,0,0,0))
+ self._check_multi_index(self.b, (0,0,0,0))
# Also check (simple cases of) too many indices:
assert_raises(IndexError, self.a.__getitem__, (0,0,0,0,0))
assert_raises(IndexError, self.a.__setitem__, (0,0,0,0,0), 0)
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
index ff3b95d6e..fd459e84e 100644
--- a/numpy/lib/format.py
+++ b/numpy/lib/format.py
@@ -35,7 +35,7 @@ Capabilities
- Is straightforward to reverse engineer. Datasets often live longer than
the programs that created them. A competent developer should be
- able create a solution in his preferred programming language to
+ able to create a solution in his preferred programming language to
read most ``.npy`` files that he has been given without much
documentation.
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 5e433d3ab..17f99a065 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -3696,6 +3696,11 @@ def insert(arr, obj, values, axis=None):
arr = arr.ravel()
ndim = arr.ndim
axis = ndim-1
+ else:
+ if ndim > 0 and (axis < -ndim or axis >= ndim):
+ raise IndexError("axis %i is out of bounds for an array "
+ "of dimension %i" % (axis, ndim))
+ if (axis < 0): axis += ndim
if (ndim == 0):
warnings.warn("in the future the special handling of scalars "
"will be removed from insert and raise an error",
@@ -3742,7 +3747,7 @@ def insert(arr, obj, values, axis=None):
# broadcasting is very different here, since a[:,0,:] = ... behaves
# very different from a[:,[0],:] = ...! This changes values so that
# it works likes the second case. (here a[:,0:1,:])
- values = np.rollaxis(values, 0, axis+1)
+ values = np.rollaxis(values, 0, axis + 1)
numnew = values.shape[axis]
newshape[axis] += numnew
new = empty(newshape, arr.dtype, arr.flags.fnc)
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index a23e406e3..de561e55a 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -211,6 +211,17 @@ class TestInsert(TestCase):
assert_equal(insert(a[:,:1], 1, a[:,1], axis=1), a)
assert_equal(insert(a[:1,:], 1, a[1,:], axis=0), a)
+ # negative axis value
+ a = np.arange(24).reshape((2,3,4))
+ assert_equal(insert(a, 1, a[:,:,3], axis=-1),
+ insert(a, 1, a[:,:,3], axis=2))
+ assert_equal(insert(a, 1, a[:,2,:], axis=-2),
+ insert(a, 1, a[:,2,:], axis=1))
+
+ # invalid axis value
+ assert_raises(IndexError, insert, a, 1, a[:,2,:], axis=3)
+ assert_raises(IndexError, insert, a, 1, a[:,2,:], axis=-4)
+
def test_0d(self):
# This is an error in the future
a = np.array(1)