diff options
author | Matti Picus <matti.picus@gmail.com> | 2019-04-25 22:50:34 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-25 22:50:34 -0700 |
commit | f7783ec8df4a3c1473fe2c9611602d617559e7a2 (patch) | |
tree | da3411ea78babbf8ffe1d0edcd12f4eea6e92925 | |
parent | c37befb43ae9477a5e0ff1faeb5aa493a135805b (diff) | |
parent | 22e6aa46f005a564589fc874171f1a31fc9aa0c3 (diff) | |
download | numpy-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.rst | 18 | ||||
-rw-r--r-- | numpy/core/_exceptions.py | 12 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 26 |
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; |