From a947f7a7f206d870862072f9dc857f5e5c5fd2f2 Mon Sep 17 00:00:00 2001 From: phofl Date: Sun, 28 Nov 2021 12:32:56 +0100 Subject: [PATCH 1/4] WARN: Clarify future warnings for read_csv --- pandas/io/parsers/readers.py | 16 ++++++++-------- .../tests/io/parser/common/test_common_basic.py | 6 ++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py index 2ca9be3ec097a..5258fa037c3a8 100644 --- a/pandas/io/parsers/readers.py +++ b/pandas/io/parsers/readers.py @@ -446,10 +446,10 @@ "low_memory", } -_deprecated_defaults: dict[str, Any] = { - "error_bad_lines": None, - "warn_bad_lines": None, - "squeeze": None, +_deprecated_defaults: dict[str, tuple[Any, str]] = { + "error_bad_lines": (None, "Use on_bad_lines in the future."), + "warn_bad_lines": (None, "Use on_bad_lines in the future."), + "squeeze": (None, 'Append .squeeze("columns") to the call to squeeze.'), } @@ -926,7 +926,7 @@ def _get_options_with_defaults(self, engine): if engine != "c" and value != default: if "python" in engine and argname not in _python_unsupported: pass - elif value == _deprecated_defaults.get(argname, default): + elif value == _deprecated_defaults.get(argname, (default, None))[0]: pass else: raise ValueError( @@ -934,7 +934,7 @@ def _get_options_with_defaults(self, engine): f"{repr(engine)} engine" ) else: - value = _deprecated_defaults.get(argname, default) + value = _deprecated_defaults.get(argname, (default, None))[0] options[argname] = value if engine == "python-fwf": @@ -1059,10 +1059,10 @@ def _clean_options(self, options, engine): for arg in _deprecated_defaults.keys(): parser_default = _c_parser_defaults.get(arg, parser_defaults[arg]) depr_default = _deprecated_defaults[arg] - if result.get(arg, depr_default) != depr_default: + if result.get(arg, depr_default) != depr_default[0]: msg = ( f"The {arg} argument has been deprecated and will be " - "removed in a future version.\n\n" + f"removed in a future version. {depr_default[1]}\n\n" ) warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) else: diff --git a/pandas/tests/io/parser/common/test_common_basic.py b/pandas/tests/io/parser/common/test_common_basic.py index 96c3709fdb3d8..1268923f30bb3 100644 --- a/pandas/tests/io/parser/common/test_common_basic.py +++ b/pandas/tests/io/parser/common/test_common_basic.py @@ -143,7 +143,8 @@ def test_squeeze(all_parsers, squeeze): result = parser.read_csv_check_warnings( FutureWarning, "The squeeze argument has been deprecated " - "and will be removed in a future version.\n\n", + "and will be removed in a future version. " + 'Append .squeeze\\("columns"\\) to the call to squeeze.\n\n', StringIO(data), index_col=0, header=None, @@ -877,7 +878,8 @@ def test_deprecated_bad_lines_warns(all_parsers, csv1, on_bad_lines): parser.read_csv_check_warnings( FutureWarning, f"The {on_bad_lines}_bad_lines argument has been deprecated " - "and will be removed in a future version.\n\n", + "and will be removed in a future version. " + "Use on_bad_lines in the future.\n\n", csv1, **kwds, ) From a4412be5fb45eed7bc5ff4073ffbafa20abb169c Mon Sep 17 00:00:00 2001 From: phofl Date: Sun, 28 Nov 2021 12:59:19 +0100 Subject: [PATCH 2/4] Adjust test --- pandas/tests/io/excel/test_readers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 60302928420d0..2f65a39c67d2d 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -1197,7 +1197,8 @@ def test_read_excel_squeeze(self, read_ext): with tm.assert_produces_warning( FutureWarning, match="The squeeze argument has been deprecated " - "and will be removed in a future version.\n\n", + "and will be removed in a future version. " + 'Append .squeeze\\("columns"\\) to the call to squeeze.\n\n', ): actual = pd.read_excel( f, sheet_name="two_columns", index_col=0, squeeze=True From aa512fd50adce51ce6433232f34a6be653a53086 Mon Sep 17 00:00:00 2001 From: phofl Date: Sun, 28 Nov 2021 20:02:37 +0100 Subject: [PATCH 3/4] Use namedtuple --- pandas/io/parsers/readers.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py index 5258fa037c3a8..8b1c2d6cd5baf 100644 --- a/pandas/io/parsers/readers.py +++ b/pandas/io/parsers/readers.py @@ -7,7 +7,10 @@ import csv import sys from textwrap import fill -from typing import Any +from typing import ( + Any, + NamedTuple, +) import warnings import numpy as np @@ -446,10 +449,18 @@ "low_memory", } -_deprecated_defaults: dict[str, tuple[Any, str]] = { - "error_bad_lines": (None, "Use on_bad_lines in the future."), - "warn_bad_lines": (None, "Use on_bad_lines in the future."), - "squeeze": (None, 'Append .squeeze("columns") to the call to squeeze.'), + +class _DeprecationConfig(NamedTuple): + default_value: Any + msg: str + + +_deprecated_defaults: dict[str, _DeprecationConfig] = { + "error_bad_lines": _DeprecationConfig(None, "Use on_bad_lines in the future."), + "warn_bad_lines": _DeprecationConfig(None, "Use on_bad_lines in the future."), + "squeeze": _DeprecationConfig( + None, 'Append .squeeze("columns") to the call to squeeze.' + ), } @@ -926,7 +937,12 @@ def _get_options_with_defaults(self, engine): if engine != "c" and value != default: if "python" in engine and argname not in _python_unsupported: pass - elif value == _deprecated_defaults.get(argname, (default, None))[0]: + elif ( + value + == _deprecated_defaults.get( + argname, (default, None) + ).default_value + ): pass else: raise ValueError( @@ -934,7 +950,7 @@ def _get_options_with_defaults(self, engine): f"{repr(engine)} engine" ) else: - value = _deprecated_defaults.get(argname, (default, None))[0] + value = _deprecated_defaults.get(argname, (default, None)).default_value options[argname] = value if engine == "python-fwf": @@ -1059,10 +1075,10 @@ def _clean_options(self, options, engine): for arg in _deprecated_defaults.keys(): parser_default = _c_parser_defaults.get(arg, parser_defaults[arg]) depr_default = _deprecated_defaults[arg] - if result.get(arg, depr_default) != depr_default[0]: + if result.get(arg, depr_default) != depr_default.default_value: msg = ( f"The {arg} argument has been deprecated and will be " - f"removed in a future version. {depr_default[1]}\n\n" + f"removed in a future version. {depr_default.msg}\n\n" ) warnings.warn(msg, FutureWarning, stacklevel=find_stack_level()) else: From 1bbc61c0f920e09769730b8648ade1d361cc8860 Mon Sep 17 00:00:00 2001 From: phofl Date: Sun, 28 Nov 2021 20:59:05 +0100 Subject: [PATCH 4/4] Fix tests --- pandas/io/parsers/readers.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pandas/io/parsers/readers.py b/pandas/io/parsers/readers.py index 8b1c2d6cd5baf..63ab10e1e5362 100644 --- a/pandas/io/parsers/readers.py +++ b/pandas/io/parsers/readers.py @@ -452,7 +452,7 @@ class _DeprecationConfig(NamedTuple): default_value: Any - msg: str + msg: str | None _deprecated_defaults: dict[str, _DeprecationConfig] = { @@ -940,7 +940,7 @@ def _get_options_with_defaults(self, engine): elif ( value == _deprecated_defaults.get( - argname, (default, None) + argname, _DeprecationConfig(default, None) ).default_value ): pass @@ -950,7 +950,9 @@ def _get_options_with_defaults(self, engine): f"{repr(engine)} engine" ) else: - value = _deprecated_defaults.get(argname, (default, None)).default_value + value = _deprecated_defaults.get( + argname, _DeprecationConfig(default, None) + ).default_value options[argname] = value if engine == "python-fwf":