From 26412353a0239cfc926dcfbc16a9ad567e968619 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 28 Oct 2023 15:29:00 -0700 Subject: [PATCH] REF: misplaced formatting tests (#55740) * misplaced tests * move info tests * misplaced info tests * rename * rename * misplaced repr_html tests * Comment --- .../formats => frame/methods}/test_info.py | 14 + .../frame/{test_repr_info.py => test_repr.py} | 29 +- pandas/tests/indexes/multi/test_formats.py | 10 + .../tests/io/formats/test_eng_formatting.py | 14 + pandas/tests/io/formats/test_format.py | 365 +++--------------- pandas/tests/io/formats/test_printing.py | 14 +- pandas/tests/io/formats/test_to_html.py | 255 ++++++++++-- pandas/tests/scalar/timedelta/test_formats.py | 65 ++++ .../methods/test_info.py} | 0 9 files changed, 385 insertions(+), 381 deletions(-) rename pandas/tests/{io/formats => frame/methods}/test_info.py (97%) rename pandas/tests/frame/{test_repr_info.py => test_repr.py} (95%) rename pandas/tests/{io/formats/test_series_info.py => series/methods/test_info.py} (100%) diff --git a/pandas/tests/io/formats/test_info.py b/pandas/tests/frame/methods/test_info.py similarity index 97% rename from pandas/tests/io/formats/test_info.py rename to pandas/tests/frame/methods/test_info.py index 6c3bf01cb1857..7d7f436e3cfe6 100644 --- a/pandas/tests/io/formats/test_info.py +++ b/pandas/tests/frame/methods/test_info.py @@ -71,6 +71,7 @@ def test_info_categorical_column_smoke_test(): "float_frame", "datetime_frame", "duplicate_columns_frame", + "float_string_frame", ], ) def test_info_smoke_test(fixture_func_name, request): @@ -80,6 +81,19 @@ def test_info_smoke_test(fixture_func_name, request): result = buf.getvalue().splitlines() assert len(result) > 10 + buf = StringIO() + frame.info(buf=buf, verbose=False) + + +def test_info_smoke_test2(float_frame): + # pretty useless test, used to be mixed into the repr tests + buf = StringIO() + float_frame.reindex(columns=["A"]).info(verbose=False, buf=buf) + float_frame.reindex(columns=["A", "B"]).info(verbose=False, buf=buf) + + # no columns or index + DataFrame().info(buf=buf) + @pytest.mark.parametrize( "num_columns, max_info_columns, verbose", diff --git a/pandas/tests/frame/test_repr_info.py b/pandas/tests/frame/test_repr.py similarity index 95% rename from pandas/tests/frame/test_repr_info.py rename to pandas/tests/frame/test_repr.py index 23aef9ba7d18d..cccb4216a7941 100644 --- a/pandas/tests/frame/test_repr_info.py +++ b/pandas/tests/frame/test_repr.py @@ -25,7 +25,7 @@ import pandas.io.formats.format as fmt -class TestDataFrameReprInfoEtc: +class TestDataFrameRepr: def test_repr_bytes_61_lines(self): # GH#12857 lets = list("ACDEFGHIJKLMNOP") @@ -141,11 +141,8 @@ def test_repr_empty(self): repr(frame) def test_repr_mixed(self, float_string_frame): - buf = StringIO() - # mixed repr(float_string_frame) - float_string_frame.info(verbose=False, buf=buf) @pytest.mark.slow def test_repr_mixed_big(self): @@ -162,26 +159,11 @@ def test_repr_mixed_big(self): repr(biggie) - def test_repr(self, float_frame): - buf = StringIO() - - # small one - repr(float_frame) - float_frame.info(verbose=False, buf=buf) - - # even smaller - float_frame.reindex(columns=["A"]).info(verbose=False, buf=buf) - float_frame.reindex(columns=["A", "B"]).info(verbose=False, buf=buf) - - # exhausting cases in DataFrame.info - + def test_repr(self): # columns but no index no_index = DataFrame(columns=[0, 1, 3]) repr(no_index) - # no columns or index - DataFrame().info(buf=buf) - df = DataFrame(["a\n\r\tb"], columns=["a\n\r\td"], index=["a\n\r\tf"]) assert "\t" not in repr(df) assert "\r" not in repr(df) @@ -204,7 +186,7 @@ def test_repr_big(self): biggie = DataFrame(np.zeros((200, 4)), columns=range(4), index=range(200)) repr(biggie) - def test_repr_unsortable(self, float_frame): + def test_repr_unsortable(self): # columns are not sortable unsortable = DataFrame( @@ -218,6 +200,9 @@ def test_repr_unsortable(self, float_frame): ) repr(unsortable) + def test_repr_float_frame_options(self, float_frame): + repr(float_frame) + fmt.set_option("display.precision", 3) repr(float_frame) @@ -257,7 +242,7 @@ def test_str_to_bytes_raises(self): with pytest.raises(TypeError, match=msg): bytes(df) - def test_very_wide_info_repr(self): + def test_very_wide_repr(self): df = DataFrame( np.random.default_rng(2).standard_normal((10, 20)), columns=np.array(["a" * 10] * 20, dtype=object), diff --git a/pandas/tests/indexes/multi/test_formats.py b/pandas/tests/indexes/multi/test_formats.py index bbe94824eefa1..1736f65e355fb 100644 --- a/pandas/tests/indexes/multi/test_formats.py +++ b/pandas/tests/indexes/multi/test_formats.py @@ -229,3 +229,13 @@ def test_tuple_width(self, wide_multi_index): ('abc', 10, '2000-01-01 00:33:19', '2000-01-01 00:33:19', ...)], names=['a', 'b', 'dti_1', 'dti_2', 'dti_3'], length=2000)""" assert result == expected + + def test_multiindex_long_element(self): + # Non-regression test towards GH#52960 + data = MultiIndex.from_tuples([("c" * 62,)]) + + expected = ( + "MultiIndex([('cccccccccccccccccccccccccccccccccccccccc" + "cccccccccccccccccccccc',)],\n )" + ) + assert str(data) == expected diff --git a/pandas/tests/io/formats/test_eng_formatting.py b/pandas/tests/io/formats/test_eng_formatting.py index 2f18623559557..75e63cb1f6b54 100644 --- a/pandas/tests/io/formats/test_eng_formatting.py +++ b/pandas/tests/io/formats/test_eng_formatting.py @@ -7,6 +7,20 @@ class TestEngFormatter: + def test_eng_float_formatter2(self, float_frame): + df = float_frame + df.loc[5] = 0 + + fmt.set_eng_float_format() + repr(df) + + fmt.set_eng_float_format(use_eng_prefix=True) + repr(df) + + fmt.set_eng_float_format(accuracy=0) + repr(df) + tm.reset_display_options() + def test_eng_float_formatter(self): df = DataFrame({"A": [1.41, 141.0, 14100, 1410000.0]}) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 231beb4abd8ba..421ca8eb58b50 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -6,12 +6,10 @@ timedelta, ) from io import StringIO -import itertools from pathlib import Path import re from shutil import get_terminal_size import sys -import textwrap import numpy as np import pytest @@ -146,20 +144,6 @@ def has_expanded_repr(df): class TestDataFrameFormatting: - def test_eng_float_formatter(self, float_frame): - df = float_frame - df.loc[5] = 0 - - fmt.set_eng_float_format() - repr(df) - - fmt.set_eng_float_format(use_eng_prefix=True) - repr(df) - - fmt.set_eng_float_format(accuracy=0) - repr(df) - tm.reset_display_options() - @pytest.mark.parametrize( "row, columns, show_counts, result", [ @@ -1843,145 +1827,6 @@ def test_show_dimensions(self): assert "5 rows" not in str(df) assert "5 rows" not in df._repr_html_() - def test_repr_html(self, float_frame): - df = float_frame - df._repr_html_() - - with option_context("display.max_rows", 1, "display.max_columns", 1): - df._repr_html_() - - with option_context("display.notebook_repr_html", False): - df._repr_html_() - - tm.reset_display_options() - - df = DataFrame([[1, 2], [3, 4]]) - with option_context("display.show_dimensions", True): - assert "2 rows" in df._repr_html_() - with option_context("display.show_dimensions", False): - assert "2 rows" not in df._repr_html_() - - tm.reset_display_options() - - def test_repr_html_mathjax(self): - df = DataFrame([[1, 2], [3, 4]]) - assert "tex2jax_ignore" not in df._repr_html_() - - with option_context("display.html.use_mathjax", False): - assert "tex2jax_ignore" in df._repr_html_() - - def test_repr_html_wide(self): - max_cols = 20 - df = DataFrame([["a" * 25] * (max_cols - 1)] * 10) - with option_context("display.max_rows", 60, "display.max_columns", 20): - assert "..." not in df._repr_html_() - - wide_df = DataFrame([["a" * 25] * (max_cols + 1)] * 10) - with option_context("display.max_rows", 60, "display.max_columns", 20): - assert "..." in wide_df._repr_html_() - - def test_repr_html_wide_multiindex_cols(self): - max_cols = 20 - - mcols = MultiIndex.from_product( - [np.arange(max_cols // 2), ["foo", "bar"]], names=["first", "second"] - ) - df = DataFrame([["a" * 25] * len(mcols)] * 10, columns=mcols) - reg_repr = df._repr_html_() - assert "..." not in reg_repr - - mcols = MultiIndex.from_product( - (np.arange(1 + (max_cols // 2)), ["foo", "bar"]), names=["first", "second"] - ) - df = DataFrame([["a" * 25] * len(mcols)] * 10, columns=mcols) - with option_context("display.max_rows", 60, "display.max_columns", 20): - assert "..." in df._repr_html_() - - def test_repr_html_long(self): - with option_context("display.max_rows", 60): - max_rows = get_option("display.max_rows") - h = max_rows - 1 - df = DataFrame({"A": np.arange(1, 1 + h), "B": np.arange(41, 41 + h)}) - reg_repr = df._repr_html_() - assert ".." not in reg_repr - assert str(41 + max_rows // 2) in reg_repr - - h = max_rows + 1 - df = DataFrame({"A": np.arange(1, 1 + h), "B": np.arange(41, 41 + h)}) - long_repr = df._repr_html_() - assert ".." in long_repr - assert str(41 + max_rows // 2) not in long_repr - assert f"{h} rows " in long_repr - assert "2 columns" in long_repr - - def test_repr_html_float(self): - with option_context("display.max_rows", 60): - max_rows = get_option("display.max_rows") - h = max_rows - 1 - df = DataFrame( - { - "idx": np.linspace(-10, 10, h), - "A": np.arange(1, 1 + h), - "B": np.arange(41, 41 + h), - } - ).set_index("idx") - reg_repr = df._repr_html_() - assert ".." not in reg_repr - assert f"{40 + h}" in reg_repr - - h = max_rows + 1 - df = DataFrame( - { - "idx": np.linspace(-10, 10, h), - "A": np.arange(1, 1 + h), - "B": np.arange(41, 41 + h), - } - ).set_index("idx") - long_repr = df._repr_html_() - assert ".." in long_repr - assert "31" not in long_repr - assert f"{h} rows " in long_repr - assert "2 columns" in long_repr - - def test_repr_html_long_multiindex(self): - max_rows = 60 - max_L1 = max_rows // 2 - - tuples = list(itertools.product(np.arange(max_L1), ["foo", "bar"])) - idx = MultiIndex.from_tuples(tuples, names=["first", "second"]) - df = DataFrame( - np.random.default_rng(2).standard_normal((max_L1 * 2, 2)), - index=idx, - columns=["A", "B"], - ) - with option_context("display.max_rows", 60, "display.max_columns", 20): - reg_repr = df._repr_html_() - assert "..." not in reg_repr - - tuples = list(itertools.product(np.arange(max_L1 + 1), ["foo", "bar"])) - idx = MultiIndex.from_tuples(tuples, names=["first", "second"]) - df = DataFrame( - np.random.default_rng(2).standard_normal(((max_L1 + 1) * 2, 2)), - index=idx, - columns=["A", "B"], - ) - long_repr = df._repr_html_() - assert "..." in long_repr - - def test_repr_html_long_and_wide(self): - max_cols = 20 - max_rows = 60 - - h, w = max_rows - 1, max_cols - 1 - df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) - with option_context("display.max_rows", 60, "display.max_columns", 20): - assert "..." not in df._repr_html_() - - h, w = max_rows + 1, max_cols + 1 - df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) - with option_context("display.max_rows", 60, "display.max_columns", 20): - assert "..." in df._repr_html_() - def test_info_repr(self): # GH#21746 For tests inside a terminal (i.e. not CI) we need to detect # the terminal size to ensure that we try to print something "too big" @@ -2028,43 +1873,10 @@ def test_info_repr_max_cols(self): ): assert not has_non_verbose_info_repr(df) + # FIXME: don't leave commented-out # test verbose overrides # set_option('display.max_info_columns', 4) # exceeded - def test_info_repr_html(self): - max_rows = 60 - max_cols = 20 - # Long - h, w = max_rows + 1, max_cols - 1 - df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) - assert r"<class" not in df._repr_html_() - with option_context("display.large_repr", "info"): - assert r"<class" in df._repr_html_() - - # Wide - h, w = max_rows - 1, max_cols + 1 - df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) - assert " never truncate + (None, 12, "html_repr_max_rows_None_min_rows_12"), + ], + ) + def test_html_repr_min_rows(self, datapath, max_rows, min_rows, expected): + # gh-27991 + + df = DataFrame({"a": range(61)}) + expected = expected_html(datapath, expected) + with option_context("display.max_rows", max_rows, "display.min_rows", min_rows): + result = df._repr_html_() + assert result == expected + + def test_repr_html_ipython_config(self, ip): + code = textwrap.dedent( + """\ + from pandas import DataFrame + df = DataFrame({"A": [1, 2]}) + df._repr_html_() + + cfg = get_ipython().config + cfg['IPKernelApp']['parent_appname'] + df._repr_html_() + """ + ) + result = ip.run_cell(code, silent=True) + assert not result.error_in_exec -@pytest.mark.parametrize( - "max_rows,min_rows,expected", - [ - # truncated after first two rows - (10, 4, "html_repr_max_rows_10_min_rows_4"), - # when set to None, follow value of max_rows - (12, None, "html_repr_max_rows_12_min_rows_None"), - # when set value higher as max_rows, use the minimum - (10, 12, "html_repr_max_rows_10_min_rows_12"), - # max_rows of None -> never truncate - (None, 12, "html_repr_max_rows_None_min_rows_12"), - ], -) -def test_html_repr_min_rows(datapath, max_rows, min_rows, expected): - # gh-27991 + def test_info_repr_html(self): + max_rows = 60 + max_cols = 20 + # Long + h, w = max_rows + 1, max_cols - 1 + df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) + assert r"<class" not in df._repr_html_() + with option_context("display.large_repr", "info"): + assert r"<class" in df._repr_html_() - df = DataFrame({"a": range(61)}) - expected = expected_html(datapath, expected) - with option_context("display.max_rows", max_rows, "display.min_rows", min_rows): - result = df._repr_html_() - assert result == expected + # Wide + h, w = max_rows - 1, max_cols + 1 + df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) + assert "{40 + h}" in reg_repr + + h = max_rows + 1 + df = DataFrame( + { + "idx": np.linspace(-10, 10, h), + "A": np.arange(1, 1 + h), + "B": np.arange(41, 41 + h), + } + ).set_index("idx") + long_repr = df._repr_html_() + assert ".." in long_repr + assert "31" not in long_repr + assert f"{h} rows " in long_repr + assert "2 columns" in long_repr + + def test_repr_html_long_multiindex(self): + max_rows = 60 + max_L1 = max_rows // 2 + + tuples = list(itertools.product(np.arange(max_L1), ["foo", "bar"])) + idx = MultiIndex.from_tuples(tuples, names=["first", "second"]) + df = DataFrame( + np.random.default_rng(2).standard_normal((max_L1 * 2, 2)), + index=idx, + columns=["A", "B"], + ) + with option_context("display.max_rows", 60, "display.max_columns", 20): + reg_repr = df._repr_html_() + assert "..." not in reg_repr + + tuples = list(itertools.product(np.arange(max_L1 + 1), ["foo", "bar"])) + idx = MultiIndex.from_tuples(tuples, names=["first", "second"]) + df = DataFrame( + np.random.default_rng(2).standard_normal(((max_L1 + 1) * 2, 2)), + index=idx, + columns=["A", "B"], + ) + long_repr = df._repr_html_() + assert "..." in long_repr + + def test_repr_html_long_and_wide(self): + max_cols = 20 + max_rows = 60 + + h, w = max_rows - 1, max_cols - 1 + df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) + with option_context("display.max_rows", 60, "display.max_columns", 20): + assert "..." not in df._repr_html_() + + h, w = max_rows + 1, max_cols + 1 + df = DataFrame({k: np.arange(1, 1 + h) for k in np.arange(w)}) + with option_context("display.max_rows", 60, "display.max_columns", 20): + assert "..." in df._repr_html_() def test_to_html_multilevel(multiindex_year_month_day_dataframe_random_data): diff --git a/pandas/tests/scalar/timedelta/test_formats.py b/pandas/tests/scalar/timedelta/test_formats.py index 753186ee4b738..e1b0076d5b7b9 100644 --- a/pandas/tests/scalar/timedelta/test_formats.py +++ b/pandas/tests/scalar/timedelta/test_formats.py @@ -42,3 +42,68 @@ def test_repr(td, expected_repr): ) def test_isoformat(td, expected_iso): assert td.isoformat() == expected_iso + + +class TestReprBase: + def test_none(self): + delta_1d = Timedelta(1, unit="D") + delta_0d = Timedelta(0, unit="D") + delta_1s = Timedelta(1, unit="s") + delta_500ms = Timedelta(500, unit="ms") + + drepr = lambda x: x._repr_base() + assert drepr(delta_1d) == "1 days" + assert drepr(-delta_1d) == "-1 days" + assert drepr(delta_0d) == "0 days" + assert drepr(delta_1s) == "0 days 00:00:01" + assert drepr(delta_500ms) == "0 days 00:00:00.500000" + assert drepr(delta_1d + delta_1s) == "1 days 00:00:01" + assert drepr(-delta_1d + delta_1s) == "-1 days +00:00:01" + assert drepr(delta_1d + delta_500ms) == "1 days 00:00:00.500000" + assert drepr(-delta_1d + delta_500ms) == "-1 days +00:00:00.500000" + + def test_sub_day(self): + delta_1d = Timedelta(1, unit="D") + delta_0d = Timedelta(0, unit="D") + delta_1s = Timedelta(1, unit="s") + delta_500ms = Timedelta(500, unit="ms") + + drepr = lambda x: x._repr_base(format="sub_day") + assert drepr(delta_1d) == "1 days" + assert drepr(-delta_1d) == "-1 days" + assert drepr(delta_0d) == "00:00:00" + assert drepr(delta_1s) == "00:00:01" + assert drepr(delta_500ms) == "00:00:00.500000" + assert drepr(delta_1d + delta_1s) == "1 days 00:00:01" + assert drepr(-delta_1d + delta_1s) == "-1 days +00:00:01" + assert drepr(delta_1d + delta_500ms) == "1 days 00:00:00.500000" + assert drepr(-delta_1d + delta_500ms) == "-1 days +00:00:00.500000" + + def test_long(self): + delta_1d = Timedelta(1, unit="D") + delta_0d = Timedelta(0, unit="D") + delta_1s = Timedelta(1, unit="s") + delta_500ms = Timedelta(500, unit="ms") + + drepr = lambda x: x._repr_base(format="long") + assert drepr(delta_1d) == "1 days 00:00:00" + assert drepr(-delta_1d) == "-1 days +00:00:00" + assert drepr(delta_0d) == "0 days 00:00:00" + assert drepr(delta_1s) == "0 days 00:00:01" + assert drepr(delta_500ms) == "0 days 00:00:00.500000" + assert drepr(delta_1d + delta_1s) == "1 days 00:00:01" + assert drepr(-delta_1d + delta_1s) == "-1 days +00:00:01" + assert drepr(delta_1d + delta_500ms) == "1 days 00:00:00.500000" + assert drepr(-delta_1d + delta_500ms) == "-1 days +00:00:00.500000" + + def test_all(self): + delta_1d = Timedelta(1, unit="D") + delta_0d = Timedelta(0, unit="D") + delta_1ns = Timedelta(1, unit="ns") + + drepr = lambda x: x._repr_base(format="all") + assert drepr(delta_1d) == "1 days 00:00:00.000000000" + assert drepr(-delta_1d) == "-1 days +00:00:00.000000000" + assert drepr(delta_0d) == "0 days 00:00:00.000000000" + assert drepr(delta_1ns) == "0 days 00:00:00.000000001" + assert drepr(-delta_1d + delta_1ns) == "-1 days +00:00:00.000000001" diff --git a/pandas/tests/io/formats/test_series_info.py b/pandas/tests/series/methods/test_info.py similarity index 100% rename from pandas/tests/io/formats/test_series_info.py rename to pandas/tests/series/methods/test_info.py