1"""
2Exceptions and Warnings
3=======================
4
5General exceptions used by NumPy. Note that some exceptions may be module
6specific, such as linear algebra errors.
7
8.. versionadded:: NumPy 1.25
9
10 The exceptions module is new in NumPy 1.25. Older exceptions remain
11 available through the main NumPy namespace for compatibility.
12
13.. currentmodule:: numpy.exceptions
14
15Warnings
16--------
17.. autosummary::
18 :toctree: generated/
19
20 ComplexWarning Given when converting complex to real.
21 VisibleDeprecationWarning Same as a DeprecationWarning, but more visible.
22 RankWarning Issued when the design matrix is rank deficient.
23
24Exceptions
25----------
26.. autosummary::
27 :toctree: generated/
28
29 AxisError Given when an axis was invalid.
30 DTypePromotionError Given when no common dtype could be found.
31 TooHardError Error specific to `numpy.shares_memory`.
32
33"""
34
35
36__all__ = [
37 "ComplexWarning", "VisibleDeprecationWarning", "ModuleDeprecationWarning",
38 "TooHardError", "AxisError", "DTypePromotionError"]
39
40
41# Disallow reloading this module so as to preserve the identities of the
42# classes defined here.
43if '_is_loaded' in globals():
44 raise RuntimeError('Reloading numpy._globals is not allowed')
45_is_loaded = True
46
47
48class ComplexWarning(RuntimeWarning):
49 """
50 The warning raised when casting a complex dtype to a real dtype.
51
52 As implemented, casting a complex number to a real discards its imaginary
53 part, but this behavior may not be what the user actually wants.
54
55 """
56 pass
57
58
59class ModuleDeprecationWarning(DeprecationWarning):
60 """Module deprecation warning.
61
62 .. warning::
63
64 This warning should not be used, since nose testing is not relevant
65 anymore.
66
67 The nose tester turns ordinary Deprecation warnings into test failures.
68 That makes it hard to deprecate whole modules, because they get
69 imported by default. So this is a special Deprecation warning that the
70 nose tester will let pass without making tests fail.
71
72 """
73 pass
74
75
76class VisibleDeprecationWarning(UserWarning):
77 """Visible deprecation warning.
78
79 By default, python will not show deprecation warnings, so this class
80 can be used when a very visible warning is helpful, for example because
81 the usage is most likely a user bug.
82
83 """
84 pass
85
86
87class RankWarning(RuntimeWarning):
88 """Matrix rank warning.
89
90 Issued by polynomial functions when the design matrix is rank deficient.
91
92 """
93 pass
94
95
96# Exception used in shares_memory()
97class TooHardError(RuntimeError):
98 """``max_work`` was exceeded.
99
100 This is raised whenever the maximum number of candidate solutions
101 to consider specified by the ``max_work`` parameter is exceeded.
102 Assigning a finite number to ``max_work`` may have caused the operation
103 to fail.
104
105 """
106 pass
107
108
109class AxisError(ValueError, IndexError):
110 """Axis supplied was invalid.
111
112 This is raised whenever an ``axis`` parameter is specified that is larger
113 than the number of array dimensions.
114 For compatibility with code written against older numpy versions, which
115 raised a mixture of :exc:`ValueError` and :exc:`IndexError` for this
116 situation, this exception subclasses both to ensure that
117 ``except ValueError`` and ``except IndexError`` statements continue
118 to catch ``AxisError``.
119
120 Parameters
121 ----------
122 axis : int or str
123 The out of bounds axis or a custom exception message.
124 If an axis is provided, then `ndim` should be specified as well.
125 ndim : int, optional
126 The number of array dimensions.
127 msg_prefix : str, optional
128 A prefix for the exception message.
129
130 Attributes
131 ----------
132 axis : int, optional
133 The out of bounds axis or ``None`` if a custom exception
134 message was provided. This should be the axis as passed by
135 the user, before any normalization to resolve negative indices.
136
137 .. versionadded:: 1.22
138 ndim : int, optional
139 The number of array dimensions or ``None`` if a custom exception
140 message was provided.
141
142 .. versionadded:: 1.22
143
144
145 Examples
146 --------
147 >>> import numpy as np
148 >>> array_1d = np.arange(10)
149 >>> np.cumsum(array_1d, axis=1)
150 Traceback (most recent call last):
151 ...
152 numpy.exceptions.AxisError: axis 1 is out of bounds for array of dimension 1
153
154 Negative axes are preserved:
155
156 >>> np.cumsum(array_1d, axis=-2)
157 Traceback (most recent call last):
158 ...
159 numpy.exceptions.AxisError: axis -2 is out of bounds for array of dimension 1
160
161 The class constructor generally takes the axis and arrays'
162 dimensionality as arguments:
163
164 >>> print(np.exceptions.AxisError(2, 1, msg_prefix='error'))
165 error: axis 2 is out of bounds for array of dimension 1
166
167 Alternatively, a custom exception message can be passed:
168
169 >>> print(np.exceptions.AxisError('Custom error message'))
170 Custom error message
171
172 """
173
174 __slots__ = ("_msg", "axis", "ndim")
175
176 def __init__(self, axis, ndim=None, msg_prefix=None):
177 if ndim is msg_prefix is None:
178 # single-argument form: directly set the error message
179 self._msg = axis
180 self.axis = None
181 self.ndim = None
182 else:
183 self._msg = msg_prefix
184 self.axis = axis
185 self.ndim = ndim
186
187 def __str__(self):
188 axis = self.axis
189 ndim = self.ndim
190
191 if axis is ndim is None:
192 return self._msg
193 else:
194 msg = f"axis {axis} is out of bounds for array of dimension {ndim}"
195 if self._msg is not None:
196 msg = f"{self._msg}: {msg}"
197 return msg
198
199
200class DTypePromotionError(TypeError):
201 """Multiple DTypes could not be converted to a common one.
202
203 This exception derives from ``TypeError`` and is raised whenever dtypes
204 cannot be converted to a single common one. This can be because they
205 are of a different category/class or incompatible instances of the same
206 one (see Examples).
207
208 Notes
209 -----
210 Many functions will use promotion to find the correct result and
211 implementation. For these functions the error will typically be chained
212 with a more specific error indicating that no implementation was found
213 for the input dtypes.
214
215 Typically promotion should be considered "invalid" between the dtypes of
216 two arrays when `arr1 == arr2` can safely return all ``False`` because the
217 dtypes are fundamentally different.
218
219 Examples
220 --------
221 Datetimes and complex numbers are incompatible classes and cannot be
222 promoted:
223
224 >>> import numpy as np
225 >>> np.result_type(np.dtype("M8[s]"), np.complex128) # doctest: +IGNORE_EXCEPTION_DETAIL
226 Traceback (most recent call last):
227 ...
228 DTypePromotionError: The DType <class 'numpy.dtype[datetime64]'> could not
229 be promoted by <class 'numpy.dtype[complex128]'>. This means that no common
230 DType exists for the given inputs. For example they cannot be stored in a
231 single array unless the dtype is `object`. The full list of DTypes is:
232 (<class 'numpy.dtype[datetime64]'>, <class 'numpy.dtype[complex128]'>)
233
234 For example for structured dtypes, the structure can mismatch and the
235 same ``DTypePromotionError`` is given when two structured dtypes with
236 a mismatch in their number of fields is given:
237
238 >>> dtype1 = np.dtype([("field1", np.float64), ("field2", np.int64)])
239 >>> dtype2 = np.dtype([("field1", np.float64)])
240 >>> np.promote_types(dtype1, dtype2) # doctest: +IGNORE_EXCEPTION_DETAIL
241 Traceback (most recent call last):
242 ...
243 DTypePromotionError: field names `('field1', 'field2')` and `('field1',)`
244 mismatch.
245
246 """ # noqa: E501
247 pass