[Python-modules-commits] [python-numpy] 01/12: Import python-numpy_1.11.0.orig.tar.gz

Sandro Tosi morph at moszumanska.debian.org
Sat Apr 9 09:25:07 UTC 2016


This is an automated email from the git hooks/post-receive script.

morph pushed a commit to branch master
in repository python-numpy.

commit 75d207b85a26d557d79cb3aab0b1d8cbb18c8f1e
Author: Sandro Tosi <morph at debian.org>
Date:   Fri Apr 8 21:20:03 2016 +0100

    Import python-numpy_1.11.0.orig.tar.gz
---
 PKG-INFO                                       |    2 +-
 doc/release/1.11.0-notes.rst                   |   88 +-
 numpy/core/code_generators/ufunc_docstrings.py |   18 +-
 numpy/core/include/numpy/halffloat.h           |    1 +
 numpy/core/include/numpy/npy_math.h            |    4 +
 numpy/core/setup.py                            |    2 +
 numpy/core/src/multiarray/common.c             |   59 +-
 numpy/core/src/multiarray/conversion_utils.c   |  109 +-
 numpy/core/src/multiarray/ctors.c              |    5 -
 numpy/core/src/multiarray/mapping.c            |  138 +-
 numpy/core/src/multiarray/number.c             |   21 +-
 numpy/core/src/npymath/halffloat.c             |   11 +
 numpy/core/src/npymath/npy_math.c.src          |   48 +
 numpy/core/src/umath/loops.c.src               |   30 +-
 numpy/core/src/umath/scalarmath.c.src          |  101 +-
 numpy/core/src/umath/simd.inc.src              |  166 +-
 numpy/core/src/umath/ufunc_object.c            |   17 +-
 numpy/core/tests/test_deprecations.py          |  335 +
 numpy/core/tests/test_dtype.py                 |    4 +
 numpy/core/tests/test_indexing.py              |  243 +-
 numpy/core/tests/test_mem_overlap.py           |    4 +-
 numpy/core/tests/test_multiarray.py            |   64 +-
 numpy/core/tests/test_numeric.py               |   32 -
 numpy/core/tests/test_scalarmath.py            |   81 +-
 numpy/core/tests/test_ufunc.py                 |   16 +
 numpy/core/tests/test_umath.py                 |   97 +
 numpy/lib/function_base.py                     |  513 +-
 numpy/lib/tests/test_function_base.py          |  142 +-
 numpy/ma/core.py                               |   48 +-
 numpy/ma/extras.py                             |    6 +-
 numpy/ma/tests/test_subclassing.py             |   20 +
 numpy/random/mtrand/mtrand.c                   | 7801 +++++++++++++-----------
 numpy/random/mtrand/mtrand.pyx                 |   30 +-
 numpy/random/tests/test_random.py              |   36 +-
 numpy/version.py                               |    8 +-
 setup.py                                       |    2 +-
 36 files changed, 5762 insertions(+), 4540 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index ce28900..34df102 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: numpy
-Version: 1.11.0b3
+Version: 1.11.0
 Summary: NumPy: array processing for numbers, strings, records, and objects.
 Home-page: http://www.numpy.org
 Author: NumPy Developers
diff --git a/doc/release/1.11.0-notes.rst b/doc/release/1.11.0-notes.rst
index aa11cdf..dad5260 100644
--- a/doc/release/1.11.0-notes.rst
+++ b/doc/release/1.11.0-notes.rst
@@ -41,14 +41,21 @@ Future Changes
 The following changes are scheduled for Numpy 1.12.0.
 
 * Support for Python 2.6, 3.2, and 3.3 will be dropped.
-* Slicing a ``MaskedArray`` will return views of both data **and** mask.
-  Currently the mask is returned as a copy.
 * Relaxed stride checking will become the default. See the 1.8.0 release
   notes for a more extended discussion of what this change implies.
 * The behavior of the datetime64 "not a time" (NaT) value will be changed
   to match that of floating point "not a number" (NaN) values: all
   comparisons involving NaT will return False, except for NaT != NaT which
   will return True.
+* Indexing with floats will raise IndexError,
+  e.g., a[0, 0.0].
+* Indexing with non-integer array_like will raise ``IndexError``,
+  e.g., ``a['1', '2']``
+* Indexing with multiple ellipsis will raise ``IndexError``,
+  e.g., ``a[..., ...]``.
+* Non-integers used as index values will raise ``TypeError``,
+  e.g., in ``reshape``, ``take``, and specifying reduce axis.
+
 
 In a future release the following changes will be made.
 
@@ -61,6 +68,10 @@ In a future release the following changes will be made.
   change.  That differs from the current behavior where arrays that are
   f_contiguous but not c_contiguous can be viewed as a dtype type of
   different size causing the first dimension to change.
+* Slicing a ``MaskedArray`` will return views of both data **and** mask.
+  Currently the mask is copy-on-write and changes to the mask in the slice do
+  not propagate to the original mask. See the FutureWarnings section below for
+  details.
 
 
 Compatibility notes
