diff options
-rw-r--r-- | doc/changelog/1.15.4-changelog.rst | 21 | ||||
-rw-r--r-- | doc/release/1.15.4-notes.rst | 38 | ||||
-rw-r--r-- | doc/source/release.rst | 1 | ||||
-rw-r--r-- | numpy/core/einsumfunc.py | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arrayobject.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 7 | ||||
-rw-r--r-- | numpy/core/src/multiarray/buffer.c | 4 | ||||
-rw-r--r-- | numpy/core/src/multiarray/buffer.h | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.c | 10 | ||||
-rw-r--r-- | numpy/core/src/multiarray/conversion_utils.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 4 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/getset.c | 3 | ||||
-rw-r--r-- | numpy/core/src/multiarray/scalartypes.c.src | 2 | ||||
-rw-r--r-- | numpy/ma/core.py | 23 | ||||
-rw-r--r-- | numpy/ma/tests/test_core.py | 150 | ||||
-rw-r--r-- | pavement.py | 4 | ||||
-rwxr-xr-x | setup.py | 2 |
18 files changed, 258 insertions, 21 deletions
diff --git a/doc/changelog/1.15.4-changelog.rst b/doc/changelog/1.15.4-changelog.rst new file mode 100644 index 000000000..fbe71f4ae --- /dev/null +++ b/doc/changelog/1.15.4-changelog.rst @@ -0,0 +1,21 @@ + +Contributors +============ + +A total of 4 people contributed to this release. People with a "+" by their +names contributed a patch for the first time. + +* Charles Harris +* Matti Picus +* Sebastian Berg +* bbbbbbbbba + + +Pull requests merged +==================== + +A total of 4 pull requests were merged for this release. + +* `#12296 <https://github.com/numpy/numpy/pull/12296>`__: BUG: Dealloc cached buffer info (#12249) +* `#12297 <https://github.com/numpy/numpy/pull/12297>`__: BUG: Fix fill value in masked array '==' and '!=' ops. +* `#12307 <https://github.com/numpy/numpy/pull/12307>`__: DOC: Correct the default value of `optimize` in `numpy.einsum` +* `#12320 <https://github.com/numpy/numpy/pull/12320>`__: REL: Prepare for the NumPy 1.15.4 release diff --git a/doc/release/1.15.4-notes.rst b/doc/release/1.15.4-notes.rst new file mode 100644 index 000000000..033bd5828 --- /dev/null +++ b/doc/release/1.15.4-notes.rst @@ -0,0 +1,38 @@ +========================== +NumPy 1.15.4 Release Notes +========================== + +This is a bugfix release for bugs and regressions reported following the 1.15.3 +release. The Python versions supported by this release are 2.7, 3.4-3.7. The +wheels are linked with OpenBLAS v0.3.0, which should fix some of the linalg +problems reported for NumPy 1.14. + +Compatibility Note +================== + +The NumPy 1.15.x OS X wheels released on PyPI no longer contain 32-bit +binaries. That will also be the case in future releases. See +`#11625 <https://github.com/numpy/numpy/issues/11625>`__ for the related +discussion. Those needing 32-bit support should look elsewhere or build +from source. + +Contributors +============ + +A total of 4 people contributed to this release. People with a "+" by their +names contributed a patch for the first time. + +* Charles Harris +* Matti Picus +* Sebastian Berg +* bbbbbbbbba + + +Pull requests merged +==================== + +A total of 4 pull requests were merged for this release. + +* `#12296 <https://github.com/numpy/numpy/pull/12296>`__: BUG: Dealloc cached buffer info +* `#12297 <https://github.com/numpy/numpy/pull/12297>`__: BUG: Fix fill value in masked array '==' and '!=' ops. +* `#12307 <https://github.com/numpy/numpy/pull/12307>`__: DOC: Correct the default value of `optimize` in `numpy.einsum` +* `#12320 <https://github.com/numpy/numpy/pull/12320>`__: REL: Prepare for the NumPy 1.15.4 release diff --git a/doc/source/release.rst b/doc/source/release.rst index cfd77e853..28e9fd5be 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -2,6 +2,7 @@ Release Notes ************* +.. include:: ../release/1.15.4-notes.rst .. include:: ../release/1.15.3-notes.rst .. include:: ../release/1.15.2-notes.rst .. include:: ../release/1.15.1-notes.rst diff --git a/numpy/core/einsumfunc.py b/numpy/core/einsumfunc.py index df2bf4a4e..c22f2da42 100644 --- a/numpy/core/einsumfunc.py +++ b/numpy/core/einsumfunc.py @@ -1028,7 +1028,7 @@ def einsum(*operands, **kwargs): Controls if intermediate optimization should occur. No optimization will occur if False and True will default to the 'greedy' algorithm. Also accepts an explicit contraction list from the ``np.einsum_path`` - function. See ``np.einsum_path`` for more details. Default is True. + function. See ``np.einsum_path`` for more details. Defaults to False. Returns ------- diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index 41748c714..8ba3f5310 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -471,7 +471,7 @@ array_dealloc(PyArrayObject *self) { PyArrayObject_fields *fa = (PyArrayObject_fields *)self; - _array_dealloc_buffer_info(self); + _dealloc_cached_buffer_info((PyObject*)self); if (fa->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *)self); diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 1055f6adc..553737a3a 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -2,7 +2,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" - +#include <limits.h> +#include <assert.h> #define NPY_NO_DEPRECATED_API NPY_API_VERSION #define _MULTIARRAYMODULE @@ -34,8 +35,7 @@ #include "cblasfuncs.h" #include "npy_cblas.h" -#include <limits.h> -#include <assert.h> +#include "buffer.h" /* check for sequences, but ignore the types numpy considers scalars */ static NPY_INLINE npy_bool @@ -947,6 +947,7 @@ VOID_setitem(PyObject *op, void *input, void *vap) memset(ip + view.len, 0, itemsize - view.len); } PyBuffer_Release(&view); + _dealloc_cached_buffer_info(op); } #else { diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index c8e3da8bc..663930337 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -884,7 +884,7 @@ fail: */ NPY_NO_EXPORT void -_array_dealloc_buffer_info(PyArrayObject *self) +_dealloc_cached_buffer_info(PyObject *self) { int reset_error_state = 0; PyObject *ptype, *pvalue, *ptraceback; @@ -898,7 +898,7 @@ _array_dealloc_buffer_info(PyArrayObject *self) PyErr_Fetch(&ptype, &pvalue, &ptraceback); } - _buffer_clear_info((PyObject*)self); + _buffer_clear_info(self); if (reset_error_state) { PyErr_Restore(ptype, pvalue, ptraceback); diff --git a/numpy/core/src/multiarray/buffer.h b/numpy/core/src/multiarray/buffer.h index d5da8f440..fae413c85 100644 --- a/numpy/core/src/multiarray/buffer.h +++ b/numpy/core/src/multiarray/buffer.h @@ -4,7 +4,7 @@ extern NPY_NO_EXPORT PyBufferProcs array_as_buffer; NPY_NO_EXPORT void -_array_dealloc_buffer_info(PyArrayObject *self); +_dealloc_cached_buffer_info(PyObject *self); NPY_NO_EXPORT PyArray_Descr* _descriptor_from_pep3118_format(char *s); diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c index c70f8526e..c6f4847b3 100644 --- a/numpy/core/src/multiarray/common.c +++ b/numpy/core/src/multiarray/common.c @@ -311,6 +311,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); + _dealloc_cached_buffer_info(obj); if (dtype) { goto promote_types; } @@ -322,6 +323,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); + _dealloc_cached_buffer_info(obj); goto promote_types; } else { @@ -679,6 +681,14 @@ _IsWriteable(PyArrayObject *ap) return NPY_FALSE; } PyBuffer_Release(&view); + /* + * The first call to PyObject_GetBuffer stores a reference to a struct + * _buffer_info_t (from buffer.c, with format, ndim, strides and shape) in + * a static dictionary, with id(base) as the key. Usually we release it + * after the call to PyBuffer_Release, via a call to + * _dealloc_cached_buffer_info, but in this case leave it in the cache to + * speed up future calls to _IsWriteable. + */ #else if (PyObject_AsWriteBuffer(base, &dummy, &n) < 0) { PyErr_Clear(); diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c index 7e92e5991..cef3c27ed 100644 --- a/numpy/core/src/multiarray/conversion_utils.c +++ b/numpy/core/src/multiarray/conversion_utils.c @@ -16,6 +16,7 @@ #include "conversion_utils.h" #include "alloc.h" +#include "buffer.h" static int PyArray_PyIntAsInt_ErrMsg(PyObject *o, const char * msg) NPY_GCC_NONNULL(2); @@ -185,6 +186,7 @@ PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf) * sticks around after the release. */ PyBuffer_Release(&view); + _dealloc_cached_buffer_info(obj); /* Point to the base of the buffer object if present */ if (PyMemoryView_Check(obj)) { diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 28a414892..3c61f3b2b 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -744,12 +744,14 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it, d[i] = buffer_view.shape[i]; } PyBuffer_Release(&buffer_view); + _dealloc_cached_buffer_info(obj); return 0; } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { d[0] = buffer_view.len; *maxndim = 1; PyBuffer_Release(&buffer_view); + _dealloc_cached_buffer_info(obj); return 0; } else { @@ -2470,6 +2472,7 @@ PyArray_FromInterface(PyObject *origin) * sticks around after the release. */ PyBuffer_Release(&view); + _dealloc_cached_buffer_info(base); #else res = PyObject_AsWriteBuffer(base, (void **)&data, &buffer_len); if (res < 0) { @@ -3725,6 +3728,7 @@ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, * sticks around after the release. */ PyBuffer_Release(&view); + _dealloc_cached_buffer_info(buf); #else if (PyObject_AsWriteBuffer(buf, (void *)&data, &ts) == -1) { writeable = 0; diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index a0dc98f0e..e3a018356 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -19,6 +19,7 @@ #include "descriptor.h" #include "alloc.h" #include "assert.h" +#include "buffer.h" /* * offset: A starting offset. @@ -1764,6 +1765,7 @@ arraydescr_dealloc(PyArray_Descr *self) Py_INCREF(self); return; } + _dealloc_cached_buffer_info((PyObject*)self); Py_XDECREF(self->typeobj); Py_XDECREF(self->names); Py_XDECREF(self->fields); diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c index cae4273ff..24962da8a 100644 --- a/numpy/core/src/multiarray/getset.c +++ b/numpy/core/src/multiarray/getset.c @@ -20,6 +20,7 @@ #include "arrayobject.h" #include "mem_overlap.h" #include "alloc.h" +#include "buffer.h" /******************* array attribute get and set routines ******************/ @@ -143,6 +144,7 @@ array_strides_set(PyArrayObject *self, PyObject *obj) offset = PyArray_BYTES(self) - (char *)view.buf; numbytes = view.len + offset; PyBuffer_Release(&view); + _dealloc_cached_buffer_info((PyObject*)new); } #else if (PyArray_BASE(new) && @@ -376,6 +378,7 @@ array_data_set(PyArrayObject *self, PyObject *op) * sticks around after the release. */ PyBuffer_Release(&view); + _dealloc_cached_buffer_info(op); #else if (PyObject_AsWriteBuffer(op, &buf, &buf_len) < 0) { PyErr_Clear(); diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index a32aa47ab..0d7db2d8f 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -139,6 +139,7 @@ gentype_alloc(PyTypeObject *type, Py_ssize_t nitems) static void gentype_dealloc(PyObject *v) { + _dealloc_cached_buffer_info(v); Py_TYPE(v)->tp_free(v); } @@ -1863,6 +1864,7 @@ gentype_reduce(PyObject *self, PyObject *NPY_UNUSED(args)) * sticks around after the release. */ PyBuffer_Release(&view); + _dealloc_cached_buffer_info(self); } else { Py_DECREF(ret); diff --git a/numpy/ma/core.py b/numpy/ma/core.py index 52039bd97..a8cf02336 100644 --- a/numpy/ma/core.py +++ b/numpy/ma/core.py @@ -449,6 +449,7 @@ def _check_fill_value(fill_value, ndtype): If fill_value is not None, its value is forced to the given dtype. The result is always a 0d array. + """ ndtype = np.dtype(ndtype) fields = ndtype.fields @@ -468,17 +469,19 @@ def _check_fill_value(fill_value, ndtype): dtype=ndtype) else: if isinstance(fill_value, basestring) and (ndtype.char not in 'OSVU'): + # Note this check doesn't work if fill_value is not a scalar err_msg = "Cannot set fill value of string with array of dtype %s" raise TypeError(err_msg % ndtype) else: # In case we want to convert 1e20 to int. + # Also in case of converting string arrays. try: fill_value = np.array(fill_value, copy=False, dtype=ndtype) - except OverflowError: - # Raise TypeError instead of OverflowError. OverflowError - # is seldom used, and the real problem here is that the - # passed fill_value is not compatible with the ndtype. - err_msg = "Fill value %s overflows dtype %s" + except (OverflowError, ValueError): + # Raise TypeError instead of OverflowError or ValueError. + # OverflowError is seldom used, and the real problem here is + # that the passed fill_value is not compatible with the ndtype. + err_msg = "Cannot convert fill_value %s to dtype %s" raise TypeError(err_msg % (fill_value, ndtype)) return np.array(fill_value) @@ -4017,6 +4020,16 @@ class MaskedArray(ndarray): check = check.view(type(self)) check._update_from(self) check._mask = mask + + # Cast fill value to bool_ if needed. If it cannot be cast, the + # default boolean fill value is used. + if check._fill_value is not None: + try: + fill = _check_fill_value(check._fill_value, np.bool_) + except (TypeError, ValueError): + fill = _check_fill_value(None, np.bool_) + check._fill_value = fill + return check def __eq__(self, other): diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py index e935b65e3..a39e7dd3d 100644 --- a/numpy/ma/tests/test_core.py +++ b/numpy/ma/tests/test_core.py @@ -60,6 +60,11 @@ suppress_copy_mask_on_assignment.filter( "setting an item on a masked array which has a shared mask will not copy") +# For parametrized numeric testing +num_dts = [np.dtype(dt_) for dt_ in '?bhilqBHILQefdgFD'] +num_ids = [dt_.char for dt_ in num_dts] + + class TestMaskedArray(object): # Base test class for MaskedArrays. @@ -1413,23 +1418,34 @@ class TestMaskedArrayArithmetic(object): # Test the equality of structured arrays ndtype = [('A', int), ('B', int)] a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype) + test = (a == a) assert_equal(test.data, [True, True]) assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + test = (a == a[0]) assert_equal(test.data, [True, False]) assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype) test = (a == b) assert_equal(test.data, [False, True]) assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + test = (a[0] == b) assert_equal(test.data, [False, False]) assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype) test = (a == b) assert_equal(test.data, [True, True]) assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + # complicated dtype, 2-dimensional array. ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])] a = array([[(1, (1, 1)), (2, (2, 2))], @@ -1439,28 +1455,40 @@ class TestMaskedArrayArithmetic(object): test = (a[0, 0] == a) assert_equal(test.data, [[True, False], [False, False]]) assert_equal(test.mask, [[False, False], [False, True]]) + assert_(test.fill_value == True) def test_ne_on_structured(self): # Test the equality of structured arrays ndtype = [('A', int), ('B', int)] a = array([(1, 1), (2, 2)], mask=[(0, 1), (0, 0)], dtype=ndtype) + test = (a != a) assert_equal(test.data, [False, False]) assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + test = (a != a[0]) assert_equal(test.data, [False, True]) assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + b = array([(1, 1), (2, 2)], mask=[(1, 0), (0, 0)], dtype=ndtype) test = (a != b) assert_equal(test.data, [True, False]) assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + test = (a[0] != b) assert_equal(test.data, [True, True]) assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + b = array([(1, 1), (2, 2)], mask=[(0, 1), (1, 0)], dtype=ndtype) test = (a != b) assert_equal(test.data, [False, False]) assert_equal(test.mask, [False, False]) + assert_(test.fill_value == True) + # complicated dtype, 2-dimensional array. ndtype = [('A', int), ('B', [('BA', int), ('BB', int)])] a = array([[(1, (1, 1)), (2, (2, 2))], @@ -1470,6 +1498,7 @@ class TestMaskedArrayArithmetic(object): test = (a[0, 0] != a) assert_equal(test.data, [[False, True], [True, True]]) assert_equal(test.mask, [[False, False], [False, True]]) + assert_(test.fill_value == True) def test_eq_ne_structured_extra(self): # ensure simple examples are symmetric and make sense. @@ -1505,6 +1534,120 @@ class TestMaskedArrayArithmetic(object): el_by_el = [m1[name] != m2[name] for name in dt.names] assert_equal(array(el_by_el, dtype=bool).any(), ne_expected) + @pytest.mark.parametrize('dt', ['S', 'U']) + @pytest.mark.parametrize('fill', [None, 'A']) + def test_eq_for_strings(self, dt, fill): + # Test the equality of structured arrays + a = array(['a', 'b'], dtype=dt, mask=[0, 1], fill_value=fill) + + test = (a == a) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a == a[0]) + assert_equal(test.data, [True, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array(['a', 'b'], dtype=dt, mask=[1, 0], fill_value=fill) + test = (a == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + # test = (a[0] == b) # doesn't work in Python2 + test = (b == a[0]) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + @pytest.mark.parametrize('dt', ['S', 'U']) + @pytest.mark.parametrize('fill', [None, 'A']) + def test_ne_for_strings(self, dt, fill): + # Test the equality of structured arrays + a = array(['a', 'b'], dtype=dt, mask=[0, 1], fill_value=fill) + + test = (a != a) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a != a[0]) + assert_equal(test.data, [False, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array(['a', 'b'], dtype=dt, mask=[1, 0], fill_value=fill) + test = (a != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + # test = (a[0] != b) # doesn't work in Python2 + test = (b != a[0]) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + @pytest.mark.parametrize('dt1', num_dts, ids=num_ids) + @pytest.mark.parametrize('dt2', num_dts, ids=num_ids) + @pytest.mark.parametrize('fill', [None, 1]) + def test_eq_for_numeric(self, dt1, dt2, fill): + # Test the equality of structured arrays + a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill) + + test = (a == a) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a == a[0]) + assert_equal(test.data, [True, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill) + test = (a == b) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + # test = (a[0] == b) # doesn't work in Python2 + test = (b == a[0]) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + + @pytest.mark.parametrize('dt1', num_dts, ids=num_ids) + @pytest.mark.parametrize('dt2', num_dts, ids=num_ids) + @pytest.mark.parametrize('fill', [None, 1]) + def test_ne_for_numeric(self, dt1, dt2, fill): + # Test the equality of structured arrays + a = array([0, 1], dtype=dt1, mask=[0, 1], fill_value=fill) + + test = (a != a) + assert_equal(test.data, [False, False]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + test = (a != a[0]) + assert_equal(test.data, [False, True]) + assert_equal(test.mask, [False, True]) + assert_(test.fill_value == True) + + b = array([0, 1], dtype=dt2, mask=[1, 0], fill_value=fill) + test = (a != b) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, True]) + assert_(test.fill_value == True) + + # test = (a[0] != b) # doesn't work in Python2 + test = (b != a[0]) + assert_equal(test.data, [True, True]) + assert_equal(test.mask, [True, False]) + assert_(test.fill_value == True) + def test_eq_with_None(self): # Really, comparisons with None should not be done, but check them # anyway. Note that pep8 will flag these tests. @@ -5019,11 +5162,8 @@ def test_astype_mask_ordering(): assert_(x_f2.mask.flags.f_contiguous) -dts = [np.dtype(dt_) for dt_ in '?bhilqBHILQefdgFD'] -ids = [dt_.char for dt_ in dts] - -@pytest.mark.parametrize('dt1', dts, ids=ids) -@pytest.mark.parametrize('dt2', dts, ids=ids) +@pytest.mark.parametrize('dt1', num_dts, ids=num_ids) +@pytest.mark.parametrize('dt2', num_dts, ids=num_ids) @pytest.mark.filterwarnings('ignore::numpy.ComplexWarning') def test_astype_basic(dt1, dt2): # See gh-12070 diff --git a/pavement.py b/pavement.py index c9a8f8f00..d0818e66b 100644 --- a/pavement.py +++ b/pavement.py @@ -95,10 +95,10 @@ finally: #----------------------------------- # Source of the release notes -RELEASE_NOTES = 'doc/release/1.15.3-notes.rst' +RELEASE_NOTES = 'doc/release/1.15.4-notes.rst' # Start/end of the log (from git) -LOG_START = 'v1.15.2' +LOG_START = 'v1.15.3' LOG_END = 'maintenance/1.15.x' @@ -64,7 +64,7 @@ Operating System :: MacOS MAJOR = 1 MINOR = 15 -MICRO = 3 +MICRO = 4 ISRELEASED = True VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO) |