diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 7ca93d7d75854..874aea1e22735 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -252,6 +252,7 @@ I/O - Bug in :func:`DataFrame.to_string` where values were truncated using display options instead of outputting the full content (:issue:`9784`) - Bug in :meth:`DataFrame.to_json` where a datetime column label would not be written out in ISO format with ``orient="table"`` (:issue:`28130`) - Bug in :func:`DataFrame.to_parquet` where writing to GCS would fail with `engine='fastparquet'` if the file did not already exist (:issue:`28326`) +- Bug in :meth:`DataFrame.to_html` where the length of the ``formatters`` argument was not verified (:issue:`28469`) Plotting ^^^^^^^^ diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 3a50f63409582..15f21814b072d 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -561,7 +561,17 @@ def __init__( self.sparsify = sparsify self.float_format = float_format - self.formatters = formatters if formatters is not None else {} + if formatters is None: + self.formatters = {} + elif len(frame.columns) == len(formatters) or isinstance(formatters, dict): + self.formatters = formatters + else: + raise ValueError( + ( + "Formatters length({flen}) should match" + " DataFrame number of columns({dlen})" + ).format(flen=len(formatters), dlen=len(frame.columns)) + ) self.na_rep = na_rep self.decimal = decimal self.col_space = col_space diff --git a/pandas/tests/io/formats/test_to_html.py b/pandas/tests/io/formats/test_to_html.py index 004dffd128dd6..ef19319e208d9 100644 --- a/pandas/tests/io/formats/test_to_html.py +++ b/pandas/tests/io/formats/test_to_html.py @@ -235,6 +235,15 @@ def test_to_html_truncate(datapath): assert result == expected +@pytest.mark.parametrize("size", [1, 5]) +def test_html_invalid_formatters_arg_raises(size): + # issue-28469 + df = DataFrame(columns=["a", "b", "c"]) + msg = "Formatters length({}) should match DataFrame number of columns(3)" + with pytest.raises(ValueError, match=re.escape(msg.format(size))): + df.to_html(formatters=["{}".format] * size) + + def test_to_html_truncate_formatter(datapath): # issue-25955 data = [