@@ -117,21 +128,6 @@ arguments cannot be cast to a common type, it could have raised a ``TypeError``
 or ``ValueError`` depending on their order. Now, ``np.dot`` will now always
 raise a ``TypeError``.
 
-DeprecationWarning to error
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-* Indexing with floats raises IndexError,
-  e.g., a[0, 0.0].
-* Indexing with non-integer array_like raises ``IndexError``,
-  e.g., ``a['1', '2']``
-* Indexing with multiple ellipsis raises ``IndexError``,
-  e.g., ``a[..., ...]``.
-* Indexing with boolean where integer expected raises ``IndexError``,
-  e.g., ``a[False:True:True]``.
-* Non-integers used as index values raise ``TypeError``,
-  e.g., in ``reshape``, ``take``, and specifying reduce axis.
-
-
 FutureWarning to changed behavior
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -142,6 +138,18 @@ FutureWarning to changed behavior
   due to a bug, sometimes no warning was raised and the dimensions were
   already preserved.
 
+``%`` and ``//`` operators
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+These operators are implemented with the ``remainder`` and ``floor_divide``
+functions respectively. Those functions are now based around ``fmod`` and are
+computed together so as to be compatible with each other and with the Python
+versions for float types.  The results should be marginally more accurate or
+outright bug fixes compared to the previous results, but they may
+differ significantly in cases where roundoff makes a difference in the integer
+returned by ``floor_divide``. Some corner cases also change, for instance, NaN
+is always returned for both functions when the divisor is zero,
+``divmod(1.0, inf)`` returns ``(0.0, 1.0)`` except on MSVC 2008, and
+``divmod(-1.0, inf)`` returns ``(-1.0, inf)``.
 
 C API
 ~~~~~
@@ -153,13 +161,23 @@ it's unlikely that any third-party code is using them either, but we
 mention it here for completeness.
 
 
+object dtype detection for old-style classes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In python 2, objects which are instances of old-style user-defined classes no
+longer automatically count as 'object' type in the dtype-detection handler.
+Instead, as in python 3, they may potentially count as sequences, but only if
+they define both a `__len__` and a `__getitem__` method. This fixes a segfault
+and inconsistency between python 2 and 3.
+
 New Features
 ============
 
 * ``np.histogram`` now provides plugin estimators for automatically
   estimating the optimal number of bins. Passing one of ['auto', 'fd',
-  'scott', 'rice', 'sturges'] as the argument to 'bins' results in the
-  corresponding estimator being used.
+  'scott', 'rice', 'sturges', 'doane', 'sqrt'] as the argument to
+  'bins' results in the corresponding estimator being used. These
+   estimators work correctly with the `range` parameter.
 
 * A benchmark suite using `Airspeed Velocity
   <http://spacetelescope.github.io/asv/>`__ has been added, converting the
@@ -207,6 +225,9 @@ New Features
   The change is backward compatible, passing a scalar ``deg`` will behave
   as before.
 
+* A divmod function for float types modeled after the Python version has
+  been added to the npy_math library.
+
 
 Improvements
 ============
@@ -341,3 +362,32 @@ interval over the closed one, ``np.random.random_integers`` is being
 deprecated in favor of calling ``np.random.randint``, which has been
 enhanced with the ``dtype`` parameter as described under "New Features".
 However, ``np.random.random_integers`` will not be removed anytime soon.
