1"""
2Expose public exceptions & warnings
3"""
4from __future__ import annotations
5
6import ctypes
7
8from pandas._config.config import OptionError
9
10from pandas._libs.tslibs import (
11 OutOfBoundsDatetime,
12 OutOfBoundsTimedelta,
13)
14
15from pandas.util.version import InvalidVersion
16
17
18class IntCastingNaNError(ValueError):
19 """
20 Exception raised when converting (``astype``) an array with NaN to an integer type.
21 """
22
23
24class NullFrequencyError(ValueError):
25 """
26 Exception raised when a ``freq`` cannot be null.
27
28 Particularly ``DatetimeIndex.shift``, ``TimedeltaIndex.shift``,
29 ``PeriodIndex.shift``.
30 """
31
32
33class PerformanceWarning(Warning):
34 """
35 Warning raised when there is a possible performance impact.
36 """
37
38
39class UnsupportedFunctionCall(ValueError):
40 """
41 Exception raised when attempting to call a unsupported numpy function.
42
43 For example, ``np.cumsum(groupby_object)``.
44 """
45
46
47class UnsortedIndexError(KeyError):
48 """
49 Error raised when slicing a MultiIndex which has not been lexsorted.
50
51 Subclass of `KeyError`.
52 """
53
54
55class ParserError(ValueError):
56 """
57 Exception that is raised by an error encountered in parsing file contents.
58
59 This is a generic error raised for errors encountered when functions like
60 `read_csv` or `read_html` are parsing contents of a file.
61
62 See Also
63 --------
64 read_csv : Read CSV (comma-separated) file into a DataFrame.
65 read_html : Read HTML table into a DataFrame.
66 """
67
68
69class DtypeWarning(Warning):
70 """
71 Warning raised when reading different dtypes in a column from a file.
72
73 Raised for a dtype incompatibility. This can happen whenever `read_csv`
74 or `read_table` encounter non-uniform dtypes in a column(s) of a given
75 CSV file.
76
77 See Also
78 --------
79 read_csv : Read CSV (comma-separated) file into a DataFrame.
80 read_table : Read general delimited file into a DataFrame.
81
82 Notes
83 -----
84 This warning is issued when dealing with larger files because the dtype
85 checking happens per chunk read.
86
87 Despite the warning, the CSV file is read with mixed types in a single
88 column which will be an object type. See the examples below to better
89 understand this issue.
90
91 Examples
92 --------
93 This example creates and reads a large CSV file with a column that contains
94 `int` and `str`.
95
96 >>> df = pd.DataFrame({'a': (['1'] * 100000 + ['X'] * 100000 +
97 ... ['1'] * 100000),
98 ... 'b': ['b'] * 300000}) # doctest: +SKIP
99 >>> df.to_csv('test.csv', index=False) # doctest: +SKIP
100 >>> df2 = pd.read_csv('test.csv') # doctest: +SKIP
101 ... # DtypeWarning: Columns (0) have mixed types
102
103 Important to notice that ``df2`` will contain both `str` and `int` for the
104 same input, '1'.
105
106 >>> df2.iloc[262140, 0] # doctest: +SKIP
107 '1'
108 >>> type(df2.iloc[262140, 0]) # doctest: +SKIP
109 <class 'str'>
110 >>> df2.iloc[262150, 0] # doctest: +SKIP
111 1
112 >>> type(df2.iloc[262150, 0]) # doctest: +SKIP
113 <class 'int'>
114
115 One way to solve this issue is using the `dtype` parameter in the
116 `read_csv` and `read_table` functions to explicit the conversion:
117
118 >>> df2 = pd.read_csv('test.csv', sep=',', dtype={'a': str}) # doctest: +SKIP
119
120 No warning was issued.
121 """
122
123
124class EmptyDataError(ValueError):
125 """
126 Exception raised in ``pd.read_csv`` when empty data or header is encountered.
127 """
128
129
130class ParserWarning(Warning):
131 """
132 Warning raised when reading a file that doesn't use the default 'c' parser.
133
134 Raised by `pd.read_csv` and `pd.read_table` when it is necessary to change
135 parsers, generally from the default 'c' parser to 'python'.
136
137 It happens due to a lack of support or functionality for parsing a
138 particular attribute of a CSV file with the requested engine.
139
140 Currently, 'c' unsupported options include the following parameters:
141
142 1. `sep` other than a single character (e.g. regex separators)
143 2. `skipfooter` higher than 0
144 3. `sep=None` with `delim_whitespace=False`
145
146 The warning can be avoided by adding `engine='python'` as a parameter in
147 `pd.read_csv` and `pd.read_table` methods.
148
149 See Also
150 --------
151 pd.read_csv : Read CSV (comma-separated) file into DataFrame.
152 pd.read_table : Read general delimited file into DataFrame.
153
154 Examples
155 --------
156 Using a `sep` in `pd.read_csv` other than a single character:
157
158 >>> import io
159 >>> csv = '''a;b;c
160 ... 1;1,8
161 ... 1;2,1'''
162 >>> df = pd.read_csv(io.StringIO(csv), sep='[;,]') # doctest: +SKIP
163 ... # ParserWarning: Falling back to the 'python' engine...
164
165 Adding `engine='python'` to `pd.read_csv` removes the Warning:
166
167 >>> df = pd.read_csv(io.StringIO(csv), sep='[;,]', engine='python')
168 """
169
170
171class MergeError(ValueError):
172 """
173 Exception raised when merging data.
174
175 Subclass of ``ValueError``.
176 """
177
178
179class AccessorRegistrationWarning(Warning):
180 """
181 Warning for attribute conflicts in accessor registration.
182 """
183
184
185class AbstractMethodError(NotImplementedError):
186 """
187 Raise this error instead of NotImplementedError for abstract methods.
188 """
189
190 def __init__(self, class_instance, methodtype: str = "method") -> None:
191 types = {"method", "classmethod", "staticmethod", "property"}
192 if methodtype not in types:
193 raise ValueError(
194 f"methodtype must be one of {methodtype}, got {types} instead."
195 )
196 self.methodtype = methodtype
197 self.class_instance = class_instance
198
199 def __str__(self) -> str:
200 if self.methodtype == "classmethod":
201 name = self.class_instance.__name__
202 else:
203 name = type(self.class_instance).__name__
204 return f"This {self.methodtype} must be defined in the concrete class {name}"
205
206
207class NumbaUtilError(Exception):
208 """
209 Error raised for unsupported Numba engine routines.
210 """
211
212
213class DuplicateLabelError(ValueError):
214 """
215 Error raised when an operation would introduce duplicate labels.
216
217 .. versionadded:: 1.2.0
218
219 Examples
220 --------
221 >>> s = pd.Series([0, 1, 2], index=['a', 'b', 'c']).set_flags(
222 ... allows_duplicate_labels=False
223 ... )
224 >>> s.reindex(['a', 'a', 'b'])
225 Traceback (most recent call last):
226 ...
227 DuplicateLabelError: Index has duplicates.
228 positions
229 label
230 a [0, 1]
231 """
232
233
234class InvalidIndexError(Exception):
235 """
236 Exception raised when attempting to use an invalid index key.
237
238 .. versionadded:: 1.1.0
239 """
240
241
242class DataError(Exception):
243 """
244 Exceptionn raised when performing an operation on non-numerical data.
245
246 For example, calling ``ohlc`` on a non-numerical column or a function
247 on a rolling window.
248 """
249
250
251class SpecificationError(Exception):
252 """
253 Exception raised by ``agg`` when the functions are ill-specified.
254
255 The exception raised in two scenarios.
256
257 The first way is calling ``agg`` on a
258 Dataframe or Series using a nested renamer (dict-of-dict).
259
260 The second way is calling ``agg`` on a Dataframe with duplicated functions
261 names without assigning column name.
262
263 Examples
264 --------
265 >>> df = pd.DataFrame({'A': [1, 1, 1, 2, 2],
266 ... 'B': range(5),
267 ... 'C': range(5)})
268 >>> df.groupby('A').B.agg({'foo': 'count'}) # doctest: +SKIP
269 ... # SpecificationError: nested renamer is not supported
270
271 >>> df.groupby('A').agg({'B': {'foo': ['sum', 'max']}}) # doctest: +SKIP
272 ... # SpecificationError: nested renamer is not supported
273
274 >>> df.groupby('A').agg(['min', 'min']) # doctest: +SKIP
275 ... # SpecificationError: nested renamer is not supported
276 """
277
278
279class SettingWithCopyError(ValueError):
280 """
281 Exception raised when trying to set on a copied slice from a ``DataFrame``.
282
283 The ``mode.chained_assignment`` needs to be set to set to 'raise.' This can
284 happen unintentionally when chained indexing.
285
286 For more information on evaluation order,
287 see :ref:`the user guide<indexing.evaluation_order>`.
288
289 For more information on view vs. copy,
290 see :ref:`the user guide<indexing.view_versus_copy>`.
291
292 Examples
293 --------
294 >>> pd.options.mode.chained_assignment = 'raise'
295 >>> df = pd.DataFrame({'A': [1, 1, 1, 2, 2]}, columns=['A'])
296 >>> df.loc[0:3]['A'] = 'a' # doctest: +SKIP
297 ... # SettingWithCopyError: A value is trying to be set on a copy of a...
298 """
299
300
301class SettingWithCopyWarning(Warning):
302 """
303 Warning raised when trying to set on a copied slice from a ``DataFrame``.
304
305 The ``mode.chained_assignment`` needs to be set to set to 'warn.'
306 'Warn' is the default option. This can happen unintentionally when
307 chained indexing.
308
309 For more information on evaluation order,
310 see :ref:`the user guide<indexing.evaluation_order>`.
311
312 For more information on view vs. copy,
313 see :ref:`the user guide<indexing.view_versus_copy>`.
314
315 Examples
316 --------
317 >>> df = pd.DataFrame({'A': [1, 1, 1, 2, 2]}, columns=['A'])
318 >>> df.loc[0:3]['A'] = 'a' # doctest: +SKIP
319 ... # SettingWithCopyWarning: A value is trying to be set on a copy of a...
320 """
321
322
323class ChainedAssignmentError(Warning):
324 """
325 Warning raised when trying to set using chained assignment.
326
327 When the ``mode.copy_on_write`` option is enabled, chained assignment can
328 never work. In such a situation, we are always setting into a temporary
329 object that is the result of an indexing operation (getitem), which under
330 Copy-on-Write always behaves as a copy. Thus, assigning through a chain
331 can never update the original Series or DataFrame.
332
333 For more information on view vs. copy,
334 see :ref:`the user guide<indexing.view_versus_copy>`.
335
336 Examples
337 --------
338 >>> pd.options.mode.copy_on_write = True
339 >>> df = pd.DataFrame({'A': [1, 1, 1, 2, 2]}, columns=['A'])
340 >>> df["A"][0:3] = 10 # doctest: +SKIP
341 ... # ChainedAssignmentError: ...
342 >>> pd.options.mode.copy_on_write = False
343 """
344
345
346_chained_assignment_msg = (
347 "A value is trying to be set on a copy of a DataFrame or Series "
348 "through chained assignment.\n"
349 "When using the Copy-on-Write mode, such chained assignment never works "
350 "to update the original DataFrame or Series, because the intermediate "
351 "object on which we are setting values always behaves as a copy.\n\n"
352 "Try using '.loc[row_indexer, col_indexer] = value' instead, to perform "
353 "the assignment in a single step.\n\n"
354 "See the caveats in the documentation: "
355 "https://pandas.pydata.org/pandas-docs/stable/user_guide/"
356 "indexing.html#returning-a-view-versus-a-copy"
357)
358
359
360class NumExprClobberingError(NameError):
361 """
362 Exception raised when trying to use a built-in numexpr name as a variable name.
363
364 ``eval`` or ``query`` will throw the error if the engine is set
365 to 'numexpr'. 'numexpr' is the default engine value for these methods if the
366 numexpr package is installed.
367
368 Examples
369 --------
370 >>> df = pd.DataFrame({'abs': [1, 1, 1]})
371 >>> df.query("abs > 2") # doctest: +SKIP
372 ... # NumExprClobberingError: Variables in expression "(abs) > (2)" overlap...
373 >>> sin, a = 1, 2
374 >>> pd.eval("sin + a", engine='numexpr') # doctest: +SKIP
375 ... # NumExprClobberingError: Variables in expression "(sin) + (a)" overlap...
376 """
377
378
379class UndefinedVariableError(NameError):
380 """
381 Exception raised by ``query`` or ``eval`` when using an undefined variable name.
382
383 It will also specify whether the undefined variable is local or not.
384
385 Examples
386 --------
387 >>> df = pd.DataFrame({'A': [1, 1, 1]})
388 >>> df.query("A > x") # doctest: +SKIP
389 ... # UndefinedVariableError: name 'x' is not defined
390 >>> df.query("A > @y") # doctest: +SKIP
391 ... # UndefinedVariableError: local variable 'y' is not defined
392 >>> pd.eval('x + 1') # doctest: +SKIP
393 ... # UndefinedVariableError: name 'x' is not defined
394 """
395
396 def __init__(self, name: str, is_local: bool | None = None) -> None:
397 base_msg = f"{repr(name)} is not defined"
398 if is_local:
399 msg = f"local variable {base_msg}"
400 else:
401 msg = f"name {base_msg}"
402 super().__init__(msg)
403
404
405class IndexingError(Exception):
406 """
407 Exception is raised when trying to index and there is a mismatch in dimensions.
408
409 Examples
410 --------
411 >>> df = pd.DataFrame({'A': [1, 1, 1]})
412 >>> df.loc[..., ..., 'A'] # doctest: +SKIP
413 ... # IndexingError: indexer may only contain one '...' entry
414 >>> df = pd.DataFrame({'A': [1, 1, 1]})
415 >>> df.loc[1, ..., ...] # doctest: +SKIP
416 ... # IndexingError: Too many indexers
417 >>> df[pd.Series([True], dtype=bool)] # doctest: +SKIP
418 ... # IndexingError: Unalignable boolean Series provided as indexer...
419 >>> s = pd.Series(range(2),
420 ... index = pd.MultiIndex.from_product([["a", "b"], ["c"]]))
421 >>> s.loc["a", "c", "d"] # doctest: +SKIP
422 ... # IndexingError: Too many indexers
423 """
424
425
426class PyperclipException(RuntimeError):
427 """
428 Exception raised when clipboard functionality is unsupported.
429
430 Raised by ``to_clipboard()`` and ``read_clipboard()``.
431 """
432
433
434class PyperclipWindowsException(PyperclipException):
435 """
436 Exception raised when clipboard functionality is unsupported by Windows.
437
438 Access to the clipboard handle would be denied due to some other
439 window process is accessing it.
440 """
441
442 def __init__(self, message: str) -> None:
443 # attr only exists on Windows, so typing fails on other platforms
444 message += f" ({ctypes.WinError()})" # type: ignore[attr-defined]
445 super().__init__(message)
446
447
448class CSSWarning(UserWarning):
449 """
450 Warning is raised when converting css styling fails.
451
452 This can be due to the styling not having an equivalent value or because the
453 styling isn't properly formatted.
454
455 Examples
456 --------
457 >>> df = pd.DataFrame({'A': [1, 1, 1]})
458 >>> (df.style.applymap(lambda x: 'background-color: blueGreenRed;')
459 ... .to_excel('styled.xlsx')) # doctest: +SKIP
460 ... # CSSWarning: Unhandled color format: 'blueGreenRed'
461 >>> (df.style.applymap(lambda x: 'border: 1px solid red red;')
462 ... .to_excel('styled.xlsx')) # doctest: +SKIP
463 ... # CSSWarning: Too many tokens provided to "border" (expected 1-3)
464 """
465
466
467class PossibleDataLossError(Exception):
468 """
469 Exception raised when trying to open a HDFStore file when already opened.
470
471 Examples
472 --------
473 >>> store = pd.HDFStore('my-store', 'a') # doctest: +SKIP
474 >>> store.open("w") # doctest: +SKIP
475 ... # PossibleDataLossError: Re-opening the file [my-store] with mode [a]...
476 """
477
478
479class ClosedFileError(Exception):
480 """
481 Exception is raised when trying to perform an operation on a closed HDFStore file.
482
483 Examples
484 --------
485 >>> store = pd.HDFStore('my-store', 'a') # doctest: +SKIP
486 >>> store.close() # doctest: +SKIP
487 >>> store.keys() # doctest: +SKIP
488 ... # ClosedFileError: my-store file is not open!
489 """
490
491
492class IncompatibilityWarning(Warning):
493 """
494 Warning raised when trying to use where criteria on an incompatible HDF5 file.
495 """
496
497
498class AttributeConflictWarning(Warning):
499 """
500 Warning raised when index attributes conflict when using HDFStore.
501
502 Occurs when attempting to append an index with a different
503 name than the existing index on an HDFStore or attempting to append an index with a
504 different frequency than the existing index on an HDFStore.
505 """
506
507
508class DatabaseError(OSError):
509 """
510 Error is raised when executing sql with bad syntax or sql that throws an error.
511
512 Examples
513 --------
514 >>> from sqlite3 import connect
515 >>> conn = connect(':memory:')
516 >>> pd.read_sql('select * test', conn) # doctest: +SKIP
517 ... # DatabaseError: Execution failed on sql 'test': near "test": syntax error
518 """
519
520
521class PossiblePrecisionLoss(Warning):
522 """
523 Warning raised by to_stata on a column with a value outside or equal to int64.
524
525 When the column value is outside or equal to the int64 value the column is
526 converted to a float64 dtype.
527
528 Examples
529 --------
530 >>> df = pd.DataFrame({"s": pd.Series([1, 2**53], dtype=np.int64)})
531 >>> df.to_stata('test') # doctest: +SKIP
532 ... # PossiblePrecisionLoss: Column converted from int64 to float64...
533 """
534
535
536class ValueLabelTypeMismatch(Warning):
537 """
538 Warning raised by to_stata on a category column that contains non-string values.
539
540 Examples
541 --------
542 >>> df = pd.DataFrame({"categories": pd.Series(["a", 2], dtype="category")})
543 >>> df.to_stata('test') # doctest: +SKIP
544 ... # ValueLabelTypeMismatch: Stata value labels (pandas categories) must be str...
545 """
546
547
548class InvalidColumnName(Warning):
549 """
550 Warning raised by to_stata the column contains a non-valid stata name.
551
552 Because the column name is an invalid Stata variable, the name needs to be
553 converted.
554
555 Examples
556 --------
557 >>> df = pd.DataFrame({"0categories": pd.Series([2, 2])})
558 >>> df.to_stata('test') # doctest: +SKIP
559 ... # InvalidColumnName: Not all pandas column names were valid Stata variable...
560 """
561
562
563class CategoricalConversionWarning(Warning):
564 """
565 Warning is raised when reading a partial labeled Stata file using a iterator.
566
567 Examples
568 --------
569 >>> from pandas.io.stata import StataReader
570 >>> with StataReader('dta_file', chunksize=2) as reader: # doctest: +SKIP
571 ... for i, block in enumerate(reader):
572 ... print(i, block)
573 ... # CategoricalConversionWarning: One or more series with value labels...
574 """
575
576
577class LossySetitemError(Exception):
578 """
579 Raised when trying to do a __setitem__ on an np.ndarray that is not lossless.
580 """
581
582
583class NoBufferPresent(Exception):
584 """
585 Exception is raised in _get_data_buffer to signal that there is no requested buffer.
586 """
587
588
589class InvalidComparison(Exception):
590 """
591 Exception is raised by _validate_comparison_value to indicate an invalid comparison.
592 """
593
594
595__all__ = [
596 "AbstractMethodError",
597 "AccessorRegistrationWarning",
598 "AttributeConflictWarning",
599 "CategoricalConversionWarning",
600 "ClosedFileError",
601 "CSSWarning",
602 "DatabaseError",
603 "DataError",
604 "DtypeWarning",
605 "DuplicateLabelError",
606 "EmptyDataError",
607 "IncompatibilityWarning",
608 "IntCastingNaNError",
609 "InvalidColumnName",
610 "InvalidComparison",
611 "InvalidIndexError",
612 "InvalidVersion",
613 "IndexingError",
614 "LossySetitemError",
615 "MergeError",
616 "NoBufferPresent",
617 "NullFrequencyError",
618 "NumbaUtilError",
619 "NumExprClobberingError",
620 "OptionError",
621 "OutOfBoundsDatetime",
622 "OutOfBoundsTimedelta",
623 "ParserError",
624 "ParserWarning",
625 "PerformanceWarning",
626 "PossibleDataLossError",
627 "PossiblePrecisionLoss",
628 "PyperclipException",
629 "PyperclipWindowsException",
630 "SettingWithCopyError",
631 "SettingWithCopyWarning",
632 "SpecificationError",
633 "UndefinedVariableError",
634 "UnsortedIndexError",
635 "UnsupportedFunctionCall",
636 "ValueLabelTypeMismatch",
637]