summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/__init__.py6
-rw-r--r--numpy/core/_exceptions.py107
-rw-r--r--numpy/core/numeric.py33
-rw-r--r--numpy/core/src/multiarray/common.h2
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c16
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c5
-rw-r--r--numpy/core/src/umath/scalarmath.c.src4
-rw-r--r--numpy/core/tests/test_multiarray.py4
-rw-r--r--numpy/exceptions.py123
-rw-r--r--numpy/tests/test_public_api.py1
10 files changed, 151 insertions, 150 deletions
diff --git a/numpy/__init__.py b/numpy/__init__.py
index bdea595ed..5af2ac847 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -110,6 +110,7 @@ from ._globals import (
ModuleDeprecationWarning, VisibleDeprecationWarning,
_NoValue, _CopyMode
)
+from .exceptions import ComplexWarning, TooHardError, AxisError
# We first need to detect if we're being called as part of the numpy setup
# procedure itself in a reliable manner.
@@ -129,8 +130,9 @@ else:
your python interpreter from there."""
raise ImportError(msg) from e
- __all__ = ['ModuleDeprecationWarning',
- 'VisibleDeprecationWarning']
+ __all__ = [
+ 'ModuleDeprecationWarning', 'VisibleDeprecationWarning',
+ 'ComplexWarning', 'TooHardError', 'AxisError']
# mapping of {name: (value, deprecation_msg)}
__deprecated_attrs__ = {}
diff --git a/numpy/core/_exceptions.py b/numpy/core/_exceptions.py
index db5dfea02..62579ed0d 100644
--- a/numpy/core/_exceptions.py
+++ b/numpy/core/_exceptions.py
@@ -114,113 +114,6 @@ class _UFuncOutputCastingError(_UFuncCastingError):
)
-# Exception used in shares_memory()
-@set_module('numpy')
-class TooHardError(RuntimeError):
- """max_work was exceeded.
-
- This is raised whenever the maximum number of candidate solutions
- to consider specified by the ``max_work`` parameter is exceeded.
- Assigning a finite number to max_work may have caused the operation
- to fail.
-
- """
-
- pass
-
-
-@set_module('numpy')
-class AxisError(ValueError, IndexError):
- """Axis supplied was invalid.
-
- This is raised whenever an ``axis`` parameter is specified that is larger
- than the number of array dimensions.
- For compatibility with code written against older numpy versions, which
- raised a mixture of `ValueError` and `IndexError` for this situation, this
- exception subclasses both to ensure that ``except ValueError`` and
- ``except IndexError`` statements continue to catch `AxisError`.
-
- .. versionadded:: 1.13
-
- Parameters
- ----------
- axis : int or str
- The out of bounds axis or a custom exception message.
- If an axis is provided, then `ndim` should be specified as well.
- ndim : int, optional
- The number of array dimensions.
- msg_prefix : str, optional
- A prefix for the exception message.
-
- Attributes
- ----------
- axis : int, optional
- The out of bounds axis or ``None`` if a custom exception
- message was provided. This should be the axis as passed by
- the user, before any normalization to resolve negative indices.
-
- .. versionadded:: 1.22
- ndim : int, optional
- The number of array dimensions or ``None`` if a custom exception
- message was provided.
-
- .. versionadded:: 1.22
-
-
- Examples
- --------
- >>> array_1d = np.arange(10)
- >>> np.cumsum(array_1d, axis=1)
- Traceback (most recent call last):
- ...
- numpy.AxisError: axis 1 is out of bounds for array of dimension 1
-
- Negative axes are preserved:
-
- >>> np.cumsum(array_1d, axis=-2)
- Traceback (most recent call last):
- ...
- numpy.AxisError: axis -2 is out of bounds for array of dimension 1
-
- The class constructor generally takes the axis and arrays'
- dimensionality as arguments:
-
- >>> print(np.AxisError(2, 1, msg_prefix='error'))
- error: axis 2 is out of bounds for array of dimension 1
-
- Alternatively, a custom exception message can be passed:
-
- >>> print(np.AxisError('Custom error message'))
- Custom error message
-
- """
-
- __slots__ = ("axis", "ndim", "_msg")
-
- def __init__(self, axis, ndim=None, msg_prefix=None):
- if ndim is msg_prefix is None:
- # single-argument form: directly set the error message
- self._msg = axis
- self.axis = None
- self.ndim = None
- else:
- self._msg = msg_prefix
- self.axis = axis
- self.ndim = ndim
-
- def __str__(self):
- axis = self.axis
- ndim = self.ndim
-
- if axis is ndim is None:
- return self._msg
- else:
- msg = f"axis {axis} is out of bounds for array of dimension {ndim}"
- if self._msg is not None:
- msg = f"{self._msg}: {msg}"
- return msg
-
-
@_display_as_base
class _ArrayMemoryError(MemoryError):
""" Thrown when an array cannot be allocated"""
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index 5b92972d1..577f8e7cd 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -26,7 +26,7 @@ from .overrides import set_array_function_like_doc, set_module
from .umath import (multiply, invert, sin, PINF, NAN)
from . import numerictypes
from .numerictypes import longlong, intc, int_, float_, complex_, bool_
-from ._exceptions import TooHardError, AxisError
+from ..exceptions import ComplexWarning, TooHardError, AxisError
from ._ufunc_config import errstate, _no_nep50_warning
bitwise_not = invert
@@ -52,22 +52,9 @@ __all__ = [
'identity', 'allclose', 'compare_chararrays', 'putmask',
'flatnonzero', 'Inf', 'inf', 'infty', 'Infinity', 'nan', 'NaN',
'False_', 'True_', 'bitwise_not', 'CLIP', 'RAISE', 'WRAP', 'MAXDIMS',
- 'BUFSIZE', 'ALLOW_THREADS', 'ComplexWarning', 'full', 'full_like',
+ 'BUFSIZE', 'ALLOW_THREADS', 'full', 'full_like',
'matmul', 'shares_memory', 'may_share_memory', 'MAY_SHARE_BOUNDS',
- 'MAY_SHARE_EXACT', 'TooHardError', 'AxisError',
- '_get_promotion_state', '_set_promotion_state']
-
-
-@set_module('numpy')
-class ComplexWarning(RuntimeWarning):
- """
- The warning raised when casting a complex dtype to a real dtype.
-
- As implemented, casting a complex number to a real discards its imaginary
- part, but this behavior may not be what the user actually wants.
-
- """
- pass
+ 'MAY_SHARE_EXACT', '_get_promotion_state', '_set_promotion_state']
def _zeros_like_dispatcher(a, dtype=None, order=None, subok=None, shape=None):
@@ -707,7 +694,7 @@ def correlate(a, v, mode='valid'):
--------
convolve : Discrete, linear convolution of two one-dimensional sequences.
multiarray.correlate : Old, no conjugate, version of correlate.
- scipy.signal.correlate : uses FFT which has superior performance on large arrays.
+ scipy.signal.correlate : uses FFT which has superior performance on large arrays.
Notes
-----
@@ -721,7 +708,7 @@ def correlate(a, v, mode='valid'):
`numpy.correlate` may perform slowly in large arrays (i.e. n = 1e5) because it does
not use the FFT to compute the convolution; in that case, `scipy.signal.correlate` might
be preferable.
-
+
Examples
--------
@@ -738,7 +725,7 @@ def correlate(a, v, mode='valid'):
array([ 0.5-0.5j, 1.0+0.j , 1.5-1.5j, 3.0-1.j , 0.0+0.j ])
Note that you get the time reversed, complex conjugated result
- (:math:`\overline{c_{-k}}`) when the two input sequences a and v change
+ (:math:`\overline{c_{-k}}`) when the two input sequences a and v change
places:
>>> np.correlate([0, 1, 0.5j], [1+1j, 2, 3-1j], 'full')
@@ -1300,7 +1287,7 @@ def rollaxis(a, axis, start=0):
+-------------------+----------------------+
| ``arr.ndim + 1`` | raise ``AxisError`` |
+-------------------+----------------------+
-
+
.. |vdots| unicode:: U+22EE .. Vertical Ellipsis
Returns
@@ -1843,11 +1830,11 @@ def fromfunction(function, shape, *, dtype=float, like=None, **kwargs):
>>> np.fromfunction(lambda i, j: i, (2, 2), dtype=float)
array([[0., 0.],
[1., 1.]])
-
- >>> np.fromfunction(lambda i, j: j, (2, 2), dtype=float)
+
+ >>> np.fromfunction(lambda i, j: j, (2, 2), dtype=float)
array([[0., 1.],
[0., 1.]])
-
+
>>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
array([[ True, False, False],
[False, True, False],
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index e40edb0d2..06322e902 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -149,7 +149,7 @@ check_and_adjust_axis_msg(int *axis, int ndim, PyObject *msg_prefix)
static PyObject *AxisError_cls = NULL;
PyObject *exc;
- npy_cache_import("numpy.core._exceptions", "AxisError", &AxisError_cls);
+ npy_cache_import("numpy.exceptions", "AxisError", &AxisError_cls);
if (AxisError_cls == NULL) {
return -1;
}
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index 7f31fd656..eeb42df66 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -384,18 +384,14 @@ PyArray_GetCastFunc(PyArray_Descr *descr, int type_num)
!PyTypeNum_ISCOMPLEX(type_num) &&
PyTypeNum_ISNUMBER(type_num) &&
!PyTypeNum_ISBOOL(type_num)) {
- PyObject *cls = NULL, *obj = NULL;
- int ret;
- obj = PyImport_ImportModule("numpy.core");
-
- if (obj) {
- cls = PyObject_GetAttrString(obj, "ComplexWarning");
- Py_DECREF(obj);
+ static PyObject *cls = NULL;
+ npy_cache_import("numpy.exceptions", "ComplexWarning", &cls);
+ if (cls == NULL) {
+ return NULL;
}
- ret = PyErr_WarnEx(cls,
+ int ret = PyErr_WarnEx(cls,
"Casting complex values to real discards "
"the imaginary part", 1);
- Py_XDECREF(cls);
if (ret < 0) {
return NULL;
}
@@ -2613,7 +2609,7 @@ complex_to_noncomplex_get_loop(
{
static PyObject *cls = NULL;
int ret;
- npy_cache_import("numpy.core", "ComplexWarning", &cls);
+ npy_cache_import("numpy.exceptions", "ComplexWarning", &cls);
if (cls == NULL) {
return -1;
}
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 8c8cc3c44..6c5eb9730 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -4162,7 +4162,6 @@ array_shares_memory_impl(PyObject *args, PyObject *kwds, Py_ssize_t default_max_
static char *kwlist[] = {"self", "other", "max_work", NULL};
mem_overlap_t result;
- static PyObject *too_hard_cls = NULL;
Py_ssize_t max_work;
NPY_BEGIN_THREADS_DEF;
@@ -4242,8 +4241,8 @@ array_shares_memory_impl(PyObject *args, PyObject *kwds, Py_ssize_t default_max_
}
else if (result == MEM_OVERLAP_TOO_HARD) {
if (raise_exceptions) {
- npy_cache_import("numpy.core._exceptions", "TooHardError",
- &too_hard_cls);
+ static PyObject *too_hard_cls = NULL;
+ npy_cache_import("numpy.exceptions", "TooHardError", &too_hard_cls);
if (too_hard_cls) {
PyErr_SetString(too_hard_cls, "Exceeded max_work");
}
diff --git a/numpy/core/src/umath/scalarmath.c.src b/numpy/core/src/umath/scalarmath.c.src
index 9d703504f..70fe963b9 100644
--- a/numpy/core/src/umath/scalarmath.c.src
+++ b/numpy/core/src/umath/scalarmath.c.src
@@ -1549,7 +1549,7 @@ static PyObject *
*
*/
-/*
+/*
* Complex numbers do not support remainder so we manually make sure that the
* operation is not defined. This is/was especially important for longdoubles
* due to their tendency to recurse for some operations, see gh-18548.
@@ -1711,7 +1711,7 @@ static int
emit_complexwarning(void)
{
static PyObject *cls = NULL;
- npy_cache_import("numpy.core", "ComplexWarning", &cls);
+ npy_cache_import("numpy.exceptions", "ComplexWarning", &cls);
if (cls == NULL) {
return -1;
}
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index ad1d9bb04..4d3996d86 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -6197,7 +6197,7 @@ class TestStats:
def test_mean_axis_error(self):
# Ensure that AxisError is raised instead of IndexError when axis is
# out of bounds, see gh-15817.
- with assert_raises(np.core._exceptions.AxisError):
+ with assert_raises(np.exceptions.AxisError):
np.arange(10).mean(axis=2)
def test_mean_where(self):
@@ -6281,7 +6281,7 @@ class TestStats:
def test_var_axis_error(self):
# Ensure that AxisError is raised instead of IndexError when axis is
# out of bounds, see gh-15817.
- with assert_raises(np.core._exceptions.AxisError):
+ with assert_raises(np.exceptions.AxisError):
np.arange(10).var(axis=2)
def test_var_where(self):
diff --git a/numpy/exceptions.py b/numpy/exceptions.py
new file mode 100644
index 000000000..4a63263a5
--- /dev/null
+++ b/numpy/exceptions.py
@@ -0,0 +1,123 @@
+from ._utils import set_module as _set_module
+
+__all__ = ["ComplexWarning", "TooHardError", "AxisError"]
+
+
+@_set_module('numpy')
+class ComplexWarning(RuntimeWarning):
+ """
+ The warning raised when casting a complex dtype to a real dtype.
+
+ As implemented, casting a complex number to a real discards its imaginary
+ part, but this behavior may not be what the user actually wants.
+
+ """
+ pass
+
+
+
+# Exception used in shares_memory()
+@_set_module('numpy')
+class TooHardError(RuntimeError):
+ """max_work was exceeded.
+
+ This is raised whenever the maximum number of candidate solutions
+ to consider specified by the ``max_work`` parameter is exceeded.
+ Assigning a finite number to max_work may have caused the operation
+ to fail.
+
+ """
+
+ pass
+
+
+@_set_module('numpy')
+class AxisError(ValueError, IndexError):
+ """Axis supplied was invalid.
+
+ This is raised whenever an ``axis`` parameter is specified that is larger
+ than the number of array dimensions.
+ For compatibility with code written against older numpy versions, which
+ raised a mixture of `ValueError` and `IndexError` for this situation, this
+ exception subclasses both to ensure that ``except ValueError`` and
+ ``except IndexError`` statements continue to catch `AxisError`.
+
+ .. versionadded:: 1.13
+
+ Parameters
+ ----------
+ axis : int or str
+ The out of bounds axis or a custom exception message.
+ If an axis is provided, then `ndim` should be specified as well.
+ ndim : int, optional
+ The number of array dimensions.
+ msg_prefix : str, optional
+ A prefix for the exception message.
+
+ Attributes
+ ----------
+ axis : int, optional
+ The out of bounds axis or ``None`` if a custom exception
+ message was provided. This should be the axis as passed by
+ the user, before any normalization to resolve negative indices.
+
+ .. versionadded:: 1.22
+ ndim : int, optional
+ The number of array dimensions or ``None`` if a custom exception
+ message was provided.
+
+ .. versionadded:: 1.22
+
+
+ Examples
+ --------
+ >>> array_1d = np.arange(10)
+ >>> np.cumsum(array_1d, axis=1)
+ Traceback (most recent call last):
+ ...
+ numpy.AxisError: axis 1 is out of bounds for array of dimension 1
+
+ Negative axes are preserved:
+
+ >>> np.cumsum(array_1d, axis=-2)
+ Traceback (most recent call last):
+ ...
+ numpy.AxisError: axis -2 is out of bounds for array of dimension 1
+
+ The class constructor generally takes the axis and arrays'
+ dimensionality as arguments:
+
+ >>> print(np.AxisError(2, 1, msg_prefix='error'))
+ error: axis 2 is out of bounds for array of dimension 1
+
+ Alternatively, a custom exception message can be passed:
+
+ >>> print(np.AxisError('Custom error message'))
+ Custom error message
+
+ """
+
+ __slots__ = ("axis", "ndim", "_msg")
+
+ def __init__(self, axis, ndim=None, msg_prefix=None):
+ if ndim is msg_prefix is None:
+ # single-argument form: directly set the error message
+ self._msg = axis
+ self.axis = None
+ self.ndim = None
+ else:
+ self._msg = msg_prefix
+ self.axis = axis
+ self.ndim = ndim
+
+ def __str__(self):
+ axis = self.axis
+ ndim = self.ndim
+
+ if axis is ndim is None:
+ return self._msg
+ else:
+ msg = f"axis {axis} is out of bounds for array of dimension {ndim}"
+ if self._msg is not None:
+ msg = f"{self._msg}: {msg}"
+ return msg
diff --git a/numpy/tests/test_public_api.py b/numpy/tests/test_public_api.py
index 396375d87..4cd602510 100644
--- a/numpy/tests/test_public_api.py
+++ b/numpy/tests/test_public_api.py
@@ -137,6 +137,7 @@ PUBLIC_MODULES = ['numpy.' + s for s in [
"doc",
"doc.constants",
"doc.ufuncs",
+ "exceptions",
"f2py",
"fft",
"lib",