+
+
+FutureWarnings
+==============
+
+Assigning to slices/views of ``MaskedArray``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Currently a slice of a masked array contains a view of the original data and a
+copy-on-write view of the mask. Consequently, any changes to the slice's mask
+will result in a copy of the original mask being made and that new mask being
+changed rather than the original. For example, if we make a slice of the
+original like so, ``view = original[:]``, then modifications to the data in one
+array will affect the data of the other but, because the mask will be copied
+during assignment operations, changes to the mask will remain local. A similar
+situation occurs when explicitly constructing a masked array using
+``MaskedArray(data, mask)``, the returned array will contain a view of ``data``
+but the mask will be a copy-on-write view of ``mask``.
+
+In the future, these cases will be normalized so that the data and mask arrays
+are treated the same way and modifications to either will propagate between
+views. In 1.11, numpy will issue a ``MaskedArrayFutureWarning`` warning
+whenever user code modifies the mask of a view that in the future may cause
+values to propagate back to the original.  To silence these warnings and make
+your code robust against the upcoming changes, you have two options: if you
+want to keep the current behavior, call ``masked_view.unshare_mask()`` before
+modifying the mask.  If you want to get the future behavior early, use
+``masked_view._sharedmask = False``. However, note that setting the
+``_sharedmask`` attribute will break following explicit calls to
+``masked_view.unshare_mask()``.
diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py
index 34ac599..8ebe63e 100644
--- a/numpy/core/code_generators/ufunc_docstrings.py
+++ b/numpy/core/code_generators/ufunc_docstrings.py
@@ -1225,8 +1225,10 @@ add_newdoc('numpy.core.umath', 'floor',
 
 add_newdoc('numpy.core.umath', 'floor_divide',
     """
-    Return the largest integer smaller or equal to the division of the
-    inputs.
+    Return the largest integer smaller or equal to the division of the inputs.
+    It is equivalent to the Python ``//`` operator and pairs with the
+    Python ``%`` (`remainder`), function so that ``b = a % b + b * (a // b)``
+    up to roundoff.
 
     Parameters
     ----------
@@ -1243,6 +1245,7 @@ add_newdoc('numpy.core.umath', 'floor_divide',
 
     See Also
     --------
+    remainder : Remainder complementary to floor_divide.
     divide : Standard division.
     floor : Round a number to the nearest integer toward minus infinity.
     ceil : Round a number to the nearest integer toward infinity.
@@ -2689,9 +2692,9 @@ add_newdoc('numpy.core.umath', 'remainder',
     """
     Return element-wise remainder of division.
 
-    Computes ``x1 - floor(x1 / x2) * x2``, the result has the same sign as
-    the divisor `x2`. It is equivalent to the Python modulus operator
-    ``x1 % x2`` and should not be confused with the Matlab(TM) ``rem``
+    Computes the remainder complementary to the `floor_divide` function.  It is
+    equivalent to the Python modulus operator``x1 % x2`` and has the same sign
+    as the divisor `x2`. It should not be confused with the Matlab(TM) ``rem``
     function.
 
     Parameters
@@ -2707,11 +2710,12 @@ add_newdoc('numpy.core.umath', 'remainder',
     Returns
     -------
     y : ndarray
-        The remainder of the quotient ``x1/x2``, element-wise. Returns a
-        scalar if both  `x1` and `x2` are scalars.
+        The element-wise remainder of the quotient ``floor_divide(x1, x2)``.
+        Returns a scalar if both  `x1` and `x2` are scalars.
 
     See Also
     --------
+    floor_divide : Equivalent of Python ``//`` operator.
     fmod : Equivalent of the Matlab(TM) ``rem`` function.
     divide, floor
 
diff --git a/numpy/core/include/numpy/halffloat.h b/numpy/core/include/numpy/halffloat.h
index 944f0ea..ab0d221 100644
--- a/numpy/core/include/numpy/halffloat.h
+++ b/numpy/core/include/numpy/halffloat.h
@@ -37,6 +37,7 @@ int npy_half_signbit(npy_half h);
 npy_half npy_half_copysign(npy_half x, npy_half y);
 npy_half npy_half_spacing(npy_half h);
 npy_half npy_half_nextafter(npy_half x, npy_half y);
+npy_half npy_half_divmod(npy_half x, npy_half y, npy_half *modulus);
 
 /*
  * Half-precision constants
diff --git a/numpy/core/include/numpy/npy_math.h b/numpy/core/include/numpy/npy_math.h
index 3dae583..e76508d 100644
--- a/numpy/core/include/numpy/npy_math.h
+++ b/numpy/core/include/numpy/npy_math.h
@@ -309,16 +309,20 @@ double npy_deg2rad(double x);
 double npy_rad2deg(double x);
 double npy_logaddexp(double x, double y);
 double npy_logaddexp2(double x, double y);
+double npy_divmod(double x, double y, double *modulus);
 
 float npy_deg2radf(float x);
 float npy_rad2degf(float x);
 float npy_logaddexpf(float x, float y);
 float npy_logaddexp2f(float x, float y);
+float npy_divmodf(float x, float y, float *modulus);
 
 npy_longdouble npy_deg2radl(npy_longdouble x);
 npy_longdouble npy_rad2degl(npy_longdouble x);
 npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
 npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_divmodl(npy_longdouble x, npy_longdouble y,
+                           npy_longdouble *modulus);
 
 #define npy_degrees npy_rad2deg
 #define npy_degreesf npy_rad2degf
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 59eaf24..3c3d160 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -896,6 +896,8 @@ def configuration(parent_package='',top_path=None):
 
     umath_deps = [
             generate_umath_py,
+            join('include', 'numpy', 'npy_math.h'),
+            join('include', 'numpy', 'halffloat.h'),
             join('src', 'multiarray', 'common.h'),
             join('src', 'private', 'templ_common.h.src'),
             join('src', 'umath', 'simd.inc.src'),
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 1948b8b..bd566b7 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -128,30 +128,6 @@ _array_find_python_scalar_type(PyObject *op)
     return NULL;
 }
 
-#if !defined(NPY_PY3K)
-static PyArray_Descr *
-_use_default_type(PyObject *op)
-{
-    int typenum, l;
-    PyObject *type;
-
-    typenum = -1;
-    l = 0;
-    type = (PyObject *)Py_TYPE(op);
-    while (l < NPY_NUMUSERTYPES) {
-        if (type == (PyObject *)(userdescrs[l]->typeobj)) {
-            typenum = l + NPY_USERDEF;
-            break;
-        }
-        l++;
-    }
-    if (typenum == -1) {
-        typenum = NPY_OBJECT;
-    }
-    return PyArray_DescrFromType(typenum);
-}
-#endif
-
 /*
  * These constants are used to signal that the recursive dtype determination in
  * PyArray_DTypeFromObject encountered a string type, and that the recursive
@@ -490,24 +466,19 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
         }
     }
 
-    /* Not exactly sure what this is about... */
-#if !defined(NPY_PY3K)
-    if (PyInstance_Check(obj)) {
-        dtype = _use_default_type(obj);
-        if (dtype == NULL) {
-            goto fail;
-        }
-        else {
-            goto promote_types;
-        }
-    }
-#endif
-
     /*
      * If we reached the maximum recursion depth without hitting one
-     * of the above cases, the output dtype should be OBJECT
+     * of the above cases, and obj isn't a sequence-like object, the output
+     * dtype should be either OBJECT or a user-defined type.
+     *
+     * Note that some libraries define sequence-like classes but want them to
+     * be treated as objects, and they expect numpy to treat it as an object if
+     * __len__ is not defined.
      */
-    if (maxdims == 0 || !PySequence_Check(obj)) {
+    if (maxdims == 0 || !PySequence_Check(obj) || PySequence_Size(obj) < 0) {
+        // clear any PySequence_Size error, which corrupts further calls to it
+        PyErr_Clear();
+
         if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) {
             Py_XDECREF(*out_dtype);
             *out_dtype = PyArray_DescrFromType(NPY_OBJECT);
@@ -518,20 +489,12 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
         return 0;
     }
 
-    /*
-     * fails if convertable to list but no len is defined which some libraries
-     * require to get object arrays
-     */
-    size = PySequence_Size(obj);
-    if (size < 0) {
-        goto fail;
-    }
-
     /* Recursive case, first check the sequence contains only one type */
     seq = PySequence_Fast(obj, "Could not convert object to sequence");
     if (seq == NULL) {
         goto fail;
     }
+    size = PySequence_Fast_GET_SIZE(seq);
     objects = PySequence_Fast_ITEMS(seq);
     common_type = size > 0 ? Py_TYPE(objects[0]) : NULL;
     for (i = 1; i < size; ++i) {
diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c
index d7a6178..8ef6f2c 100644
--- a/numpy/core/src/multiarray/conversion_utils.c
+++ b/numpy/core/src/multiarray/conversion_utils.c
@@ -4,12 +4,14 @@
 
 #define NPY_NO_DEPRECATED_API NPY_API_VERSION
 #define _MULTIARRAYMODULE
+
 #include "numpy/arrayobject.h"
 #include "numpy/arrayscalars.h"
 #include "numpy/arrayobject.h"
 
 #include "npy_config.h"
 #include "npy_pycompat.h"
+#include "npy_import.h"
 
 #include "common.h"
 #include "arraytypes.h"
@@ -797,17 +799,28 @@ PyArray_PyIntAsIntp_ErrMsg(PyObject *o, const char * msg)
     long long_value = -1;
 #endif
     PyObject *obj, *err;
+    static PyObject *VisibleDeprecation = NULL;
 
-    /*
-     * Be a bit stricter and not allow bools.
-     * np.bool_ is also disallowed as Boolean arrays do not currently
-     * support index.
-     */
-    if (!o || PyBool_Check(o) || PyArray_IsScalar(o, Bool)) {
+    npy_cache_import(
+        "numpy", "VisibleDeprecationWarning", &VisibleDeprecation);
+
+    if (!o) {
         PyErr_SetString(PyExc_TypeError, msg);
         return -1;
     }
 
+    /* Be a bit stricter and not allow bools, np.bool_ is handled later */
+    if (PyBool_Check(o)) {
+        /* 2013-04-13, 1.8 */
+        if (PyErr_WarnEx(
+                VisibleDeprecation,
+                "using a boolean instead of an integer"
+                " will result in an error in the future",
+                1) < 0) {
+            return -1;
+        }
+    }
+
     /*
      * Since it is the usual case, first check if o is an integer. This is
      * an exact check, since otherwise __index__ is used.
@@ -833,22 +846,90 @@ PyArray_PyIntAsIntp_ErrMsg(PyObject *o, const char * msg)
         return (npy_intp)long_value;
     }
 
+    /* Disallow numpy.bool_. Boolean arrays do not currently support index. */
+    if (PyArray_IsScalar(o, Bool)) {
+        /* 2013-06-09, 1.8 */
+        if (PyErr_WarnEx(
+                VisibleDeprecation,
+                "using a boolean instead of an integer"
+                " will result in an error in the future",
+                1) < 0) {
+            return -1;
+        }
+    }
+
     /*
      * The most general case. PyNumber_Index(o) covers everything
      * including arrays. In principle it may be possible to replace
      * the whole function by PyIndex_AsSSize_t after deprecation.
      */
     obj = PyNumber_Index(o);
-    if (obj == NULL) {
-        return -1;
-    }
+    if (obj) {
 #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP)
-    long_value = PyLong_AsLongLong(obj);
+        long_value = PyLong_AsLongLong(obj);
 #else
-    long_value = PyLong_AsLong(obj);
+        long_value = PyLong_AsLong(obj);
+#endif
+        Py_DECREF(obj);
+        goto finish;
+    }
+    else {
+        /*
+         * Set the TypeError like PyNumber_Index(o) would after trying
+         * the general case.
+         */
+        PyErr_Clear();
+    }
+
+    /*
+     * For backward compatibility check the number C-Api number protcol
+     * This should be removed up the finish label after deprecation.
+     */
+    if (Py_TYPE(o)->tp_as_number != NULL &&
+        Py_TYPE(o)->tp_as_number->nb_int != NULL) {
+        obj = Py_TYPE(o)->tp_as_number->nb_int(o);
+        if (obj == NULL) {
+            return -1;
+        }
+ #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP)
+        long_value = PyLong_AsLongLong(obj);
+ #else
+        long_value = PyLong_AsLong(obj);
+ #endif
+        Py_DECREF(obj);
+    }
+#if !defined(NPY_PY3K)
+    else if (Py_TYPE(o)->tp_as_number != NULL &&
+             Py_TYPE(o)->tp_as_number->nb_long != NULL) {
+        obj = Py_TYPE(o)->tp_as_number->nb_long(o);
+        if (obj == NULL) {
+            return -1;
+        }
+  #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP)
+        long_value = PyLong_AsLongLong(obj);
+  #else
+        long_value = PyLong_AsLong(obj);
+  #endif
+        Py_DECREF(obj);
+    }
 #endif
-    Py_DECREF(obj);
+    else {
+        PyErr_SetString(PyExc_TypeError, msg);
+        return -1;
+    }
+    /* Give a deprecation warning, unless there was already an error */
+    if (!error_converting(long_value)) {
+        /* 2013-04-13, 1.8 */
+        if (PyErr_WarnEx(
+                VisibleDeprecation,
+                "using a non-integer number instead of an integer"
+                " will result in an error in the future",
+                1) < 0) {
+            return -1;
+        }
+    }
 
+ finish:
     if (error_converting(long_value)) {
         err = PyErr_Occurred();
         /* Only replace TypeError's here, which are the normal errors. */
@@ -857,9 +938,9 @@ PyArray_PyIntAsIntp_ErrMsg(PyObject *o, const char * msg)
         }
         return -1;
     }
-    goto overflow_check; /* silence unused warning */
 
-overflow_check:
+    goto overflow_check; /* silence unused warning */
+ overflow_check:
 #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP)
   #if (NPY_SIZEOF_LONGLONG > NPY_SIZEOF_INTP)
     if ((long_value < NPY_MIN_INTP) || (long_value > NPY_MAX_INTP)) {
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 7fb86a1..46753ac 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -695,11 +695,6 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it,
 
     /* obj is not a Sequence */
     if (!PySequence_Check(obj) ||
-#if defined(NPY_PY3K)
-        /* FIXME: XXX -- what is the correct thing to do here? */
-#else
-            PyInstance_Check(obj) ||
-#endif
             PySequence_Length(obj) < 0) {
         *maxndim = 0;
         PyErr_Clear();
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index 6c56d77..178740f 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -178,6 +178,10 @@ prepare_index(PyArrayObject *self, PyObject *index,
 
     int index_type = 0;
     int ellipsis_pos = -1;
+    static PyObject *VisibleDeprecation = NULL;
+
+    npy_cache_import(
+        "numpy", "VisibleDeprecationWarning", &VisibleDeprecation);
 
     /*
      * The index might be a multi-dimensional index, but not yet a tuple
@@ -286,13 +290,37 @@ prepare_index(PyArrayObject *self, PyObject *index,
 
         /* Index is an ellipsis (`...`) */
         if (obj == Py_Ellipsis) {
-            /* At most one ellipsis in an index */
+            /*
+             * If there is more then one Ellipsis, it is replaced. Deprecated,
+             * since it is hard to imagine anyone using two Ellipsis and
+             * actually planning on all but the first being automatically
+             * replaced with a slice.
+             */
             if (index_type & HAS_ELLIPSIS) {
-                PyErr_Format(PyExc_IndexError,
-                    "an index can only have a single ellipsis ('...')");
-                goto failed_building_indices;
+                /* 2013-04-14, 1.8 */
+                if (PyErr_WarnEx(
+                        VisibleDeprecation,
+                        "an index can only have a single Ellipsis (`...`); "
+                        "replace all but one with slices (`:`).",
+                        1) < 0) {
+                    goto failed_building_indices;
+                }
+                index_type |= HAS_SLICE;
+
+                indices[curr_idx].type = HAS_SLICE;
+                indices[curr_idx].object = PySlice_New(NULL, NULL, NULL);
+
+                if (indices[curr_idx].object == NULL) {
+                    goto failed_building_indices;
+                }
+
+                used_ndim += 1;
+                new_ndim += 1;
+                curr_idx += 1;
+                continue;
             }
             index_type |= HAS_ELLIPSIS;
+
             indices[curr_idx].type = HAS_ELLIPSIS;
             indices[curr_idx].object = NULL;
             /* number of slices it is worth, won't update if it is 0: */
@@ -395,9 +423,107 @@ prepare_index(PyArrayObject *self, PyObject *index,
                     goto failed_building_indices;
                 }
             }
-            else {
+            /*
+             * Special case to allow 0-d boolean indexing with
+             * scalars. Should be removed after boolean-array
+             * like as integer-array like deprecation.
+             * (does not cover ufunc.at, because it does not use the
+             * boolean special case, but that should not matter...)
+             * Since all but strictly boolean indices are invalid,
+             * there is no need for any further conversion tries.
+             */
+            else if (PyArray_NDIM(self) == 0) {
                 arr = tmp_arr;
             }
+            else {
+                /*
+                 * These Checks can be removed after deprecation, since
+                 * they should then be either correct already or error out
+                 * later just like a normal array.
+                 */
+                if (PyArray_ISBOOL(tmp_arr)) {
+                    /* 2013-04-14, 1.8 */
+                    if (DEPRECATE_FUTUREWARNING(
+                            "in the future, boolean array-likes will be "
+                            "handled as a boolean array index") < 0) {
+                        Py_DECREF(tmp_arr);
+                        goto failed_building_indices;
+                    }
+                    if (PyArray_NDIM(tmp_arr) == 0) {
+                        /*
+                         * Need to raise an error here, since the
+                         * DeprecationWarning before was not triggered.
+                         * TODO: A `False` triggers a Deprecation *not* a
+                         *       a FutureWarning.
+                         */
+                        PyErr_SetString(PyExc_IndexError,
+                                "in the future, 0-d boolean arrays will be "
+                                "interpreted as a valid boolean index");
+                        Py_DECREF(tmp_arr);
+                        goto failed_building_indices;
+                    }
+                    else {
+                        arr = tmp_arr;
+                    }
+                }
+                /*
+                 * Note: Down the road, the integers will be cast to intp.
+                 *       The user has to make sure they can be safely cast.
+                 *       If not, we might index wrong instead of an giving
+                 *       an error.
+                 */
+                else if (!PyArray_ISINTEGER(tmp_arr)) {
+                    if (PyArray_NDIM(tmp_arr) == 0) {
+                        /* match integer deprecation warning */
+                        /* 2013-09-25, 1.8 */
+                        if (PyErr_WarnEx(
+                                VisibleDeprecation,
+                                "using a non-integer number instead of an "
+                                "integer will result in an error in the "
+                                "future",
+                                1) < 0) {
+
+                            /* The error message raised in the future */
+                            PyErr_SetString(PyExc_IndexError,
+                                "only integers, slices (`:`), ellipsis (`...`), "
+                                "numpy.newaxis (`None`) and integer or boolean "
+                                "arrays are valid indices");
+                            Py_DECREF((PyObject *)tmp_arr);
+                            goto failed_building_indices;
+                        }
+                    }
+                    else {
+                        /* 2013-09-25, 1.8 */
+                        if (PyErr_WarnEx(
+                                VisibleDeprecation,
+                                "non integer (and non boolean) array-likes "
+                                "will not be accepted as indices in the "
+                                "future",
+                                1) < 0) {
+
+                            /* Error message to be raised in the future */
+                            PyErr_SetString(PyExc_IndexError,
+                                "non integer (and non boolean) array-likes will "
+                                "not be accepted as indices in the future");
+                            Py_DECREF((PyObject *)tmp_arr);
+                            goto failed_building_indices;
+                        }
+                    }
+                }
+
+                arr = (PyArrayObject *)PyArray_FromArray(tmp_arr,
+                                            PyArray_DescrFromType(NPY_INTP),
+                                            NPY_ARRAY_FORCECAST);
+
+                if (arr == NULL) {
+                    /* Since this will be removed, handle this later */
+                    PyErr_Clear();
+                    arr = tmp_arr;
+                }
+                else {
+                    Py_DECREF((PyObject *)tmp_arr);
+                }
+            }
         }
         else {
             Py_INCREF(obj);
@@ -662,7 +788,7 @@ prepare_index(PyArrayObject *self, PyObject *index,
         for (i = 0; i < curr_idx; i++) {
             if ((indices[i].type == HAS_FANCY) && indices[i].value > 0) {
                 if (indices[i].value != PyArray_DIM(self, used_ndim)) {
-                    static PyObject *warning;
+                    static PyObject *warning = NULL;
 
                     char err_msg[174];
                     PyOS_snprintf(err_msg, sizeof(err_msg),
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index fec015a..b85521f 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -1025,11 +1025,26 @@ _array_copy_nice(PyArrayObject *self)
 static PyObject *
 array_index(PyArrayObject *v)
 {
-    if (!PyArray_ISINTEGER(v) || PyArray_NDIM(v) != 0) {
-        PyErr_SetString(PyExc_TypeError,
-            "only integer scalar arrays can be converted to a scalar index");
+    static PyObject *VisibleDeprecation = NULL;
+
+    npy_cache_import(
+        "numpy", "VisibleDeprecationWarning", &VisibleDeprecation);
+
+    if (!PyArray_ISINTEGER(v) || PyArray_SIZE(v) != 1) {
+        PyErr_SetString(PyExc_TypeError, "only integer arrays with "     \
+                        "one element can be converted to an index");
         return NULL;
     }
+    if (PyArray_NDIM(v) != 0) {
+        /* 2013-04-20, 1.8 */
+        if (PyErr_WarnEx(
+                VisibleDeprecation,
+                "converting an array with ndim > 0 to an index"
+                " will result in an error in the future",
+                1) < 0) {
+            return NULL;
+        }
+    }
     return PyArray_DESCR(v)->f->getitem(PyArray_DATA(v), v);
 }
 
diff --git a/numpy/core/src/npymath/halffloat.c b/numpy/core/src/npymath/halffloat.c
index 34ac642..9517682 100644
--- a/numpy/core/src/npymath/halffloat.c
+++ b/numpy/core/src/npymath/halffloat.c
@@ -224,6 +224,17 @@ int npy_half_ge(npy_half h1, npy_half h2)
     return npy_half_le(h2, h1);
 }
 
+npy_half npy_half_divmod(npy_half h1, npy_half h2, npy_half *modulus)
+{
+    float fh1 = npy_half_to_float(h1);
+    float fh2 = npy_half_to_float(h2);
+    float div, mod;
+
+    div = npy_divmodf(fh1, fh2, &mod);
+    *modulus = npy_float_to_half(mod);
+    return npy_float_to_half(div);
+}
+
 
 
 /*
diff --git a/numpy/core/src/npymath/npy_math.c.src b/numpy/core/src/npymath/npy_math.c.src
index 4dcb019..45b618a 100644
--- a/numpy/core/src/npymath/npy_math.c.src
+++ b/numpy/core/src/npymath/npy_math.c.src
@@ -608,6 +608,54 @@ double npy_log2(double x)
     }
 }
 
+/*
+ * Python version of divmod.
+ *
+ * The implementation is mostly copied from cpython 3.5.
+ */
+ at type@
+npy_divmod at c@(@type@ a, @type@ b, @type@ *modulus)
+{
+    @type@ div, mod, floordiv;
+
+    mod = npy_fmod at c@(a, b);
+
+    if (!b) {
+        /* If b == 0, return result of fmod. For IEEE is nan */
+        *modulus = mod;
+        return mod;
+    }
+
+    /* a - mod should be very nearly an integer multiple of b */
+    div = (a - mod) / b;
+
+    /* adjust fmod result to conform to Python convention of remainder */
+    if (mod) {
+        if ((b < 0) != (mod < 0)) {
+            mod += b;
+            div -= 1.0 at c@;
+        }
+    }
+    else {
+        /* if mod is zero ensure correct sign */
+        mod = (b > 0) ? 0.0 at c@ : -0.0 at c@;
+    }
+
+    /* snap quotient to nearest integral value */
+    if (div) {
+        floordiv = npy_floor(div);
+        if (div - floordiv > 0.5 at c@)
+            floordiv += 1.0 at c@;
+    }
+    else {
+        /* if div is zero ensure correct sign */
+        floordiv = (a / b > 0) ?  0.0 at c@ : -0.0 at c@;
+    }
+
+    *modulus = mod;
+    return floordiv;
+}
+
 #undef LOGE2
 #undef LOG2E
 #undef RAD2DEG
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src
index 7b8dcdb..ab74600 100644
--- a/numpy/core/src/umath/loops.c.src
+++ b/numpy/core/src/umath/loops.c.src
@@ -1596,11 +1596,14 @@ NPY_NO_EXPORT void
 /**begin repeat1
  * #kind = isnan, isinf, isfinite, signbit#
  * #func = npy_isnan, npy_isinf, npy_isfinite, npy_signbit#
+ * #isnan = 1, 0*3#
  **/
 NPY_NO_EXPORT void
 @TYPE at _@kind@(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
 {
-    if (!run_ at kind@_simd_ at TYPE@(args, dimensions, steps)) {
+    char * margs[] = {args[0], args[0], args[1]};
+    npy_intp msteps[] = {steps[0], steps[0], steps[1]};
+    if (!@isnan@ || !run_binary_simd_not_equal_ at TYPE@(margs, dimensions, msteps)) {
         UNARY_LOOP {
             const @type@ in1 = *(@type@ *)ip1;
             *((npy_bool *)op1) = @func@(in1) != 0;
@@ -1696,7 +1699,8 @@ NPY_NO_EXPORT void
     BINARY_LOOP {
         const @type@ in1 = *(@type@ *)ip1;
         const @type@ in2 = *(@type@ *)ip2;
-        *((@type@ *)op1) = npy_floor at c@(in1/in2);
+        @type@ mod;
+        *((@type@ *)op1) = npy_divmod at c@(in1, in2, &mod);
     }
 }
 
@@ -1706,8 +1710,7 @@ NPY_NO_EXPORT void
     BINARY_LOOP {
         const @type@ in1 = *(@type@ *)ip1;
         const @type@ in2 = *(@type@ *)ip2;
-        const @type@ div = in1/in2;
-        *((@type@ *)op1) = in2*(div - npy_floor at c@(div));
+        npy_divmod at c@(in1, in2, (@type@ *)op1);
     }
 }
 
@@ -2011,9 +2014,10 @@ NPY_NO_EXPORT void
 HALF_floor_divide(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
 {
     BINARY_LOOP {
-        const float in1 = npy_half_to_float(*(npy_half *)ip1);
-        const float in2 = npy_half_to_float(*(npy_half *)ip2);
-        *((npy_half *)op1) = npy_float_to_half(npy_floorf(in1/in2));
+        const npy_half in1 = *(npy_half *)ip1;
+        const npy_half in2 = *(npy_half *)ip2;
+        npy_half mod;
+        *((npy_half *)op1) = npy_half_divmod(in1, in2, &mod);
     }
 }
 
@@ -2021,15 +2025,9 @@ NPY_NO_EXPORT void
 HALF_remainder(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func))
 {
     BINARY_LOOP {
-        const float in1 = npy_half_to_float(*(npy_half *)ip1);
-        const float in2 = npy_half_to_float(*(npy_half *)ip2);
-        const float res = npy_fmodf(in1,in2);
-        if (res && ((in2 < 0) != (res < 0))) {
-            *((npy_half *)op1) = npy_float_to_half(res + in2);
-        }
-        else {
-            *((npy_half *)op1) = npy_float_to_half(res);
-        }
+        const npy_half in1 = *(npy_half *)ip1;
+        const npy_half in2 = *(npy_half *)ip2;
+        npy_half_divmod(in1, in2, (npy_half *)op1);
     }
 }
 
diff --git a/numpy/core/src/umath/scalarmath.c.src b/numpy/core/src/umath/scalarmath.c.src
index 706eccb..77520ab 100644
--- a/numpy/core/src/umath/scalarmath.c.src
+++ b/numpy/core/src/umath/scalarmath.c.src
@@ -175,6 +175,7 @@ static void
 }
 
 #define @name at _ctype_floor_divide @name at _ctype_divide
+
 static void
 @name at _ctype_remainder(@type@ a, @type@ b, @type@ *out) {
     if (a == 0 || b == 0) {
@@ -268,20 +269,40 @@ static void
 /**begin repeat
  * #name = float, double, longdouble#
  * #type = npy_float, npy_double, npy_longdouble#
+ * #c = f, , l#
  */
-static @type@ (*_basic_ at name@_floor)(@type@);
 static @type@ (*_basic_ at name@_sqrt)(@type@);
 static @type@ (*_basic_ at name@_fmod)(@type@, @type@);
+
 #define @name at _ctype_add(a, b, outp) *(outp) = (a) + (b)
 #define @name at _ctype_subtract(a, b, outp) *(outp) = (a) - (b)
 #define @name at _ctype_multiply(a, b, outp) *(outp) = (a) * (b)
 #define @name at _ctype_divide(a, b, outp) *(outp) = (a) / (b)
 #define @name at _ctype_true_divide @name at _ctype_divide
-#define @name at _ctype_floor_divide(a, b, outp)   \
-    *(outp) = _basic_ at name@_floor((a) / (b))
+
+
+static void
+ at name@_ctype_floor_divide(@type@ a, @type@ b, @type@ *out) {
+    @type@ mod;
+
+    *out = npy_divmod at c@(a, b, &mod);
+}
+
+
+static void
+ at name@_ctype_remainder(@type@ a, @type@ b, @type@ *out) {
+    npy_divmod at c@(a, b, out);
+}
+
+
+static void
+ at name@_ctype_divmod(@type@ a, @type@ b, @type@ *out1, @type@ *out2) {
+    *out1 = npy_divmod at c@(a, b, out2);
+}
+
+
 /**end repeat**/
 
-static npy_half (*_basic_half_floor)(npy_half);
 static npy_half (*_basic_half_sqrt)(npy_half);
 static npy_half (*_basic_half_fmod)(npy_half, npy_half);
 
@@ -294,9 +315,26 @@ static npy_half (*_basic_half_fmod)(npy_half, npy_half);
... 24948 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-numpy.git



More information about the Python-modules-commits mailing list