From 643d30082dfb4ea5bec8b7ac3aa70dbe73884466 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Wed, 1 Sep 2021 11:05:49 +0200 Subject: [PATCH 1/6] styler.format options and validator tests --- pandas/core/config_init.py | 8 +++++++- pandas/tests/io/formats/style/test_format.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 89f3bc76d2905..21ecb74cfb93f 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -793,6 +793,12 @@ def register_converter_cb(key): A formatter object to be used as default within ``Styler.format``. """ + +def _is_formatter(x): + if not (x is None or callable(x) or isinstance(x, (dict, str))): + return ValueError("Value must have type 'callable, dict, str' or None.") + + with cf.config_prefix("styler"): cf.register_option("sparse.index", True, styler_sparse_index_doc, validator=bool) @@ -838,5 +844,5 @@ def register_converter_cb(key): "format.formatter", None, styler_formatter, - validator=is_instance_factory([type(None), dict, callable, str]), + validator=_is_formatter, ) diff --git a/pandas/tests/io/formats/style/test_format.py b/pandas/tests/io/formats/style/test_format.py index 58f18a6959efa..2ed8a1f74f296 100644 --- a/pandas/tests/io/formats/style/test_format.py +++ b/pandas/tests/io/formats/style/test_format.py @@ -298,3 +298,15 @@ def test_format_options(): with option_context("styler.format.formatter", {"int": "{:,.2f}"}): ctx_with_op = df.style._translate(True, True) assert ctx_with_op["body"][0][1]["display_value"] == "2,000.00" + + +def test_format_options_validator(): + df = DataFrame([[9]]) + with option_context("styler.format.formatter", lambda x: f"{x:.3f}"): + assert " 9.000 " in df.style.to_latex() + with option_context("styler.format.formatter", "{:.2f}"): + assert " 9.00 " in df.style.to_latex() + with option_context("styler.format.formatter", {0: "{:.1f}"}): + assert " 9.0 " in df.style.to_latex() + with option_context("styler.format.formatter", None): + assert " 9 " in df.style.to_latex() From d42fdacd97ad9b5d261d8bec116598b26b327c29 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Wed, 1 Sep 2021 18:18:44 +0200 Subject: [PATCH 2/6] add to tests --- pandas/core/config_init.py | 2 +- pandas/tests/io/formats/style/test_format.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 21ecb74cfb93f..c5da4bf05b4df 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -796,7 +796,7 @@ def register_converter_cb(key): def _is_formatter(x): if not (x is None or callable(x) or isinstance(x, (dict, str))): - return ValueError("Value must have type 'callable, dict, str' or None.") + raise ValueError("Value must have type 'callable, dict, str' or None.") with cf.config_prefix("styler"): diff --git a/pandas/tests/io/formats/style/test_format.py b/pandas/tests/io/formats/style/test_format.py index 2ed8a1f74f296..c352e495368b4 100644 --- a/pandas/tests/io/formats/style/test_format.py +++ b/pandas/tests/io/formats/style/test_format.py @@ -310,3 +310,8 @@ def test_format_options_validator(): assert " 9.0 " in df.style.to_latex() with option_context("styler.format.formatter", None): assert " 9 " in df.style.to_latex() + + msg = "Value must have type" + with pytest.raises(ValueError, match=msg): + with option_context("styler.format.formatter", ["bad", "type"]): + df.style.to_latex() From fe30ac7b7ddd75cfc7e860211199f896b24c5f18 Mon Sep 17 00:00:00 2001 From: Thomas Li <47963215+lithomas1@users.noreply.github.com> Date: Wed, 1 Sep 2021 09:15:35 -0700 Subject: [PATCH 3/6] CI: Revive Banklist Tests (#42889) (cherry picked from commit 998117229ad665dca63a35e5b324eadcef59f88b) --- doc/source/user_guide/io.rst | 12 +++++++----- pandas/tests/io/test_html.py | 26 ++++++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/doc/source/user_guide/io.rst b/doc/source/user_guide/io.rst index 1f1556123db17..4c7b13bcf989f 100644 --- a/doc/source/user_guide/io.rst +++ b/doc/source/user_guide/io.rst @@ -2502,14 +2502,16 @@ Read a URL with no options: .. ipython:: python - url = ( - "https://raw.githubusercontent.com/pandas-dev/pandas/master/" - "pandas/tests/io/data/html/spam.html" - ) + url = "https://www.fdic.gov/resources/resolutions/bank-failures/failed-bank-list" dfs = pd.read_html(url) dfs -Read in the content of the "banklist.html" file and pass it to ``read_html`` +.. note:: + + The data from the above URL changes every Monday so the resulting data above + and the data below may be slightly different. + +Read in the content of the file from the above URL and pass it to ``read_html`` as a string: .. ipython:: python diff --git a/pandas/tests/io/test_html.py b/pandas/tests/io/test_html.py index f842e4cd58863..1363a0b04ee0a 100644 --- a/pandas/tests/io/test_html.py +++ b/pandas/tests/io/test_html.py @@ -134,28 +134,38 @@ def test_to_html_compat(self): res = self.read_html(out, attrs={"class": "dataframe"}, index_col=0)[0] tm.assert_frame_equal(res, df) - @pytest.mark.xfail(reason="Html file was removed") @tm.network def test_banklist_url_positional_match(self): - url = "https://www.fdic.gov/bank/individual/failed/banklist.html" + url = "http://www.fdic.gov/resources/resolutions/bank-failures/failed-bank-list/index.html" # noqa E501 # Passing match argument as positional should cause a FutureWarning. with tm.assert_produces_warning(FutureWarning): df1 = self.read_html( - url, "First Federal Bank of Florida", attrs={"id": "table"} + # lxml cannot find attrs leave out for now + url, + "First Federal Bank of Florida", # attrs={"class": "dataTable"} ) with tm.assert_produces_warning(FutureWarning): - df2 = self.read_html(url, "Metcalf Bank", attrs={"id": "table"}) + # lxml cannot find attrs leave out for now + df2 = self.read_html( + url, + "Metcalf Bank", + ) # attrs={"class": "dataTable"}) assert_framelist_equal(df1, df2) - @pytest.mark.xfail(reason="Html file was removed") @tm.network def test_banklist_url(self): - url = "https://www.fdic.gov/bank/individual/failed/banklist.html" + url = "http://www.fdic.gov/resources/resolutions/bank-failures/failed-bank-list/index.html" # noqa E501 df1 = self.read_html( - url, match="First Federal Bank of Florida", attrs={"id": "table"} + # lxml cannot find attrs leave out for now + url, + match="First Federal Bank of Florida", # attrs={"class": "dataTable"} ) - df2 = self.read_html(url, match="Metcalf Bank", attrs={"id": "table"}) + # lxml cannot find attrs leave out for now + df2 = self.read_html( + url, + match="Metcalf Bank", + ) # attrs={"class": "dataTable"}) assert_framelist_equal(df1, df2) From 37a9b339f15040e277415dab138cd1b4a844f640 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Thu, 2 Sep 2021 17:40:48 +0200 Subject: [PATCH 4/6] test param --- pandas/tests/io/formats/style/test_format.py | 25 ++++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pandas/tests/io/formats/style/test_format.py b/pandas/tests/io/formats/style/test_format.py index 7c1236c649ea8..89cec09ea7eeb 100644 --- a/pandas/tests/io/formats/style/test_format.py +++ b/pandas/tests/io/formats/style/test_format.py @@ -307,18 +307,23 @@ def test_precision_zero(df): assert ctx["body"][1][2]["display_value"] == "-1" -def test_format_options_validator(): +@pytest.mark.parametrize( + "formatter, exp", + [ + (lambda x: f"{x:.3f}", "9.000"), + ("{:.2f}", "9.00"), + ({0: "{:.1f}"}, "9.0"), + (None, "9"), + ], +) +def test_formatter_options_validator(formatter, exp): df = DataFrame([[9]]) - with option_context("styler.format.formatter", lambda x: f"{x:.3f}"): - assert " 9.000 " in df.style.to_latex() - with option_context("styler.format.formatter", "{:.2f}"): - assert " 9.00 " in df.style.to_latex() - with option_context("styler.format.formatter", {0: "{:.1f}"}): - assert " 9.0 " in df.style.to_latex() - with option_context("styler.format.formatter", None): - assert " 9 " in df.style.to_latex() + with option_context("styler.format.formatter", formatter): + assert f" {exp} " in df.style.to_latex() + +def test_formatter_options_raises(): msg = "Value must have type" with pytest.raises(ValueError, match=msg): with option_context("styler.format.formatter", ["bad", "type"]): - df.style.to_latex() + DataFrame().style.to_latex() From d51ddb67631bef85c562a1738849ba2ac5c4d3e7 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sun, 5 Sep 2021 14:22:27 +0200 Subject: [PATCH 5/6] revert and fix --- pandas/core/config_init.py | 8 ++------ pandas/tests/io/formats/style/test_format.py | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index 093573832ed55..cec8d100e7196 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -10,6 +10,7 @@ """ import os +from typing import Callable import warnings import pandas._config.config as cf @@ -826,11 +827,6 @@ def register_converter_cb(key): """ -def _is_formatter(x): - if not (x is None or callable(x) or isinstance(x, (dict, str))): - raise ValueError("Value must have type 'callable, dict, str' or None.") - - with cf.config_prefix("styler"): cf.register_option("sparse.index", True, styler_sparse_index_doc, validator=is_bool) @@ -885,7 +881,7 @@ def _is_formatter(x): "format.formatter", None, styler_formatter, - validator=_is_formatter, + validator=is_instance_factory([type(None), dict, Callable, str]), ) cf.register_option("html.mathjax", True, styler_mathjax, validator=is_bool) diff --git a/pandas/tests/io/formats/style/test_format.py b/pandas/tests/io/formats/style/test_format.py index 4113432b95044..7ecd8ffec3bea 100644 --- a/pandas/tests/io/formats/style/test_format.py +++ b/pandas/tests/io/formats/style/test_format.py @@ -324,7 +324,7 @@ def test_formatter_options_validator(formatter, exp): def test_formatter_options_raises(): - msg = "Value must have type" + msg = "Value must be an instance of" with pytest.raises(ValueError, match=msg): with option_context("styler.format.formatter", ["bad", "type"]): DataFrame().style.to_latex() From 2fb4e2cd4b31bb142866b1acc750ed3c472823a9 Mon Sep 17 00:00:00 2001 From: "JHM Darbyshire (iMac)" Date: Sun, 5 Sep 2021 14:23:06 +0200 Subject: [PATCH 6/6] revert and fix --- pandas/core/config_init.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/config_init.py b/pandas/core/config_init.py index cec8d100e7196..83e5f890ff3c7 100644 --- a/pandas/core/config_init.py +++ b/pandas/core/config_init.py @@ -826,7 +826,6 @@ def register_converter_cb(key): will not be used in Jupyter Notebook. """ - with cf.config_prefix("styler"): cf.register_option("sparse.index", True, styler_sparse_index_doc, validator=is_bool)