summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2019-04-25 22:50:34 -0700
committerGitHub <noreply@github.com>2019-04-25 22:50:34 -0700
commitf7783ec8df4a3c1473fe2c9611602d617559e7a2 (patch)
treeda3411ea78babbf8ffe1d0edcd12f4eea6e92925
parentc37befb43ae9477a5e0ff1faeb5aa493a135805b (diff)
parent22e6aa46f005a564589fc874171f1a31fc9aa0c3 (diff)
downloadnumpy-f7783ec8df4a3c1473fe2c9611602d617559e7a2.tar.gz
Merge pull request #13306 from bmakos/Fix#13225
MAINT: better MemoryError message (#13225)
-rw-r--r--doc/release/1.17.0-notes.rst18
-rw-r--r--numpy/core/_exceptions.py12
-rw-r--r--numpy/core/src/multiarray/ctors.c26
3 files changed, 48 insertions, 8 deletions
diff --git a/doc/release/1.17.0-notes.rst b/doc/release/1.17.0-notes.rst
index 45840e221..71ad17673 100644
--- a/doc/release/1.17.0-notes.rst
+++ b/doc/release/1.17.0-notes.rst
@@ -220,9 +220,9 @@ returns an appropriate infinity.
Specialized ``np.isnan``, ``np.isinf``, and ``np.isfinite`` ufuncs for bool and int types
-----------------------------------------------------------------------------------------
-The boolean and integer types are incapable of storing ``np.nan`` and ``np.inf`` values,
-which allows us to provide specialized ufuncs that are up to 250x faster than the current
-approach.
+The boolean and integer types are incapable of storing ``np.nan`` and
+``np.inf`` values, which allows us to provide specialized ufuncs that are up to
+250x faster than the current approach.
``np.isfinite`` supports ``datetime64`` and ``timedelta64`` types
-----------------------------------------------------------------
@@ -231,9 +231,15 @@ two types.
New keywords added to ``np.nan_to_num``
---------------------------------------
-``np.nan_to_num`` now accepts keywords ``nan``, ``posinf`` and ``neginf`` allowing the
-user to define the value to replace the ``nan``, positive and negative ``np.inf`` values
-respectively.
+``np.nan_to_num`` now accepts keywords ``nan``, ``posinf`` and ``neginf``
+allowing the user to define the value to replace the ``nan``, positive and
+negative ``np.inf`` values respectively.
+
+MemoryErrors caused by allocated overly large arrays are more descriptive
+-------------------------------------------------------------------------
+Often the cause of a MemoryError is incorrect broadcasting, which results in a
+very large and incorrect shape. The message of the error now includes this
+shape to help diagnose the cause of failure.
`floor`, `ceil`, and `trunc` now respect builtin magic methods
--------------------------------------------------------------
diff --git a/numpy/core/_exceptions.py b/numpy/core/_exceptions.py
index a1997ef6b..1dcea6255 100644
--- a/numpy/core/_exceptions.py
+++ b/numpy/core/_exceptions.py
@@ -121,3 +121,15 @@ class AxisError(ValueError, IndexError):
msg = "{}: {}".format(msg_prefix, msg)
super(AxisError, self).__init__(msg)
+
+
+@_display_as_base
+class _ArrayMemoryError(MemoryError):
+ """ Thrown when an array cannot be allocated"""
+ def __init__(self, shape, dtype):
+ self.shape = shape
+ self.dtype = dtype
+
+ def __str__(self):
+ return "Unable to allocate array with shape {} and data type {}".format(self.shape, self.dtype)
+
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 546eb2a48..dc42d1cfe 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -1072,8 +1072,30 @@ PyArray_NewFromDescr_int(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
data = npy_alloc_cache(nbytes);
}
if (data == NULL) {
- PyErr_NoMemory();
- goto fail;
+ static PyObject *exc_type = NULL;
+
+ npy_cache_import(
+ "numpy.core._exceptions", "_ArrayMemoryError",
+ &exc_type);
+ if (exc_type == NULL) {
+ return NULL;
+ }
+
+ PyObject *shape = PyArray_IntTupleFromIntp(fa->nd,fa->dimensions);
+ if (shape == NULL) {
+ return NULL;
+ }
+
+ /* produce an error object */
+ PyObject *exc_value = PyTuple_Pack(2, shape, descr);
+ Py_DECREF(shape);
+ if (exc_value == NULL){
+ return NULL;
+ }
+ PyErr_SetObject(exc_type, exc_value);
+ Py_DECREF(exc_value);
+ return NULL;
+
}
fa->flags |= NPY_ARRAY_OWNDATA;