From 7739fda2c8dfdce7fa67bf867db2ef14f0a10fff Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Fri, 1 Nov 2024 12:20:27 +0100 Subject: [PATCH 01/24] feat(python): Add show methods to DataFrame and LazyFrame --- py-polars/polars/dataframe/frame.py | 57 +++++++++++++++++++++++++++++ py-polars/polars/lazyframe/frame.py | 52 ++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 0eebc0f52a2c..d5a3bdbb696b 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -46,6 +46,7 @@ from polars._utils.serde import serialize_polars_object from polars._utils.unstable import issue_unstable_warning, unstable from polars._utils.various import ( + _in_notebook, is_bool_sequence, no_default, normalize_filepath, @@ -11664,6 +11665,62 @@ def melt( value_name=value_name, ) + def show(self, n: int = 5) -> None: + """ + Show the first `n` rows. + + Parameters + ---------- + n + Numbers of rows to show. If a negative value is passed, return all rows + except the last `abs(n)`. + + See Also + -------- + head + + Examples + -------- + >>> df = pl.DataFrame( + ... { + ... "foo": [1, 2, 3, 4, 5], + ... "bar": [6, 7, 8, 9, 10], + ... "ham": ["a", "b", "c", "d", "e"], + ... } + ... ) + >>> df.show(3) + shape: (3, 3) + ┌─────┬─────┬─────┐ + │ foo ┆ bar ┆ ham │ + │ --- ┆ --- ┆ --- │ + │ i64 ┆ i64 ┆ str │ + ╞═════╪═════╪═════╡ + │ 1 ┆ 6 ┆ a │ + │ 2 ┆ 7 ┆ b │ + │ 3 ┆ 8 ┆ c │ + └─────┴─────┴─────┘ + + Pass a negative value to get all rows `except` the last `abs(n)`. + + >>> df.show(-3) + shape: (2, 3) + ┌─────┬─────┬─────┐ + │ foo ┆ bar ┆ ham │ + │ --- ┆ --- ┆ --- │ + │ i64 ┆ i64 ┆ str │ + ╞═════╪═════╪═════╡ + │ 1 ┆ 6 ┆ a │ + │ 2 ┆ 7 ┆ b │ + └─────┴─────┴─────┘ + """ + show_result = self.head(n) + if _in_notebook(): + from IPython.display import display_html + + display_html(show_result) + else: + print(show_result) + def _to_metadata( self, columns: None | str | list[str] = None, diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 3abfeb6c95b2..7b720e6ec7d2 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7286,6 +7286,58 @@ def melt( streamable=streamable, ) + def show(self, n: int = 5) -> None: + """ + Show the first `n` rows. + + Parameters + ---------- + n + Number of rows to return. + + Warnings + -------- + * This method does *not* maintain the laziness of the frame, and will `collect` + the final result. This could potentially be an expensive operation. + + Examples + -------- + >>> lf = pl.LazyFrame( + ... { + ... "a": [1, 2, 3, 4, 5, 6], + ... "b": [7, 8, 9, 10, 11, 12], + ... } + ... ) + >>> lf.show() + ┌─────┬─────┐ + │ a ┆ b │ + │ --- ┆ --- │ + │ i64 ┆ i64 │ + ╞═════╪═════╡ + │ 1 ┆ 7 │ + │ 2 ┆ 8 │ + │ 3 ┆ 9 │ + │ 4 ┆ 10 │ + │ 5 ┆ 11 │ + └─────┴─────┘ + >>> lf.show(2) + ┌─────┬─────┐ + │ a ┆ b │ + │ --- ┆ --- │ + │ i64 ┆ i64 │ + ╞═════╪═════╡ + │ 1 ┆ 7 │ + │ 2 ┆ 8 │ + └─────┴─────┘ + """ + show_result = self.head(n).collect() + if _in_notebook(): + from IPython.display import display_html + + display_html(show_result) + else: + print(show_result) + def _to_metadata( self, columns: None | str | list[str] = None, From 05a61b79208411765c0533a140146f2223e6522c Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Mon, 4 Nov 2024 19:07:22 +0100 Subject: [PATCH 02/24] refine implementation and add tests --- py-polars/polars/dataframe/frame.py | 45 +++- py-polars/polars/lazyframe/frame.py | 42 +++- py-polars/tests/unit/dataframe/test_show.py | 225 ++++++++++++++++++++ py-polars/tests/unit/lazyframe/test_show.py | 27 +++ 4 files changed, 321 insertions(+), 18 deletions(-) create mode 100644 py-polars/tests/unit/dataframe/test_show.py create mode 100644 py-polars/tests/unit/lazyframe/test_show.py diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index d5a3bdbb696b..a2931ce0e22e 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -55,6 +55,7 @@ warn_null_comparison, ) from polars._utils.wrap import wrap_expr, wrap_ldf, wrap_s +from polars.config import Config from polars.dataframe._html import NotebookFormatter from polars.dataframe.group_by import DynamicGroupBy, GroupBy, RollingGroupBy from polars.dataframe.plotting import DataFramePlot @@ -11665,15 +11666,35 @@ def melt( value_name=value_name, ) - def show(self, n: int = 5) -> None: + def show( + self, + n: int = 5, + *, + float_precision: int | None = None, + fmt_str_lengths: int | None = None, + fmt_table_cell_list_len: int | None = None, + tbl_cols: int | None = None, + ) -> None: """ Show the first `n` rows. Parameters ---------- - n + n : int Numbers of rows to show. If a negative value is passed, return all rows except the last `abs(n)`. + float_precision : int + Number of decimal places to display for floating point values. See + :func:`Config.set_float_precision` for more information. + fmt_str_lengths : int + Number of characters to display for string values. See + :func:`Config.set_fmt_str_lengths` for more information. + fmt_table_cell_list_len : int + Number of elements to display for List values. See + :func:`Config.set_fmt_table_cell_list_len` for more information. + tbl_cols : int + Number of columns to display. See :func:`Config.set_tbl_cols` for more + information. See Also -------- @@ -11713,13 +11734,21 @@ def show(self, n: int = 5) -> None: │ 2 ┆ 7 ┆ b │ └─────┴─────┴─────┘ """ - show_result = self.head(n) - if _in_notebook(): - from IPython.display import display_html + df = self.head(n) + with Config( + float_precision=float_precision, + fmt_str_lengths=fmt_str_lengths, + fmt_table_cell_list_len=fmt_table_cell_list_len, + tbl_cols=tbl_cols, + tbl_rows=n, + ): + if _in_notebook(): + print("In notebook") + from IPython.display import display_html - display_html(show_result) - else: - print(show_result) + display_html(df) + else: + print(df) def _to_metadata( self, diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 7b720e6ec7d2..8d0676927549 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7286,14 +7286,34 @@ def melt( streamable=streamable, ) - def show(self, n: int = 5) -> None: + def show( + self, + n: int = 5, + *, + float_precision: int | None = None, + fmt_str_lengths: int | None = None, + fmt_table_cell_list_len: int | None = None, + tbl_cols: int | None = None, + ) -> None: """ Show the first `n` rows. Parameters ---------- - n - Number of rows to return. + n : int + Number of rows to show. + float_precision : int + Number of decimal places to display for floating point values. See + :func:`Config.set_float_precision` for more information. + fmt_str_lengths : int + Number of characters to display for string values. See + :func:`Config.set_fmt_str_lengths` for more information. + fmt_table_cell_list_len : int + Number of elements to display for List values. See + :func:`Config.set_fmt_table_cell_list_len` for more information. + tbl_cols : int + Number of columns to display. See :func:`Config.set_tbl_cols` for more + information. Warnings -------- @@ -7309,6 +7329,7 @@ def show(self, n: int = 5) -> None: ... } ... ) >>> lf.show() + shape: (5, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ @@ -7321,6 +7342,7 @@ def show(self, n: int = 5) -> None: │ 5 ┆ 11 │ └─────┴─────┘ >>> lf.show(2) + shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ │ --- ┆ --- │ @@ -7330,13 +7352,13 @@ def show(self, n: int = 5) -> None: │ 2 ┆ 8 │ └─────┴─────┘ """ - show_result = self.head(n).collect() - if _in_notebook(): - from IPython.display import display_html - - display_html(show_result) - else: - print(show_result) + self.head(n).collect().show( + n, + float_precision=float_precision, + fmt_str_lengths=fmt_str_lengths, + fmt_table_cell_list_len=fmt_table_cell_list_len, + tbl_cols=tbl_cols, + ) def _to_metadata( self, diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py new file mode 100644 index 000000000000..54e29facc04c --- /dev/null +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -0,0 +1,225 @@ +from unittest.mock import patch + +import pytest + +import polars as pl +from polars.testing.asserts import assert_frame_equal + + +@pytest.fixture(name="in_notebook") +def _in_notebook(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setattr("polars.dataframe.frame._in_notebook", lambda: True) + + +def test_df_show_default(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + { + "foo": [1, 2, 3, 4, 5, 6, 7], + "bar": ["a", "b", "c", "d", "e", "f", "g"], + } + ) + df.show() + out, _ = capsys.readouterr() + assert ( + out + == """shape: (5, 2) +┌─────┬─────┐ +│ foo ┆ bar │ +│ --- ┆ --- │ +│ i64 ┆ str │ +╞═════╪═════╡ +│ 1 ┆ a │ +│ 2 ┆ b │ +│ 3 ┆ c │ +│ 4 ┆ d │ +│ 5 ┆ e │ +└─────┴─────┘ +""" + ) + + +def test_df_show_n_rows(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + { + "foo": [1, 2, 3, 4, 5, 6, 7], + "bar": ["a", "b", "c", "d", "e", "f", "g"], + } + ) + df.show(3) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +┌─────┬─────┐ +│ foo ┆ bar │ +│ --- ┆ --- │ +│ i64 ┆ str │ +╞═════╪═════╡ +│ 1 ┆ a │ +│ 2 ┆ b │ +│ 3 ┆ c │ +└─────┴─────┘ +""" + ) + + +def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: + from math import e, pi + + df = pl.DataFrame({"const": ["pi", "e"], "value": [pi, e]}) + df.show(float_precision=15) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) +┌───────┬───────────────────┐ +│ const ┆ value │ +│ --- ┆ --- │ +│ str ┆ f64 │ +╞═══════╪═══════════════════╡ +│ pi ┆ 3.141592653589793 │ +│ e ┆ 2.718281828459045 │ +└───────┴───────────────────┘ +""" + ) + + df.show(float_precision=3) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) +┌───────┬───────┐ +│ const ┆ value │ +│ --- ┆ --- │ +│ str ┆ f64 │ +╞═══════╪═══════╡ +│ pi ┆ 3.142 │ +│ e ┆ 2.718 │ +└───────┴───────┘ +""" + ) + + +def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + { + "txt": [ + "Play it, Sam. Play 'As Time Goes By'.", + "This is the beginning of a beautiful friendship.", + ] + } + ) + df.show(fmt_str_lengths=10) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 1) +┌─────────────┐ +│ txt │ +│ --- │ +│ str │ +╞═════════════╡ +│ Play it, S… │ +│ This is th… │ +└─────────────┘ +""" + ) + df.show(fmt_str_lengths=50) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 1) +┌──────────────────────────────────────────────────┐ +│ txt │ +│ --- │ +│ str │ +╞══════════════════════════════════════════════════╡ +│ Play it, Sam. Play 'As Time Goes By'. │ +│ This is the beginning of a beautiful friendship. │ +└──────────────────────────────────────────────────┘ +""" + ) + + +def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"nums": [list(range(10))]}) + + df.show(fmt_table_cell_list_len=2) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 1) +┌───────────┐ +│ nums │ +│ --- │ +│ list[i64] │ +╞═══════════╡ +│ [0, … 9] │ +└───────────┘ +""" + ) + + df.show(fmt_table_cell_list_len=8) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 1) +┌────────────────────────────┐ +│ nums │ +│ --- │ +│ list[i64] │ +╞════════════════════════════╡ +│ [0, 1, 2, 3, 4, 5, 6, … 9] │ +└────────────────────────────┘ +""" + ) + + +def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({str(i): [i] for i in range(10)}) + + df.show(tbl_cols=3) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 10) +┌─────┬─────┬───┬─────┐ +│ 0 ┆ 1 ┆ … ┆ 9 │ +│ --- ┆ --- ┆ ┆ --- │ +│ i64 ┆ i64 ┆ ┆ i64 │ +╞═════╪═════╪═══╪═════╡ +│ 0 ┆ 1 ┆ … ┆ 9 │ +└─────┴─────┴───┴─────┘ +""" + ) + + df.show(tbl_cols=7) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 10) +┌─────┬─────┬─────┬─────┬───┬─────┬─────┬─────┐ +│ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ +│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- │ +│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ ┆ i64 ┆ i64 ┆ i64 │ +╞═════╪═════╪═════╪═════╪═══╪═════╪═════╪═════╡ +│ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ +└─────┴─────┴─────┴─────┴───┴─────┴─────┴─────┘ +""" + ) + + +@pytest.mark.usefixtures("in_notebook") +def test_df_show_in_notebook(monkeypatch: pytest.MonkeyPatch) -> None: + with patch("IPython.display.display_html") as display_html: + df = pl.DataFrame( + { + "foo": [1, 2, 3, 4, 5, 6, 7], + "bar": ["a", "b", "c", "d", "e", "f", "g"], + } + ) + df.show(7) + display_html.assert_called_once() + args, _ = display_html.call_args + assert len(args) == 1 + assert_frame_equal(args[0], df) diff --git a/py-polars/tests/unit/lazyframe/test_show.py b/py-polars/tests/unit/lazyframe/test_show.py new file mode 100644 index 000000000000..9363390f10b1 --- /dev/null +++ b/py-polars/tests/unit/lazyframe/test_show.py @@ -0,0 +1,27 @@ +from inspect import signature +from unittest.mock import patch + +import polars as pl + + +def test_show_signature_match() -> None: + assert signature(pl.LazyFrame.show) == signature(pl.DataFrame.show) + + +def test_lf_show_calls_df_show() -> None: + lf = pl.LazyFrame( + { + "foo": ["a", "b", "c", "d", "e", "f", "g"], + "bar": [1, 2, 3, 4, 5, 6, 7], + } + ) + with patch.object(pl.DataFrame, "show") as df_show: + lf.show(5) + + df_show.assert_called_once_with( + 5, + float_precision=None, + fmt_str_lengths=None, + fmt_table_cell_list_len=None, + tbl_cols=None, + ) From 45f8fbf0d770164fab35d5b283097e5c015b50e9 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Tue, 5 Nov 2024 12:43:01 +0100 Subject: [PATCH 03/24] remove show_in_notebook test --- py-polars/tests/unit/dataframe/test_show.py | 24 --------------------- 1 file changed, 24 deletions(-) diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 54e29facc04c..0c6dba346e5e 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -1,14 +1,6 @@ -from unittest.mock import patch - import pytest import polars as pl -from polars.testing.asserts import assert_frame_equal - - -@pytest.fixture(name="in_notebook") -def _in_notebook(monkeypatch: pytest.MonkeyPatch) -> None: - monkeypatch.setattr("polars.dataframe.frame._in_notebook", lambda: True) def test_df_show_default(capsys: pytest.CaptureFixture[str]) -> None: @@ -207,19 +199,3 @@ def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: └─────┴─────┴─────┴─────┴───┴─────┴─────┴─────┘ """ ) - - -@pytest.mark.usefixtures("in_notebook") -def test_df_show_in_notebook(monkeypatch: pytest.MonkeyPatch) -> None: - with patch("IPython.display.display_html") as display_html: - df = pl.DataFrame( - { - "foo": [1, 2, 3, 4, 5, 6, 7], - "bar": ["a", "b", "c", "d", "e", "f", "g"], - } - ) - df.show(7) - display_html.assert_called_once() - args, _ = display_html.call_args - assert len(args) == 1 - assert_frame_equal(args[0], df) From 54d8da96d77324f1bce76ccd8964366be084bed5 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Tue, 5 Nov 2024 20:30:59 +0100 Subject: [PATCH 04/24] refactor: replace `n` with `limit` Refactor both `show` methods to use a limit rather than a number of rows to show. The `limit` parameter is an extension of the `n` number of rows parameter, and can be set to None. In that case, the `show` method will display all frame rows. --- py-polars/polars/dataframe/frame.py | 19 +++++-- py-polars/polars/lazyframe/frame.py | 19 +++++-- py-polars/tests/unit/dataframe/test_show.py | 55 ++++++++++++++++++++- py-polars/tests/unit/lazyframe/test_show.py | 16 +++--- 4 files changed, 93 insertions(+), 16 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index a2931ce0e22e..e578485d3f2c 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11668,7 +11668,7 @@ def melt( def show( self, - n: int = 5, + limit: int | None = 5, *, float_precision: int | None = None, fmt_str_lengths: int | None = None, @@ -11680,9 +11680,9 @@ def show( Parameters ---------- - n : int + limit : int Numbers of rows to show. If a negative value is passed, return all rows - except the last `abs(n)`. + except the last `abs(n)`. If None is passed, return all rows. float_precision : int Number of decimal places to display for floating point values. See :func:`Config.set_float_precision` for more information. @@ -11734,13 +11734,22 @@ def show( │ 2 ┆ 7 ┆ b │ └─────┴─────┴─────┘ """ - df = self.head(n) + if limit is None: + df = self + tbl_rows = self.height + else: + df = self.head(limit) + if limit < 0: + tbl_rows = self.height - abs(limit) + else: + tbl_rows = limit + with Config( float_precision=float_precision, fmt_str_lengths=fmt_str_lengths, fmt_table_cell_list_len=fmt_table_cell_list_len, tbl_cols=tbl_cols, - tbl_rows=n, + tbl_rows=tbl_rows, ): if _in_notebook(): print("In notebook") diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 8d0676927549..33be2d531730 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7288,7 +7288,7 @@ def melt( def show( self, - n: int = 5, + limit: int | None = 5, *, float_precision: int | None = None, fmt_str_lengths: int | None = None, @@ -7301,7 +7301,7 @@ def show( Parameters ---------- n : int - Number of rows to show. + Number of rows to show. If None is passed, return all rows. float_precision : int Number of decimal places to display for floating point values. See :func:`Config.set_float_precision` for more information. @@ -7352,8 +7352,19 @@ def show( │ 2 ┆ 8 │ └─────┴─────┘ """ - self.head(n).collect().show( - n, + if limit is None: + lf = self + issue_warning( + "Showing a LazyFrame without a limit requires collecting the whole " + "LazyFrame, which could be an expensive operation. Set a limit to " + "show the LazyFrame without this warning.", + category=PerformanceWarning, + ) + else: + lf = self.head(limit) + + lf.collect().show( + limit, float_precision=float_precision, fmt_str_lengths=fmt_str_lengths, fmt_table_cell_list_len=fmt_table_cell_list_len, diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 0c6dba346e5e..4ae34c250aaf 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -30,7 +30,7 @@ def test_df_show_default(capsys: pytest.CaptureFixture[str]) -> None: ) -def test_df_show_n_rows(capsys: pytest.CaptureFixture[str]) -> None: +def test_df_show_positive_limit(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame( { "foo": [1, 2, 3, 4, 5, 6, 7], @@ -55,6 +55,59 @@ def test_df_show_n_rows(capsys: pytest.CaptureFixture[str]) -> None: ) +def test_df_show_negative_limit(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + { + "foo": [1, 2, 3, 4, 5, 6, 7], + "bar": ["a", "b", "c", "d", "e", "f", "g"], + } + ) + df.show(-5) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) +┌─────┬─────┐ +│ foo ┆ bar │ +│ --- ┆ --- │ +│ i64 ┆ str │ +╞═════╪═════╡ +│ 1 ┆ a │ +│ 2 ┆ b │ +└─────┴─────┘ +""" + ) + + +def test_df_show_no_limit(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + { + "foo": [1, 2, 3, 4, 5, 6, 7], + "bar": ["a", "b", "c", "d", "e", "f", "g"], + } + ) + df.show(limit=None) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (7, 2) +┌─────┬─────┐ +│ foo ┆ bar │ +│ --- ┆ --- │ +│ i64 ┆ str │ +╞═════╪═════╡ +│ 1 ┆ a │ +│ 2 ┆ b │ +│ 3 ┆ c │ +│ 4 ┆ d │ +│ 5 ┆ e │ +│ 6 ┆ f │ +│ 7 ┆ g │ +└─────┴─────┘ +""" + ) + + def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: from math import e, pi diff --git a/py-polars/tests/unit/lazyframe/test_show.py b/py-polars/tests/unit/lazyframe/test_show.py index 9363390f10b1..cee36e3a5c1d 100644 --- a/py-polars/tests/unit/lazyframe/test_show.py +++ b/py-polars/tests/unit/lazyframe/test_show.py @@ -1,7 +1,10 @@ from inspect import signature from unittest.mock import patch +import pytest + import polars as pl +from polars.exceptions import PerformanceWarning def test_show_signature_match() -> None: @@ -9,12 +12,7 @@ def test_show_signature_match() -> None: def test_lf_show_calls_df_show() -> None: - lf = pl.LazyFrame( - { - "foo": ["a", "b", "c", "d", "e", "f", "g"], - "bar": [1, 2, 3, 4, 5, 6, 7], - } - ) + lf = pl.LazyFrame({}) with patch.object(pl.DataFrame, "show") as df_show: lf.show(5) @@ -25,3 +23,9 @@ def test_lf_show_calls_df_show() -> None: fmt_table_cell_list_len=None, tbl_cols=None, ) + + +def test_lf_show_no_limit_issues_warning() -> None: + lf = pl.LazyFrame({}) + with pytest.warns(PerformanceWarning): + lf.show(limit=None) From 25626b31fa1f79e57fb0bf1a52488bcaac05bd8e Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 00:57:55 +0100 Subject: [PATCH 05/24] decorate existing tests with Config --- py-polars/tests/unit/dataframe/test_show.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 4ae34c250aaf..44ca312731aa 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -108,6 +108,7 @@ def test_df_show_no_limit(capsys: pytest.CaptureFixture[str]) -> None: ) +@pl.Config(float_precision=8) def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: from math import e, pi @@ -145,6 +146,7 @@ def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: ) +@pl.Config(fmt_str_lengths=20) def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame( { @@ -186,6 +188,7 @@ def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: ) +@pl.Config(fmt_table_cell_list_len=5) def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"nums": [list(range(10))]}) @@ -220,6 +223,7 @@ def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> ) +@pl.Config(tbl_cols=2) def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({str(i): [i] for i in range(10)}) From a2a5de30b9e746eaf2c0bbe27fe581636140b1c7 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 00:59:59 +0100 Subject: [PATCH 06/24] use shorthand for unlimited rows --- py-polars/polars/dataframe/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index e578485d3f2c..1dc9843f0092 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11736,7 +11736,7 @@ def show( """ if limit is None: df = self - tbl_rows = self.height + tbl_rows = -1 else: df = self.head(limit) if limit < 0: From da957e84ccb9f4c04f46bf647bae8a145bed0661 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 01:45:25 +0100 Subject: [PATCH 07/24] more formatting options for DataFrame.show --- py-polars/polars/dataframe/frame.py | 33 +++++++ py-polars/tests/unit/dataframe/test_show.py | 100 ++++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 1dc9843f0092..db9d5e6039c6 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -167,6 +167,7 @@ UnstackDirection, ) from polars._utils.various import NoDefault + from polars.config import TableFormatNames from polars.interchange.dataframe import PolarsDataFrame from polars.io.cloud import CredentialProviderFunction from polars.ml.torch import PolarsDataset @@ -11673,6 +11674,9 @@ def show( float_precision: int | None = None, fmt_str_lengths: int | None = None, fmt_table_cell_list_len: int | None = None, + tbl_cell_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, + tbl_cell_numeric_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, + tbl_formatting: TableFormatNames | None = None, tbl_cols: int | None = None, ) -> None: """ @@ -11692,6 +11696,32 @@ def show( fmt_table_cell_list_len : int Number of elements to display for List values. See :func:`Config.set_fmt_table_cell_list_len` for more information. + tbl_cell_alignment : str + Set table cell alignment. Supported options are: + * "LEFT": left aligned + * "CENTER": center aligned + * "RIGHT": right aligned + tbl_cell_numeric_alignment : str + Set table cell alignment for numeric columns. Supported options are: + * "LEFT": left aligned + * "CENTER": center aligned + * "RIGHT": right aligned + tbl_formatting : str + Set table formatting style. Supported options are: + * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. + * "ASCII_FULL_CONDENSED": Same as ASCII_FULL, but with dense row spacing. + * "ASCII_NO_BORDERS": ASCII, no borders. + * "ASCII_BORDERS_ONLY": ASCII, borders only. + * "ASCII_BORDERS_ONLY_CONDENSED": ASCII, borders only, dense row spacing. + * "ASCII_HORIZONTAL_ONLY": ASCII, horizontal lines only. + * "ASCII_MARKDOWN": Markdown format (ascii ellipses for truncated values). + * "MARKDOWN": Markdown format (utf8 ellipses for truncated values). + * "UTF8_FULL": UTF8, with all borders and lines, including row dividers. + * "UTF8_FULL_CONDENSED": Same as UTF8_FULL, but with dense row spacing. + * "UTF8_NO_BORDERS": UTF8, no borders. + * "UTF8_BORDERS_ONLY": UTF8, borders only. + * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. + * "NOTHING": No borders or other lines. tbl_cols : int Number of columns to display. See :func:`Config.set_tbl_cols` for more information. @@ -11748,6 +11778,9 @@ def show( float_precision=float_precision, fmt_str_lengths=fmt_str_lengths, fmt_table_cell_list_len=fmt_table_cell_list_len, + tbl_cell_alignment=tbl_cell_alignment, + tbl_cell_numeric_alignment=tbl_cell_numeric_alignment, + tbl_formatting=tbl_formatting, tbl_cols=tbl_cols, tbl_rows=tbl_rows, ): diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 44ca312731aa..549f4419a9ce 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -10,6 +10,7 @@ def test_df_show_default(capsys: pytest.CaptureFixture[str]) -> None: "bar": ["a", "b", "c", "d", "e", "f", "g"], } ) + df.show() out, _ = capsys.readouterr() assert ( @@ -37,6 +38,7 @@ def test_df_show_positive_limit(capsys: pytest.CaptureFixture[str]) -> None: "bar": ["a", "b", "c", "d", "e", "f", "g"], } ) + df.show(3) out, _ = capsys.readouterr() assert ( @@ -62,6 +64,7 @@ def test_df_show_negative_limit(capsys: pytest.CaptureFixture[str]) -> None: "bar": ["a", "b", "c", "d", "e", "f", "g"], } ) + df.show(-5) out, _ = capsys.readouterr() assert ( @@ -86,6 +89,7 @@ def test_df_show_no_limit(capsys: pytest.CaptureFixture[str]) -> None: "bar": ["a", "b", "c", "d", "e", "f", "g"], } ) + df.show(limit=None) out, _ = capsys.readouterr() assert ( @@ -113,6 +117,7 @@ def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: from math import e, pi df = pl.DataFrame({"const": ["pi", "e"], "value": [pi, e]}) + df.show(float_precision=15) out, _ = capsys.readouterr() assert ( @@ -156,6 +161,7 @@ def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: ] } ) + df.show(fmt_str_lengths=10) out, _ = capsys.readouterr() assert ( @@ -171,6 +177,7 @@ def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: └─────────────┘ """ ) + df.show(fmt_str_lengths=50) out, _ = capsys.readouterr() assert ( @@ -223,6 +230,99 @@ def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> ) +@pl.Config(tbl_cell_alignment="LEFT") +def test_df_show_tbl_cell_alignment(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + {"column_abc": [1.0, 2.5, 5.0], "column_xyz": [True, False, True]} + ) + + df.show(tbl_cell_alignment="RIGHT") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +┌────────────┬────────────┐ +│ column_abc ┆ column_xyz │ +│ --- ┆ --- │ +│ f64 ┆ bool │ +╞════════════╪════════════╡ +│ 1.0 ┆ true │ +│ 2.5 ┆ false │ +│ 5.0 ┆ true │ +└────────────┴────────────┘ +""" + ) + + +@pl.Config(tbl_cell_numeric_alignment="LEFT") +def test_df_show_tbl_cell_numeric_alignment(capsys: pytest.CaptureFixture[str]) -> None: + from datetime import date + + df = pl.DataFrame( + { + "abc": [11, 2, 333], + "mno": [date(2023, 10, 29), None, date(2001, 7, 5)], + "xyz": [True, False, None], + } + ) + + df.show(tbl_cell_numeric_alignment="RIGHT") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 3) +┌─────┬────────────┬───────┐ +│ abc ┆ mno ┆ xyz │ +│ --- ┆ --- ┆ --- │ +│ i64 ┆ date ┆ bool │ +╞═════╪════════════╪═══════╡ +│ 11 ┆ 2023-10-29 ┆ true │ +│ 2 ┆ null ┆ false │ +│ 333 ┆ 2001-07-05 ┆ null │ +└─────┴────────────┴───────┘ +""" + ) + + +@pl.Config(tbl_formatting="UTF8_FULL") +def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}) + + df.show(tbl_formatting="ASCII_FULL") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 3) ++-----+-----+-----+ +| a | b | c | +| --- | --- | --- | +| i64 | i64 | i64 | ++=================+ +| 1 | 4 | 7 | +|-----+-----+-----| +| 2 | 5 | 8 | +|-----+-----+-----| +| 3 | 6 | 9 | ++-----+-----+-----+ +""" + ) + + df.show(tbl_formatting="MARKDOWN") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 3) +| a | b | c | +| --- | --- | --- | +| i64 | i64 | i64 | +|-----|-----|-----| +| 1 | 4 | 7 | +| 2 | 5 | 8 | +| 3 | 6 | 9 | +""" + ) + + @pl.Config(tbl_cols=2) def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({str(i): [i] for i in range(10)}) From a52ef6cca2523211ffab8d8ba6ae8713246c12b1 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 01:51:39 +0100 Subject: [PATCH 08/24] mandatory OCD commit --- py-polars/polars/dataframe/frame.py | 10 +-- py-polars/tests/unit/dataframe/test_show.py | 70 ++++++++++----------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index db9d5e6039c6..9d7bc8d6d742 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11676,8 +11676,8 @@ def show( fmt_table_cell_list_len: int | None = None, tbl_cell_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, tbl_cell_numeric_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, - tbl_formatting: TableFormatNames | None = None, tbl_cols: int | None = None, + tbl_formatting: TableFormatNames | None = None, ) -> None: """ Show the first `n` rows. @@ -11706,6 +11706,9 @@ def show( * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned + tbl_cols : int + Number of columns to display. See :func:`Config.set_tbl_cols` for more + information. tbl_formatting : str Set table formatting style. Supported options are: * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. @@ -11722,9 +11725,6 @@ def show( * "UTF8_BORDERS_ONLY": UTF8, borders only. * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. * "NOTHING": No borders or other lines. - tbl_cols : int - Number of columns to display. See :func:`Config.set_tbl_cols` for more - information. See Also -------- @@ -11780,8 +11780,8 @@ def show( fmt_table_cell_list_len=fmt_table_cell_list_len, tbl_cell_alignment=tbl_cell_alignment, tbl_cell_numeric_alignment=tbl_cell_numeric_alignment, - tbl_formatting=tbl_formatting, tbl_cols=tbl_cols, + tbl_formatting=tbl_formatting, tbl_rows=tbl_rows, ): if _in_notebook(): diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 549f4419a9ce..3247f9a8de96 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -284,6 +284,41 @@ def test_df_show_tbl_cell_numeric_alignment(capsys: pytest.CaptureFixture[str]) ) +@pl.Config(tbl_cols=2) +def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({str(i): [i] for i in range(10)}) + + df.show(tbl_cols=3) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 10) +┌─────┬─────┬───┬─────┐ +│ 0 ┆ 1 ┆ … ┆ 9 │ +│ --- ┆ --- ┆ ┆ --- │ +│ i64 ┆ i64 ┆ ┆ i64 │ +╞═════╪═════╪═══╪═════╡ +│ 0 ┆ 1 ┆ … ┆ 9 │ +└─────┴─────┴───┴─────┘ +""" + ) + + df.show(tbl_cols=7) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 10) +┌─────┬─────┬─────┬─────┬───┬─────┬─────┬─────┐ +│ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ +│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- │ +│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ ┆ i64 ┆ i64 ┆ i64 │ +╞═════╪═════╪═════╪═════╪═══╪═════╪═════╪═════╡ +│ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ +└─────┴─────┴─────┴─────┴───┴─────┴─────┴─────┘ +""" + ) + + @pl.Config(tbl_formatting="UTF8_FULL") def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}) @@ -321,38 +356,3 @@ def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: | 3 | 6 | 9 | """ ) - - -@pl.Config(tbl_cols=2) -def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: - df = pl.DataFrame({str(i): [i] for i in range(10)}) - - df.show(tbl_cols=3) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (1, 10) -┌─────┬─────┬───┬─────┐ -│ 0 ┆ 1 ┆ … ┆ 9 │ -│ --- ┆ --- ┆ ┆ --- │ -│ i64 ┆ i64 ┆ ┆ i64 │ -╞═════╪═════╪═══╪═════╡ -│ 0 ┆ 1 ┆ … ┆ 9 │ -└─────┴─────┴───┴─────┘ -""" - ) - - df.show(tbl_cols=7) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (1, 10) -┌─────┬─────┬─────┬─────┬───┬─────┬─────┬─────┐ -│ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ -│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- │ -│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ ┆ i64 ┆ i64 ┆ i64 │ -╞═════╪═════╪═════╪═════╪═══╪═════╪═════╪═════╡ -│ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ -└─────┴─────┴─────┴─────┴───┴─────┴─────┴─────┘ -""" - ) From 5b9235394fb6801f261e7267ef0709f42fdf3e0c Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 02:55:31 +0100 Subject: [PATCH 09/24] rename `LazyFrame.show` parameter to `limit` --- py-polars/polars/lazyframe/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 33be2d531730..8dffa1fc1f1f 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7300,7 +7300,7 @@ def show( Parameters ---------- - n : int + limit : int Number of rows to show. If None is passed, return all rows. float_precision : int Number of decimal places to display for floating point values. See From 973191b4c5009d58705b5a95232d876f3e867eaf Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Sun, 9 Feb 2025 01:42:34 +0100 Subject: [PATCH 10/24] add all config options to show methods --- py-polars/polars/dataframe/frame.py | 64 ++++- py-polars/polars/lazyframe/frame.py | 91 ++++++ py-polars/tests/unit/dataframe/test_show.py | 294 ++++++++++++++++++++ py-polars/tests/unit/lazyframe/test_show.py | 16 ++ 4 files changed, 464 insertions(+), 1 deletion(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 9d7bc8d6d742..31b8423c32e4 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -23,7 +23,12 @@ import polars._reexport as pl from polars import functions as F -from polars._typing import DbWriteMode, JaxExportType, TorchExportType +from polars._typing import ( + DbWriteMode, + FloatFmt, + JaxExportType, + TorchExportType, +) from polars._utils.construction import ( arrow_to_pydf, dataframe_to_pydf, @@ -11671,13 +11676,26 @@ def show( self, limit: int | None = 5, *, + ascii_tables: bool | None = None, + auto_structify: bool | None = None, + decimal_separator: str | None = None, + thousands_separator: str | bool | None = None, float_precision: int | None = None, + fmt_float: FloatFmt | None = None, fmt_str_lengths: int | None = None, fmt_table_cell_list_len: int | None = None, tbl_cell_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, tbl_cell_numeric_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, tbl_cols: int | None = None, + tbl_column_data_type_inline: bool | None = None, + tbl_dataframe_shape_below: bool | None = None, tbl_formatting: TableFormatNames | None = None, + tbl_hide_column_data_types: bool | None = None, + tbl_hide_column_names: bool | None = None, + tbl_hide_dtype_separator: bool | None = None, + tbl_hide_dataframe_shape: bool | None = None, + tbl_width_chars: int | None = None, + trim_decimal_zeros: bool | None = None, ) -> None: """ Show the first `n` rows. @@ -11687,9 +11705,23 @@ def show( limit : int Numbers of rows to show. If a negative value is passed, return all rows except the last `abs(n)`. If None is passed, return all rows. + ascii_tables : bool + Use ASCII characters to display table outlines. Set False to revert to the + default UTF8_FULL_CONDENSED formatting style. + auto_structify : bool + Allow multi-output expressions to be automatically turned into Structs. + decimal_separator : str + Set the decimal separator character. + thousands_separator : str + Set the thousands grouping separator character. float_precision : int Number of decimal places to display for floating point values. See :func:`Config.set_float_precision` for more information. + fmt_float : {"mixed", "full"} + Control how floating point values are displayed. Supported options are: + * "mixed": Limit the number of decimal places and use scientific notation + for large/small values. + * "full": Print the full precision of the floating point number. fmt_str_lengths : int Number of characters to display for string values. See :func:`Config.set_fmt_str_lengths` for more information. @@ -11709,6 +11741,11 @@ def show( tbl_cols : int Number of columns to display. See :func:`Config.set_tbl_cols` for more information. + tbl_column_data_type_inline : bool + Moves the data type inline with the column name (to the right, in + parentheses). + tbl_dataframe_shape_below : bool + Print the DataFrame shape information below the data when displaying tables. tbl_formatting : str Set table formatting style. Supported options are: * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. @@ -11725,6 +11762,18 @@ def show( * "UTF8_BORDERS_ONLY": UTF8, borders only. * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. * "NOTHING": No borders or other lines. + tbl_hide_column_data_types : bool + Hide table column data types (i64, f64, str etc.). + tbl_hide_column_names : bool + Hide table column names. + tbl_hide_dtype_separator : bool + Hide the '---' separator between the column names and column types. + tbl_hide_dataframe_shape : bool + Hide the DataFrame shape information when displaying tables. + tbl_width_chars : int + Set the maximum width of a table in characters. + trim_decimal_zeros : bool + Strip trailing zeros from Decimal data type values. See Also -------- @@ -11775,14 +11824,27 @@ def show( tbl_rows = limit with Config( + ascii_tables=ascii_tables, + auto_structify=auto_structify, + decimal_separator=decimal_separator, + thousands_separator=thousands_separator, float_precision=float_precision, + fmt_float=fmt_float, fmt_str_lengths=fmt_str_lengths, fmt_table_cell_list_len=fmt_table_cell_list_len, tbl_cell_alignment=tbl_cell_alignment, tbl_cell_numeric_alignment=tbl_cell_numeric_alignment, tbl_cols=tbl_cols, + tbl_column_data_type_inline=tbl_column_data_type_inline, + tbl_dataframe_shape_below=tbl_dataframe_shape_below, tbl_formatting=tbl_formatting, + tbl_hide_column_data_types=tbl_hide_column_data_types, + tbl_hide_column_names=tbl_hide_column_names, + tbl_hide_dtype_separator=tbl_hide_dtype_separator, + tbl_hide_dataframe_shape=tbl_hide_dataframe_shape, tbl_rows=tbl_rows, + tbl_width_chars=tbl_width_chars, + trim_decimal_zeros=trim_decimal_zeros, ): if _in_notebook(): print("In notebook") diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 8dffa1fc1f1f..1ff388aa8fd9 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -110,6 +110,7 @@ EngineType, ExplainFormat, FillNullStrategy, + FloatFmt, FrameInitTypes, IntoExpr, IntoExprColumn, @@ -127,6 +128,7 @@ StartBy, UniqueKeepStrategy, ) + from polars.config import TableFormatNames from polars.dependencies import numpy as np from polars.io.cloud import CredentialProviderFunction @@ -7290,10 +7292,26 @@ def show( self, limit: int | None = 5, *, + ascii_tables: bool | None = None, + auto_structify: bool | None = None, + decimal_separator: str | None = None, + thousands_separator: str | bool | None = None, float_precision: int | None = None, + fmt_float: FloatFmt | None = None, fmt_str_lengths: int | None = None, fmt_table_cell_list_len: int | None = None, + tbl_cell_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, + tbl_cell_numeric_alignment: Literal["LEFT", "CENTER", "RIGHT"] | None = None, tbl_cols: int | None = None, + tbl_column_data_type_inline: bool | None = None, + tbl_dataframe_shape_below: bool | None = None, + tbl_formatting: TableFormatNames | None = None, + tbl_hide_column_data_types: bool | None = None, + tbl_hide_column_names: bool | None = None, + tbl_hide_dtype_separator: bool | None = None, + tbl_hide_dataframe_shape: bool | None = None, + tbl_width_chars: int | None = None, + trim_decimal_zeros: bool | None = None, ) -> None: """ Show the first `n` rows. @@ -7302,18 +7320,75 @@ def show( ---------- limit : int Number of rows to show. If None is passed, return all rows. + ascii_tables : bool + Use ASCII characters to display table outlines. Set False to revert to the + default UTF8_FULL_CONDENSED formatting style. + auto_structify : bool + Allow multi-output expressions to be automatically turned into Structs. + decimal_separator : str + Set the decimal separator character. + thousands_separator : str + Set the thousands grouping separator character. float_precision : int Number of decimal places to display for floating point values. See :func:`Config.set_float_precision` for more information. + fmt_float : {"mixed", "full"} + Control how floating point values are displayed. Supported options are: + * "mixed": Limit the number of decimal places and use scientific notation + for large/small values. + * "full": Print the full precision of the floating point number. fmt_str_lengths : int Number of characters to display for string values. See :func:`Config.set_fmt_str_lengths` for more information. fmt_table_cell_list_len : int Number of elements to display for List values. See :func:`Config.set_fmt_table_cell_list_len` for more information. + tbl_cell_alignment : str + Set table cell alignment. Supported options are: + * "LEFT": left aligned + * "CENTER": center aligned + * "RIGHT": right aligned + tbl_cell_numeric_alignment : str + Set table cell alignment for numeric columns. Supported options are: + * "LEFT": left aligned + * "CENTER": center aligned + * "RIGHT": right aligned tbl_cols : int Number of columns to display. See :func:`Config.set_tbl_cols` for more information. + tbl_column_data_type_inline : bool + Moves the data type inline with the column name (to the right, in + parentheses). + tbl_dataframe_shape_below : bool + Print the DataFrame shape information below the data when displaying tables. + tbl_formatting : str + Set table formatting style. Supported options are: + * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. + * "ASCII_FULL_CONDENSED": Same as ASCII_FULL, but with dense row spacing. + * "ASCII_NO_BORDERS": ASCII, no borders. + * "ASCII_BORDERS_ONLY": ASCII, borders only. + * "ASCII_BORDERS_ONLY_CONDENSED": ASCII, borders only, dense row spacing. + * "ASCII_HORIZONTAL_ONLY": ASCII, horizontal lines only. + * "ASCII_MARKDOWN": Markdown format (ascii ellipses for truncated values). + * "MARKDOWN": Markdown format (utf8 ellipses for truncated values). + * "UTF8_FULL": UTF8, with all borders and lines, including row dividers. + * "UTF8_FULL_CONDENSED": Same as UTF8_FULL, but with dense row spacing. + * "UTF8_NO_BORDERS": UTF8, no borders. + * "UTF8_BORDERS_ONLY": UTF8, borders only. + * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. + * "NOTHING": No borders or other lines. + tbl_hide_column_data_types : bool + Hide table column data types (i64, f64, str etc.). + tbl_hide_column_names : bool + Hide table column names. + tbl_hide_dtype_separator : bool + Hide the '---' separator between the column names and column types. + tbl_hide_dataframe_shape : bool + Hide the DataFrame shape information when displaying tables. + tbl_width_chars : int + Set the maximum width of a table in characters. + trim_decimal_zeros : bool + Strip trailing zeros from Decimal data type values. Warnings -------- @@ -7365,10 +7440,26 @@ def show( lf.collect().show( limit, + ascii_tables=ascii_tables, + auto_structify=auto_structify, + decimal_separator=decimal_separator, + thousands_separator=thousands_separator, float_precision=float_precision, + fmt_float=fmt_float, fmt_str_lengths=fmt_str_lengths, fmt_table_cell_list_len=fmt_table_cell_list_len, + tbl_cell_alignment=tbl_cell_alignment, + tbl_cell_numeric_alignment=tbl_cell_numeric_alignment, tbl_cols=tbl_cols, + tbl_column_data_type_inline=tbl_column_data_type_inline, + tbl_dataframe_shape_below=tbl_dataframe_shape_below, + tbl_formatting=tbl_formatting, + tbl_hide_column_data_types=tbl_hide_column_data_types, + tbl_hide_column_names=tbl_hide_column_names, + tbl_hide_dtype_separator=tbl_hide_dtype_separator, + tbl_hide_dataframe_shape=tbl_hide_dataframe_shape, + tbl_width_chars=tbl_width_chars, + trim_decimal_zeros=trim_decimal_zeros, ) def _to_metadata( diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 3247f9a8de96..58eba1efc144 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -112,6 +112,98 @@ def test_df_show_no_limit(capsys: pytest.CaptureFixture[str]) -> None: ) +# FIXME: ascii_tables config option doesn't work. +@pytest.mark.skip("`ascii_tables` doesn't work") +@pl.Config(ascii_tables=False) +def test_df_show_ascii_tables(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(ascii_tables=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) ++-----+-------+ +| abc | xyz | +| --- | --- | +| f64 | bool | ++=============+ +| 1.0 | true | +| 2.5 | false | +| 5.0 | true | ++-----+-------+ +""" + ) + + +# FIXME: auto_structify config option doesn't work. +@pytest.mark.skip("`auto_structify` doesn't work") +@pl.Config(auto_structify=False) +def test_df_show_auto_structify(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"v": [1, 2, 3], "v2": [4, 5, 6]}) + + df.show(auto_structify=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) +┌───────────┐ +│ v │ +│ --- │ +│ struct[2] │ +╞═══════════╡ +│ {1,4} │ +│ {2,5} │ +│ {3,6} │ +└───────────┘ +""" + ) + + +@pl.Config(decimal_separator=",") +def test_df_show_decimal_separator(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) + + df.show(decimal_separator=",") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) +┌────────────┐ +│ v │ +│ --- │ +│ f64 │ +╞════════════╡ +│ 9876,54321 │ +│ 1,010101e6 │ +│ -123456,78 │ +└────────────┘ +""" + ) + + +@pl.Config(thousands_separator=".") +def test_df_show_thousands_separator(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) + + df.show(thousands_separator=" ") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) +┌─────────────┐ +│ v │ +│ --- │ +│ f64 │ +╞═════════════╡ +│ 9 876.54321 │ +│ 1.010101e6 │ +│ -123 456.78 │ +└─────────────┘ +""" + ) + + @pl.Config(float_precision=8) def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: from math import e, pi @@ -151,6 +243,28 @@ def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: ) +@pl.Config(fmt_float="full") +def test_df_show_fmt_float(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"num": [1.2304980958725870923, 1e6, 1e-8]}) + + df.show(fmt_float="mixed") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) +┌───────────┐ +│ num │ +│ --- │ +│ f64 │ +╞═══════════╡ +│ 1.230498 │ +│ 1e6 │ +│ 1.0000e-8 │ +└───────────┘ +""" + ) + + @pl.Config(fmt_str_lengths=20) def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame( @@ -319,6 +433,48 @@ def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: ) +@pl.Config(tbl_column_data_type_inline=False) +def test_df_show_tbl_column_data_type_inline( + capsys: pytest.CaptureFixture[str], +) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(tbl_column_data_type_inline=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +┌───────────┬────────────┐ +│ abc (f64) ┆ xyz (bool) │ +╞═══════════╪════════════╡ +│ 1.0 ┆ true │ +│ 2.5 ┆ false │ +│ 5.0 ┆ true │ +└───────────┴────────────┘ +""" + ) + + +@pl.Config(tbl_dataframe_shape_below=False) +def test_df_show_tbl_dataframe_shape_below(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(tbl_dataframe_shape_below=True) + out, _ = capsys.readouterr() + assert out == ( + "┌─────┬───────┐\n" + "│ abc ┆ xyz │\n" + "│ --- ┆ --- │\n" + "│ f64 ┆ bool │\n" + "╞═════╪═══════╡\n" + "│ 1.0 ┆ true │\n" + "│ 2.5 ┆ false │\n" + "│ 5.0 ┆ true │\n" + "└─────┴───────┘\n" + "shape: (3, 2)\n" + ) + + @pl.Config(tbl_formatting="UTF8_FULL") def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}) @@ -356,3 +512,141 @@ def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: | 3 | 6 | 9 | """ ) + + +@pl.Config(tbl_hide_column_data_types=False) +def test_df_show_tbl_hide_column_data_types(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(tbl_hide_column_data_types=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +┌─────┬───────┐ +│ abc ┆ xyz │ +╞═════╪═══════╡ +│ 1.0 ┆ true │ +│ 2.5 ┆ false │ +│ 5.0 ┆ true │ +└─────┴───────┘ +""" + ) + + +@pl.Config(tbl_hide_column_names=False) +def test_df_show_tbl_hide_column_names(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(tbl_hide_column_names=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +┌─────┬───────┐ +│ f64 ┆ bool │ +╞═════╪═══════╡ +│ 1.0 ┆ true │ +│ 2.5 ┆ false │ +│ 5.0 ┆ true │ +└─────┴───────┘ +""" + ) + + +@pl.Config(tbl_hide_dtype_separator=False) +def test_df_show_tbl_hide_dtype_separator(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(tbl_hide_dtype_separator=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +┌─────┬───────┐ +│ abc ┆ xyz │ +│ f64 ┆ bool │ +╞═════╪═══════╡ +│ 1.0 ┆ true │ +│ 2.5 ┆ false │ +│ 5.0 ┆ true │ +└─────┴───────┘ +""" + ) + + +@pl.Config(tbl_hide_dataframe_shape=False) +def test_df_show_tbl_hide_dataframe_shape(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) + + df.show(tbl_hide_dataframe_shape=True) + out, _ = capsys.readouterr() + assert out == ( + "┌─────┬───────┐\n" + "│ abc ┆ xyz │\n" + "│ --- ┆ --- │\n" + "│ f64 ┆ bool │\n" + "╞═════╪═══════╡\n" + "│ 1.0 ┆ true │\n" + "│ 2.5 ┆ false │\n" + "│ 5.0 ┆ true │\n" + "└─────┴───────┘\n" + ) + + +@pl.Config(tbl_width_chars=100) +def test_df_show_tbl_width_chars(capsys: pytest.CaptureFixture[str]) -> None: + df = pl.DataFrame( + { + "id": ["SEQ1", "SEQ2"], + "seq": ["ATGATAAAGGAG", "GCAACGCATATA"], + } + ) + + df.show(tbl_width_chars=12) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) +┌─────┬─────┐ +│ id ┆ seq │ +│ --- ┆ --- │ +│ str ┆ str │ +╞═════╪═════╡ +│ SEQ ┆ ATG │ +│ 1 ┆ ATA │ +│ ┆ AAG │ +│ ┆ GAG │ +│ SEQ ┆ GCA │ +│ 2 ┆ ACG │ +│ ┆ CAT │ +│ ┆ ATA │ +└─────┴─────┘ +""" + ) + + +@pl.Config(trim_decimal_zeros=False) +def test_df_show_trim_decimal_zeros(capsys: pytest.CaptureFixture[str]) -> None: + from decimal import Decimal as D + + df = pl.DataFrame( + data={"d": [D("1.01000"), D("-5.67890")]}, + schema={"d": pl.Decimal(scale=5)}, + ) + + df.show(trim_decimal_zeros=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 1) +┌──────────────┐ +│ d │ +│ --- │ +│ decimal[*,5] │ +╞══════════════╡ +│ 1.01 │ +│ -5.6789 │ +└──────────────┘ +""" + ) diff --git a/py-polars/tests/unit/lazyframe/test_show.py b/py-polars/tests/unit/lazyframe/test_show.py index cee36e3a5c1d..1f81e020eacb 100644 --- a/py-polars/tests/unit/lazyframe/test_show.py +++ b/py-polars/tests/unit/lazyframe/test_show.py @@ -18,10 +18,26 @@ def test_lf_show_calls_df_show() -> None: df_show.assert_called_once_with( 5, + ascii_tables=None, + auto_structify=None, + decimal_separator=None, + thousands_separator=None, float_precision=None, + fmt_float=None, fmt_str_lengths=None, fmt_table_cell_list_len=None, + tbl_cell_alignment=None, + tbl_cell_numeric_alignment=None, tbl_cols=None, + tbl_column_data_type_inline=None, + tbl_dataframe_shape_below=None, + tbl_formatting=None, + tbl_hide_column_data_types=None, + tbl_hide_column_names=None, + tbl_hide_dtype_separator=None, + tbl_hide_dataframe_shape=None, + tbl_width_chars=None, + trim_decimal_zeros=None, ) From c525d47b7a6f6736878cd2ad20ebf59ec283ac11 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 10:32:21 +0100 Subject: [PATCH 11/24] remove debug print --- py-polars/polars/dataframe/frame.py | 1 - 1 file changed, 1 deletion(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 31b8423c32e4..31901763470b 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11847,7 +11847,6 @@ def show( trim_decimal_zeros=trim_decimal_zeros, ): if _in_notebook(): - print("In notebook") from IPython.display import display_html display_html(df) From 1753d0c3b7d2b933b1f048e57f25cbe494414de4 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 10:47:52 +0100 Subject: [PATCH 12/24] fix ascii_tables setting --- py-polars/polars/dataframe/frame.py | 9 +++++++++ py-polars/tests/unit/dataframe/test_show.py | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 31901763470b..5288b24d9c9a 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11823,6 +11823,15 @@ def show( else: tbl_rows = limit + if ascii_tables is not None and tbl_formatting is not None: + msg = "Can not set `ascii_tables` and `tbl_formatting` at the same time." + raise ValueError(msg) + if ascii_tables is not None: + if ascii_tables: + tbl_formatting = "ASCII_FULL_CONDENSED" + else: + tbl_formatting = "UTF8_FULL_CONDENSED" + with Config( ascii_tables=ascii_tables, auto_structify=auto_structify, diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 58eba1efc144..2abc0a0bd0bb 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -112,8 +112,6 @@ def test_df_show_no_limit(capsys: pytest.CaptureFixture[str]) -> None: ) -# FIXME: ascii_tables config option doesn't work. -@pytest.mark.skip("`ascii_tables` doesn't work") @pl.Config(ascii_tables=False) def test_df_show_ascii_tables(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) From 61c9d5ae1841499351a3f1bbf43ffd953794ef8a Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 10:54:44 +0100 Subject: [PATCH 13/24] remove auto_structify option --- py-polars/polars/dataframe/frame.py | 4 ---- py-polars/polars/lazyframe/frame.py | 4 ---- py-polars/tests/unit/dataframe/test_show.py | 24 --------------------- py-polars/tests/unit/lazyframe/test_show.py | 1 - 4 files changed, 33 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 5288b24d9c9a..9a50b0a3286d 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11677,7 +11677,6 @@ def show( limit: int | None = 5, *, ascii_tables: bool | None = None, - auto_structify: bool | None = None, decimal_separator: str | None = None, thousands_separator: str | bool | None = None, float_precision: int | None = None, @@ -11708,8 +11707,6 @@ def show( ascii_tables : bool Use ASCII characters to display table outlines. Set False to revert to the default UTF8_FULL_CONDENSED formatting style. - auto_structify : bool - Allow multi-output expressions to be automatically turned into Structs. decimal_separator : str Set the decimal separator character. thousands_separator : str @@ -11834,7 +11831,6 @@ def show( with Config( ascii_tables=ascii_tables, - auto_structify=auto_structify, decimal_separator=decimal_separator, thousands_separator=thousands_separator, float_precision=float_precision, diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 1ff388aa8fd9..74c7fdc83a6e 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7293,7 +7293,6 @@ def show( limit: int | None = 5, *, ascii_tables: bool | None = None, - auto_structify: bool | None = None, decimal_separator: str | None = None, thousands_separator: str | bool | None = None, float_precision: int | None = None, @@ -7323,8 +7322,6 @@ def show( ascii_tables : bool Use ASCII characters to display table outlines. Set False to revert to the default UTF8_FULL_CONDENSED formatting style. - auto_structify : bool - Allow multi-output expressions to be automatically turned into Structs. decimal_separator : str Set the decimal separator character. thousands_separator : str @@ -7441,7 +7438,6 @@ def show( lf.collect().show( limit, ascii_tables=ascii_tables, - auto_structify=auto_structify, decimal_separator=decimal_separator, thousands_separator=thousands_separator, float_precision=float_precision, diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 2abc0a0bd0bb..df2734b32cf7 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -134,30 +134,6 @@ def test_df_show_ascii_tables(capsys: pytest.CaptureFixture[str]) -> None: ) -# FIXME: auto_structify config option doesn't work. -@pytest.mark.skip("`auto_structify` doesn't work") -@pl.Config(auto_structify=False) -def test_df_show_auto_structify(capsys: pytest.CaptureFixture[str]) -> None: - df = pl.DataFrame({"v": [1, 2, 3], "v2": [4, 5, 6]}) - - df.show(auto_structify=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 1) -┌───────────┐ -│ v │ -│ --- │ -│ struct[2] │ -╞═══════════╡ -│ {1,4} │ -│ {2,5} │ -│ {3,6} │ -└───────────┘ -""" - ) - - @pl.Config(decimal_separator=",") def test_df_show_decimal_separator(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) diff --git a/py-polars/tests/unit/lazyframe/test_show.py b/py-polars/tests/unit/lazyframe/test_show.py index 1f81e020eacb..41ea0156138e 100644 --- a/py-polars/tests/unit/lazyframe/test_show.py +++ b/py-polars/tests/unit/lazyframe/test_show.py @@ -19,7 +19,6 @@ def test_lf_show_calls_df_show() -> None: df_show.assert_called_once_with( 5, ascii_tables=None, - auto_structify=None, decimal_separator=None, thousands_separator=None, float_precision=None, From 584ea3ad819f1fd7e8eac64d1a2e8b0a21872cf1 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 10:57:46 +0100 Subject: [PATCH 14/24] fix lint --- py-polars/polars/dataframe/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 9a50b0a3286d..62381d755a26 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -25,7 +25,6 @@ from polars import functions as F from polars._typing import ( DbWriteMode, - FloatFmt, JaxExportType, TorchExportType, ) @@ -141,6 +140,7 @@ CsvQuoteStyle, DbWriteEngine, FillNullStrategy, + FloatFmt, FrameInitTypes, IndexOrder, IntoExpr, From 6f13782d2aacfdccbfc109736ef1273e4a44a023 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 11:07:42 +0100 Subject: [PATCH 15/24] test incompatible settings ascii_tables & tbl_formatting --- py-polars/tests/unit/dataframe/test_show.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index df2734b32cf7..7e5e5d593da0 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -1,6 +1,7 @@ import pytest import polars as pl +from polars.config import TableFormatNames def test_df_show_default(capsys: pytest.CaptureFixture[str]) -> None: @@ -134,6 +135,24 @@ def test_df_show_ascii_tables(capsys: pytest.CaptureFixture[str]) -> None: ) +@pytest.mark.parametrize( + ("ascii_tables", "tbl_formatting"), + [ + (True, "ASCII_FULL_CONDENSED"), + (True, "UTF8_FULL_CONDENSED"), + (False, "ASCII_FULL_CONDENSED"), + (False, "UTF8_FULL_CONDENSED"), + ], +) +def test_df_show_cannot_set_ascii_tables_and_tbl_formatting( + ascii_tables: bool, tbl_formatting: TableFormatNames +) -> None: + df = pl.DataFrame() + + with pytest.raises(ValueError): + df.show(ascii_tables=ascii_tables, tbl_formatting=tbl_formatting) + + @pl.Config(decimal_separator=",") def test_df_show_decimal_separator(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) From 7680856f44123143b74031a1897731df9af42a55 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 11:53:37 +0100 Subject: [PATCH 16/24] update docstrings with refs to config options --- py-polars/polars/dataframe/frame.py | 44 ++++++++++++++++++++--------- py-polars/polars/lazyframe/frame.py | 44 ++++++++++++++++++++--------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 62381d755a26..06a07d22df81 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11706,16 +11706,20 @@ def show( except the last `abs(n)`. If None is passed, return all rows. ascii_tables : bool Use ASCII characters to display table outlines. Set False to revert to the - default UTF8_FULL_CONDENSED formatting style. + default UTF8_FULL_CONDENSED formatting style. See + :func:`Config.set_ascii_tables` for more information. decimal_separator : str - Set the decimal separator character. + Set the decimal separator character. See + :func:`Config.set_decimal_separator` for more information. thousands_separator : str - Set the thousands grouping separator character. + Set the thousands grouping separator character. See + :func:`Config.set_thousands_separator` for more information. float_precision : int Number of decimal places to display for floating point values. See :func:`Config.set_float_precision` for more information. fmt_float : {"mixed", "full"} - Control how floating point values are displayed. Supported options are: + Control how floating point values are displayed. See + :func:`Config.set_fmt_float` for more informations. Supported options are: * "mixed": Limit the number of decimal places and use scientific notation for large/small values. * "full": Print the full precision of the floating point number. @@ -11726,12 +11730,15 @@ def show( Number of elements to display for List values. See :func:`Config.set_fmt_table_cell_list_len` for more information. tbl_cell_alignment : str - Set table cell alignment. Supported options are: + Set table cell alignment. See :func:`Config.set_tbl_cell_alignment` for more + information. Supported options are: * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned tbl_cell_numeric_alignment : str - Set table cell alignment for numeric columns. Supported options are: + Set table cell alignment for numeric columns. See + :func:`Config.set_tbl_cell_numeric_alignment` for more information. + Supported options are: * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned @@ -11740,11 +11747,14 @@ def show( information. tbl_column_data_type_inline : bool Moves the data type inline with the column name (to the right, in - parentheses). + parentheses). See :func:`Config.set_tbl_column_data_type_inline` for more + information. tbl_dataframe_shape_below : bool Print the DataFrame shape information below the data when displaying tables. + See :func:`Config.set_tbl_dataframe_shape_below` for more information. tbl_formatting : str - Set table formatting style. Supported options are: + Set table formatting style. See :func:`Config.set_tbl_formatting` for more + information. Supported options are: * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. * "ASCII_FULL_CONDENSED": Same as ASCII_FULL, but with dense row spacing. * "ASCII_NO_BORDERS": ASCII, no borders. @@ -11760,17 +11770,23 @@ def show( * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. * "NOTHING": No borders or other lines. tbl_hide_column_data_types : bool - Hide table column data types (i64, f64, str etc.). + Hide table column data types (i64, f64, str etc.). See + :func:`Config.set_tbl_hide_column_data_types` for more information. tbl_hide_column_names : bool - Hide table column names. + Hide table column names. See :func:`Config.set_tbl_hide_column_names` for + more information. tbl_hide_dtype_separator : bool - Hide the '---' separator between the column names and column types. + Hide the '---' separator between the column names and column types. See + :func:`Config.set_tbl_hide_dtype_separator` for more information. tbl_hide_dataframe_shape : bool - Hide the DataFrame shape information when displaying tables. + Hide the DataFrame shape information when displaying tables. See + :func:`Config.set_tbl_hide_dataframe_shape` for more information. tbl_width_chars : int - Set the maximum width of a table in characters. + Set the maximum width of a table in characters. See + :func:`Config.set_tbl_width_chars` for more information. trim_decimal_zeros : bool - Strip trailing zeros from Decimal data type values. + Strip trailing zeros from Decimal data type values. See + :func:`Config.set_trim_decimal_zeros` for more information. See Also -------- diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 74c7fdc83a6e..f14c0dcb3bd1 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7321,16 +7321,20 @@ def show( Number of rows to show. If None is passed, return all rows. ascii_tables : bool Use ASCII characters to display table outlines. Set False to revert to the - default UTF8_FULL_CONDENSED formatting style. + default UTF8_FULL_CONDENSED formatting style. See + :func:`Config.set_ascii_tables` for more information. decimal_separator : str - Set the decimal separator character. + Set the decimal separator character. See + :func:`Config.set_decimal_separator` for more information. thousands_separator : str - Set the thousands grouping separator character. + Set the thousands grouping separator character. See + :func:`Config.set_thousands_separator` for more information. float_precision : int Number of decimal places to display for floating point values. See :func:`Config.set_float_precision` for more information. fmt_float : {"mixed", "full"} - Control how floating point values are displayed. Supported options are: + Control how floating point values are displayed. See + :func:`Config.set_fmt_float` for more informations. Supported options are: * "mixed": Limit the number of decimal places and use scientific notation for large/small values. * "full": Print the full precision of the floating point number. @@ -7341,12 +7345,15 @@ def show( Number of elements to display for List values. See :func:`Config.set_fmt_table_cell_list_len` for more information. tbl_cell_alignment : str - Set table cell alignment. Supported options are: + Set table cell alignment. See :func:`Config.set_tbl_cell_alignment` for more + information. Supported options are: * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned tbl_cell_numeric_alignment : str - Set table cell alignment for numeric columns. Supported options are: + Set table cell alignment for numeric columns. See + :func:`Config.set_tbl_cell_numeric_alignment` for more information. + Supported options are: * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned @@ -7355,11 +7362,14 @@ def show( information. tbl_column_data_type_inline : bool Moves the data type inline with the column name (to the right, in - parentheses). + parentheses). See :func:`Config.set_tbl_column_data_type_inline` for more + information. tbl_dataframe_shape_below : bool Print the DataFrame shape information below the data when displaying tables. + See :func:`Config.set_tbl_dataframe_shape_below` for more information. tbl_formatting : str - Set table formatting style. Supported options are: + Set table formatting style. See :func:`Config.set_tbl_formatting` for more + information. Supported options are: * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. * "ASCII_FULL_CONDENSED": Same as ASCII_FULL, but with dense row spacing. * "ASCII_NO_BORDERS": ASCII, no borders. @@ -7375,17 +7385,23 @@ def show( * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. * "NOTHING": No borders or other lines. tbl_hide_column_data_types : bool - Hide table column data types (i64, f64, str etc.). + Hide table column data types (i64, f64, str etc.). See + :func:`Config.set_tbl_hide_column_data_types` for more information. tbl_hide_column_names : bool - Hide table column names. + Hide table column names. See :func:`Config.set_tbl_hide_column_names` for + more information. tbl_hide_dtype_separator : bool - Hide the '---' separator between the column names and column types. + Hide the '---' separator between the column names and column types. See + :func:`Config.set_tbl_hide_dtype_separator` for more information. tbl_hide_dataframe_shape : bool - Hide the DataFrame shape information when displaying tables. + Hide the DataFrame shape information when displaying tables. See + :func:`Config.set_tbl_hide_dataframe_shape` for more information. tbl_width_chars : int - Set the maximum width of a table in characters. + Set the maximum width of a table in characters. See + :func:`Config.set_tbl_width_chars` for more information. trim_decimal_zeros : bool - Strip trailing zeros from Decimal data type values. + Strip trailing zeros from Decimal data type values. See + :func:`Config.set_trim_decimal_zeros` for more information. Warnings -------- From 18faf2e915bf4bd3730fa0291966dc2ce52ce46d Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 11:55:30 +0100 Subject: [PATCH 17/24] fix typo --- py-polars/polars/dataframe/frame.py | 2 +- py-polars/polars/lazyframe/frame.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 06a07d22df81..17629b05868f 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11719,7 +11719,7 @@ def show( :func:`Config.set_float_precision` for more information. fmt_float : {"mixed", "full"} Control how floating point values are displayed. See - :func:`Config.set_fmt_float` for more informations. Supported options are: + :func:`Config.set_fmt_float` for more information. Supported options are: * "mixed": Limit the number of decimal places and use scientific notation for large/small values. * "full": Print the full precision of the floating point number. diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index f14c0dcb3bd1..850f8db41869 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7334,7 +7334,7 @@ def show( :func:`Config.set_float_precision` for more information. fmt_float : {"mixed", "full"} Control how floating point values are displayed. See - :func:`Config.set_fmt_float` for more informations. Supported options are: + :func:`Config.set_fmt_float` for more information. Supported options are: * "mixed": Limit the number of decimal places and use scientific notation for large/small values. * "full": Print the full precision of the floating point number. From e3bed540d694683432ed7afd6353901e7cf2514c Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 18:11:47 +0100 Subject: [PATCH 18/24] fix docstring indentation issue --- py-polars/polars/dataframe/frame.py | 2 +- py-polars/polars/lazyframe/frame.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 17629b05868f..37d39d5f5e50 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11721,7 +11721,7 @@ def show( Control how floating point values are displayed. See :func:`Config.set_fmt_float` for more information. Supported options are: * "mixed": Limit the number of decimal places and use scientific notation - for large/small values. + for large/small values. * "full": Print the full precision of the floating point number. fmt_str_lengths : int Number of characters to display for string values. See diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 850f8db41869..438ba9932798 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7336,7 +7336,7 @@ def show( Control how floating point values are displayed. See :func:`Config.set_fmt_float` for more information. Supported options are: * "mixed": Limit the number of decimal places and use scientific notation - for large/small values. + for large/small values. * "full": Print the full precision of the floating point number. fmt_str_lengths : int Number of characters to display for string values. See From 8079b879fff44a9ca8e39bd510aa1a5ea12b2191 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 18:24:01 +0100 Subject: [PATCH 19/24] feat: add doc entries for show methods --- py-polars/docs/source/reference/dataframe/descriptive.rst | 1 + py-polars/docs/source/reference/lazyframe/descriptive.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/py-polars/docs/source/reference/dataframe/descriptive.rst b/py-polars/docs/source/reference/dataframe/descriptive.rst index 00fba0d0cad1..ad166c830253 100644 --- a/py-polars/docs/source/reference/dataframe/descriptive.rst +++ b/py-polars/docs/source/reference/dataframe/descriptive.rst @@ -16,3 +16,4 @@ Descriptive DataFrame.n_chunks DataFrame.n_unique DataFrame.null_count + DataFrame.show diff --git a/py-polars/docs/source/reference/lazyframe/descriptive.rst b/py-polars/docs/source/reference/lazyframe/descriptive.rst index 0f05afae8960..0d499ea37e3f 100644 --- a/py-polars/docs/source/reference/lazyframe/descriptive.rst +++ b/py-polars/docs/source/reference/lazyframe/descriptive.rst @@ -9,3 +9,4 @@ Descriptive LazyFrame.describe LazyFrame.explain LazyFrame.show_graph + LazyFrame.show From 5934acbf0ae72e19947ef012a8bb73847a8a561b Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Thu, 7 Nov 2024 18:39:36 +0100 Subject: [PATCH 20/24] fix bullet lists --- py-polars/polars/dataframe/frame.py | 10 +++++++++- py-polars/polars/lazyframe/frame.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 37d39d5f5e50..ef73e45f310a 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11720,9 +11720,11 @@ def show( fmt_float : {"mixed", "full"} Control how floating point values are displayed. See :func:`Config.set_fmt_float` for more information. Supported options are: + * "mixed": Limit the number of decimal places and use scientific notation - for large/small values. + for large/small values. * "full": Print the full precision of the floating point number. + fmt_str_lengths : int Number of characters to display for string values. See :func:`Config.set_fmt_str_lengths` for more information. @@ -11732,16 +11734,20 @@ def show( tbl_cell_alignment : str Set table cell alignment. See :func:`Config.set_tbl_cell_alignment` for more information. Supported options are: + * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned + tbl_cell_numeric_alignment : str Set table cell alignment for numeric columns. See :func:`Config.set_tbl_cell_numeric_alignment` for more information. Supported options are: + * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned + tbl_cols : int Number of columns to display. See :func:`Config.set_tbl_cols` for more information. @@ -11755,6 +11761,7 @@ def show( tbl_formatting : str Set table formatting style. See :func:`Config.set_tbl_formatting` for more information. Supported options are: + * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. * "ASCII_FULL_CONDENSED": Same as ASCII_FULL, but with dense row spacing. * "ASCII_NO_BORDERS": ASCII, no borders. @@ -11769,6 +11776,7 @@ def show( * "UTF8_BORDERS_ONLY": UTF8, borders only. * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. * "NOTHING": No borders or other lines. + tbl_hide_column_data_types : bool Hide table column data types (i64, f64, str etc.). See :func:`Config.set_tbl_hide_column_data_types` for more information. diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 438ba9932798..496b37f3506e 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7335,9 +7335,11 @@ def show( fmt_float : {"mixed", "full"} Control how floating point values are displayed. See :func:`Config.set_fmt_float` for more information. Supported options are: + * "mixed": Limit the number of decimal places and use scientific notation - for large/small values. + for large/small values. * "full": Print the full precision of the floating point number. + fmt_str_lengths : int Number of characters to display for string values. See :func:`Config.set_fmt_str_lengths` for more information. @@ -7347,16 +7349,20 @@ def show( tbl_cell_alignment : str Set table cell alignment. See :func:`Config.set_tbl_cell_alignment` for more information. Supported options are: + * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned + tbl_cell_numeric_alignment : str Set table cell alignment for numeric columns. See :func:`Config.set_tbl_cell_numeric_alignment` for more information. Supported options are: + * "LEFT": left aligned * "CENTER": center aligned * "RIGHT": right aligned + tbl_cols : int Number of columns to display. See :func:`Config.set_tbl_cols` for more information. @@ -7370,6 +7376,7 @@ def show( tbl_formatting : str Set table formatting style. See :func:`Config.set_tbl_formatting` for more information. Supported options are: + * "ASCII_FULL": ASCII, with all borders and lines, including row dividers. * "ASCII_FULL_CONDENSED": Same as ASCII_FULL, but with dense row spacing. * "ASCII_NO_BORDERS": ASCII, no borders. @@ -7384,6 +7391,7 @@ def show( * "UTF8_BORDERS_ONLY": UTF8, borders only. * "UTF8_HORIZONTAL_ONLY": UTF8, horizontal lines only. * "NOTHING": No borders or other lines. + tbl_hide_column_data_types : bool Hide table column data types (i64, f64, str etc.). See :func:`Config.set_tbl_hide_column_data_types` for more information. From 9048dc91f3c307676277fb4ca2c96397c875c955 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Tue, 19 Nov 2024 00:11:53 +0100 Subject: [PATCH 21/24] correctly document thousands_separator type --- py-polars/polars/dataframe/frame.py | 2 +- py-polars/polars/lazyframe/frame.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index ef73e45f310a..1f4863762525 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11711,7 +11711,7 @@ def show( decimal_separator : str Set the decimal separator character. See :func:`Config.set_decimal_separator` for more information. - thousands_separator : str + thousands_separator : str, bool Set the thousands grouping separator character. See :func:`Config.set_thousands_separator` for more information. float_precision : int diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 496b37f3506e..91ad34dce596 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7326,7 +7326,7 @@ def show( decimal_separator : str Set the decimal separator character. See :func:`Config.set_decimal_separator` for more information. - thousands_separator : str + thousands_separator : str, bool Set the thousands grouping separator character. See :func:`Config.set_thousands_separator` for more information. float_precision : int From 095083db94f6b8ce47430856428a53fe771e1f59 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Tue, 19 Nov 2024 01:21:09 +0100 Subject: [PATCH 22/24] set trim_decimal_zeros default to the same value as in Config --- py-polars/polars/dataframe/frame.py | 2 +- py-polars/polars/lazyframe/frame.py | 2 +- py-polars/tests/unit/lazyframe/test_show.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/py-polars/polars/dataframe/frame.py b/py-polars/polars/dataframe/frame.py index 1f4863762525..d0edf5db61f0 100644 --- a/py-polars/polars/dataframe/frame.py +++ b/py-polars/polars/dataframe/frame.py @@ -11694,7 +11694,7 @@ def show( tbl_hide_dtype_separator: bool | None = None, tbl_hide_dataframe_shape: bool | None = None, tbl_width_chars: int | None = None, - trim_decimal_zeros: bool | None = None, + trim_decimal_zeros: bool | None = True, ) -> None: """ Show the first `n` rows. diff --git a/py-polars/polars/lazyframe/frame.py b/py-polars/polars/lazyframe/frame.py index 91ad34dce596..112e0cd8ea5a 100644 --- a/py-polars/polars/lazyframe/frame.py +++ b/py-polars/polars/lazyframe/frame.py @@ -7310,7 +7310,7 @@ def show( tbl_hide_dtype_separator: bool | None = None, tbl_hide_dataframe_shape: bool | None = None, tbl_width_chars: int | None = None, - trim_decimal_zeros: bool | None = None, + trim_decimal_zeros: bool | None = True, ) -> None: """ Show the first `n` rows. diff --git a/py-polars/tests/unit/lazyframe/test_show.py b/py-polars/tests/unit/lazyframe/test_show.py index 41ea0156138e..747d6b7513b7 100644 --- a/py-polars/tests/unit/lazyframe/test_show.py +++ b/py-polars/tests/unit/lazyframe/test_show.py @@ -36,7 +36,7 @@ def test_lf_show_calls_df_show() -> None: tbl_hide_dtype_separator=None, tbl_hide_dataframe_shape=None, tbl_width_chars=None, - trim_decimal_zeros=None, + trim_decimal_zeros=True, ) From 871082076b48fc582631380743e6584aafefb68e Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Tue, 19 Nov 2024 01:29:46 +0100 Subject: [PATCH 23/24] fix test context --- py-polars/tests/unit/dataframe/test_show.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 7e5e5d593da0..3f29ee592819 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -153,7 +153,7 @@ def test_df_show_cannot_set_ascii_tables_and_tbl_formatting( df.show(ascii_tables=ascii_tables, tbl_formatting=tbl_formatting) -@pl.Config(decimal_separator=",") +@pl.Config(decimal_separator=".") def test_df_show_decimal_separator(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) From 399ddb1ad8c453e27d8789ef57efdd6ff2714786 Mon Sep 17 00:00:00 2001 From: Guilhem de Viry Date: Tue, 19 Nov 2024 09:48:20 +0100 Subject: [PATCH 24/24] test: replace config decorators with config context managers --- py-polars/tests/unit/dataframe/test_show.py | 356 ++++++++++---------- 1 file changed, 178 insertions(+), 178 deletions(-) diff --git a/py-polars/tests/unit/dataframe/test_show.py b/py-polars/tests/unit/dataframe/test_show.py index 3f29ee592819..94ebc0ebbe07 100644 --- a/py-polars/tests/unit/dataframe/test_show.py +++ b/py-polars/tests/unit/dataframe/test_show.py @@ -113,15 +113,15 @@ def test_df_show_no_limit(capsys: pytest.CaptureFixture[str]) -> None: ) -@pl.Config(ascii_tables=False) def test_df_show_ascii_tables(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(ascii_tables=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 2) + with pl.Config(ascii_tables=False): + df.show(ascii_tables=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) +-----+-------+ | abc | xyz | | --- | --- | @@ -132,7 +132,7 @@ def test_df_show_ascii_tables(capsys: pytest.CaptureFixture[str]) -> None: | 5.0 | true | +-----+-------+ """ - ) + ) @pytest.mark.parametrize( @@ -153,15 +153,15 @@ def test_df_show_cannot_set_ascii_tables_and_tbl_formatting( df.show(ascii_tables=ascii_tables, tbl_formatting=tbl_formatting) -@pl.Config(decimal_separator=".") def test_df_show_decimal_separator(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) - df.show(decimal_separator=",") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 1) + with pl.Config(decimal_separator="."): + df.show(decimal_separator=",") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) ┌────────────┐ │ v │ │ --- │ @@ -172,18 +172,18 @@ def test_df_show_decimal_separator(capsys: pytest.CaptureFixture[str]) -> None: │ -123456,78 │ └────────────┘ """ - ) + ) -@pl.Config(thousands_separator=".") def test_df_show_thousands_separator(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"v": [9876.54321, 1010101.0, -123456.78]}) - df.show(thousands_separator=" ") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 1) + with pl.Config(thousands_separator="."): + df.show(thousands_separator=" ") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) ┌─────────────┐ │ v │ │ --- │ @@ -194,20 +194,20 @@ def test_df_show_thousands_separator(capsys: pytest.CaptureFixture[str]) -> None │ -123 456.78 │ └─────────────┘ """ - ) + ) -@pl.Config(float_precision=8) def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: from math import e, pi df = pl.DataFrame({"const": ["pi", "e"], "value": [pi, e]}) - df.show(float_precision=15) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (2, 2) + with pl.Config(float_precision=8): + df.show(float_precision=15) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) ┌───────┬───────────────────┐ │ const ┆ value │ │ --- ┆ --- │ @@ -217,13 +217,13 @@ def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: │ e ┆ 2.718281828459045 │ └───────┴───────────────────┘ """ - ) + ) - df.show(float_precision=3) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (2, 2) + df.show(float_precision=3) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) ┌───────┬───────┐ │ const ┆ value │ │ --- ┆ --- │ @@ -233,18 +233,18 @@ def test_df_show_float_precision(capsys: pytest.CaptureFixture[str]) -> None: │ e ┆ 2.718 │ └───────┴───────┘ """ - ) + ) -@pl.Config(fmt_float="full") def test_df_show_fmt_float(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"num": [1.2304980958725870923, 1e6, 1e-8]}) - df.show(fmt_float="mixed") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 1) + with pl.Config(fmt_float="full"): + df.show(fmt_float="mixed") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 1) ┌───────────┐ │ num │ │ --- │ @@ -255,10 +255,9 @@ def test_df_show_fmt_float(capsys: pytest.CaptureFixture[str]) -> None: │ 1.0000e-8 │ └───────────┘ """ - ) + ) -@pl.Config(fmt_str_lengths=20) def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame( { @@ -269,11 +268,12 @@ def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: } ) - df.show(fmt_str_lengths=10) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (2, 1) + with pl.Config(fmt_str_lengths=20): + df.show(fmt_str_lengths=10) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 1) ┌─────────────┐ │ txt │ │ --- │ @@ -283,13 +283,13 @@ def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: │ This is th… │ └─────────────┘ """ - ) + ) - df.show(fmt_str_lengths=50) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (2, 1) + df.show(fmt_str_lengths=50) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 1) ┌──────────────────────────────────────────────────┐ │ txt │ │ --- │ @@ -299,18 +299,18 @@ def test_df_show_fmt_str_lengths(capsys: pytest.CaptureFixture[str]) -> None: │ This is the beginning of a beautiful friendship. │ └──────────────────────────────────────────────────┘ """ - ) + ) -@pl.Config(fmt_table_cell_list_len=5) def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"nums": [list(range(10))]}) - df.show(fmt_table_cell_list_len=2) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (1, 1) + with pl.Config(fmt_table_cell_list_len=5): + df.show(fmt_table_cell_list_len=2) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 1) ┌───────────┐ │ nums │ │ --- │ @@ -319,13 +319,13 @@ def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> │ [0, … 9] │ └───────────┘ """ - ) + ) - df.show(fmt_table_cell_list_len=8) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (1, 1) + df.show(fmt_table_cell_list_len=8) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 1) ┌────────────────────────────┐ │ nums │ │ --- │ @@ -334,20 +334,20 @@ def test_df_show_fmt_table_cell_list_len(capsys: pytest.CaptureFixture[str]) -> │ [0, 1, 2, 3, 4, 5, 6, … 9] │ └────────────────────────────┘ """ - ) + ) -@pl.Config(tbl_cell_alignment="LEFT") def test_df_show_tbl_cell_alignment(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame( {"column_abc": [1.0, 2.5, 5.0], "column_xyz": [True, False, True]} ) - df.show(tbl_cell_alignment="RIGHT") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 2) + with pl.Config(tbl_cell_alignment="LEFT"): + df.show(tbl_cell_alignment="RIGHT") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) ┌────────────┬────────────┐ │ column_abc ┆ column_xyz │ │ --- ┆ --- │ @@ -358,10 +358,9 @@ def test_df_show_tbl_cell_alignment(capsys: pytest.CaptureFixture[str]) -> None: │ 5.0 ┆ true │ └────────────┴────────────┘ """ - ) + ) -@pl.Config(tbl_cell_numeric_alignment="LEFT") def test_df_show_tbl_cell_numeric_alignment(capsys: pytest.CaptureFixture[str]) -> None: from datetime import date @@ -373,11 +372,12 @@ def test_df_show_tbl_cell_numeric_alignment(capsys: pytest.CaptureFixture[str]) } ) - df.show(tbl_cell_numeric_alignment="RIGHT") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 3) + with pl.Config(tbl_cell_numeric_alignment="LEFT"): + df.show(tbl_cell_numeric_alignment="RIGHT") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 3) ┌─────┬────────────┬───────┐ │ abc ┆ mno ┆ xyz │ │ --- ┆ --- ┆ --- │ @@ -388,18 +388,18 @@ def test_df_show_tbl_cell_numeric_alignment(capsys: pytest.CaptureFixture[str]) │ 333 ┆ 2001-07-05 ┆ null │ └─────┴────────────┴───────┘ """ - ) + ) -@pl.Config(tbl_cols=2) def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({str(i): [i] for i in range(10)}) - df.show(tbl_cols=3) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (1, 10) + with pl.Config(tbl_cols=2): + df.show(tbl_cols=3) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 10) ┌─────┬─────┬───┬─────┐ │ 0 ┆ 1 ┆ … ┆ 9 │ │ --- ┆ --- ┆ ┆ --- │ @@ -408,13 +408,13 @@ def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: │ 0 ┆ 1 ┆ … ┆ 9 │ └─────┴─────┴───┴─────┘ """ - ) + ) - df.show(tbl_cols=7) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (1, 10) + df.show(tbl_cols=7) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (1, 10) ┌─────┬─────┬─────┬─────┬───┬─────┬─────┬─────┐ │ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ │ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- │ @@ -423,20 +423,20 @@ def test_df_show_tbl_cols(capsys: pytest.CaptureFixture[str]) -> None: │ 0 ┆ 1 ┆ 2 ┆ 3 ┆ … ┆ 7 ┆ 8 ┆ 9 │ └─────┴─────┴─────┴─────┴───┴─────┴─────┴─────┘ """ - ) + ) -@pl.Config(tbl_column_data_type_inline=False) def test_df_show_tbl_column_data_type_inline( capsys: pytest.CaptureFixture[str], ) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(tbl_column_data_type_inline=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 2) + with pl.Config(tbl_column_data_type_inline=False): + df.show(tbl_column_data_type_inline=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) ┌───────────┬────────────┐ │ abc (f64) ┆ xyz (bool) │ ╞═══════════╪════════════╡ @@ -445,38 +445,38 @@ def test_df_show_tbl_column_data_type_inline( │ 5.0 ┆ true │ └───────────┴────────────┘ """ - ) + ) -@pl.Config(tbl_dataframe_shape_below=False) def test_df_show_tbl_dataframe_shape_below(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(tbl_dataframe_shape_below=True) - out, _ = capsys.readouterr() - assert out == ( - "┌─────┬───────┐\n" - "│ abc ┆ xyz │\n" - "│ --- ┆ --- │\n" - "│ f64 ┆ bool │\n" - "╞═════╪═══════╡\n" - "│ 1.0 ┆ true │\n" - "│ 2.5 ┆ false │\n" - "│ 5.0 ┆ true │\n" - "└─────┴───────┘\n" - "shape: (3, 2)\n" - ) + with pl.Config(tbl_dataframe_shape_below=False): + df.show(tbl_dataframe_shape_below=True) + out, _ = capsys.readouterr() + assert out == ( + "┌─────┬───────┐\n" + "│ abc ┆ xyz │\n" + "│ --- ┆ --- │\n" + "│ f64 ┆ bool │\n" + "╞═════╪═══════╡\n" + "│ 1.0 ┆ true │\n" + "│ 2.5 ┆ false │\n" + "│ 5.0 ┆ true │\n" + "└─────┴───────┘\n" + "shape: (3, 2)\n" + ) -@pl.Config(tbl_formatting="UTF8_FULL") def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6], "c": [7, 8, 9]}) - df.show(tbl_formatting="ASCII_FULL") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 3) + with pl.Config(tbl_formatting="UTF8_FULL"): + df.show(tbl_formatting="ASCII_FULL") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 3) +-----+-----+-----+ | a | b | c | | --- | --- | --- | @@ -489,13 +489,13 @@ def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: | 3 | 6 | 9 | +-----+-----+-----+ """ - ) + ) - df.show(tbl_formatting="MARKDOWN") - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 3) + df.show(tbl_formatting="MARKDOWN") + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 3) | a | b | c | | --- | --- | --- | | i64 | i64 | i64 | @@ -504,18 +504,18 @@ def test_df_show_tbl_formatting(capsys: pytest.CaptureFixture[str]) -> None: | 2 | 5 | 8 | | 3 | 6 | 9 | """ - ) + ) -@pl.Config(tbl_hide_column_data_types=False) def test_df_show_tbl_hide_column_data_types(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(tbl_hide_column_data_types=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 2) + with pl.Config(tbl_hide_column_data_types=False): + df.show(tbl_hide_column_data_types=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) ┌─────┬───────┐ │ abc ┆ xyz │ ╞═════╪═══════╡ @@ -524,18 +524,18 @@ def test_df_show_tbl_hide_column_data_types(capsys: pytest.CaptureFixture[str]) │ 5.0 ┆ true │ └─────┴───────┘ """ - ) + ) -@pl.Config(tbl_hide_column_names=False) def test_df_show_tbl_hide_column_names(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(tbl_hide_column_names=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 2) + with pl.Config(tbl_hide_column_names=False): + df.show(tbl_hide_column_names=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) ┌─────┬───────┐ │ f64 ┆ bool │ ╞═════╪═══════╡ @@ -544,18 +544,18 @@ def test_df_show_tbl_hide_column_names(capsys: pytest.CaptureFixture[str]) -> No │ 5.0 ┆ true │ └─────┴───────┘ """ - ) + ) -@pl.Config(tbl_hide_dtype_separator=False) def test_df_show_tbl_hide_dtype_separator(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(tbl_hide_dtype_separator=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (3, 2) + with pl.Config(tbl_hide_dtype_separator=False): + df.show(tbl_hide_dtype_separator=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (3, 2) ┌─────┬───────┐ │ abc ┆ xyz │ │ f64 ┆ bool │ @@ -565,29 +565,28 @@ def test_df_show_tbl_hide_dtype_separator(capsys: pytest.CaptureFixture[str]) -> │ 5.0 ┆ true │ └─────┴───────┘ """ - ) + ) -@pl.Config(tbl_hide_dataframe_shape=False) def test_df_show_tbl_hide_dataframe_shape(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame({"abc": [1.0, 2.5, 5.0], "xyz": [True, False, True]}) - df.show(tbl_hide_dataframe_shape=True) - out, _ = capsys.readouterr() - assert out == ( - "┌─────┬───────┐\n" - "│ abc ┆ xyz │\n" - "│ --- ┆ --- │\n" - "│ f64 ┆ bool │\n" - "╞═════╪═══════╡\n" - "│ 1.0 ┆ true │\n" - "│ 2.5 ┆ false │\n" - "│ 5.0 ┆ true │\n" - "└─────┴───────┘\n" - ) + with pl.Config(tbl_hide_dataframe_shape=False): + df.show(tbl_hide_dataframe_shape=True) + out, _ = capsys.readouterr() + assert out == ( + "┌─────┬───────┐\n" + "│ abc ┆ xyz │\n" + "│ --- ┆ --- │\n" + "│ f64 ┆ bool │\n" + "╞═════╪═══════╡\n" + "│ 1.0 ┆ true │\n" + "│ 2.5 ┆ false │\n" + "│ 5.0 ┆ true │\n" + "└─────┴───────┘\n" + ) -@pl.Config(tbl_width_chars=100) def test_df_show_tbl_width_chars(capsys: pytest.CaptureFixture[str]) -> None: df = pl.DataFrame( { @@ -596,11 +595,12 @@ def test_df_show_tbl_width_chars(capsys: pytest.CaptureFixture[str]) -> None: } ) - df.show(tbl_width_chars=12) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (2, 2) + with pl.Config(tbl_width_chars=100): + df.show(tbl_width_chars=12) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 2) ┌─────┬─────┐ │ id ┆ seq │ │ --- ┆ --- │ @@ -616,10 +616,9 @@ def test_df_show_tbl_width_chars(capsys: pytest.CaptureFixture[str]) -> None: │ ┆ ATA │ └─────┴─────┘ """ - ) + ) -@pl.Config(trim_decimal_zeros=False) def test_df_show_trim_decimal_zeros(capsys: pytest.CaptureFixture[str]) -> None: from decimal import Decimal as D @@ -628,11 +627,12 @@ def test_df_show_trim_decimal_zeros(capsys: pytest.CaptureFixture[str]) -> None: schema={"d": pl.Decimal(scale=5)}, ) - df.show(trim_decimal_zeros=True) - out, _ = capsys.readouterr() - assert ( - out - == """shape: (2, 1) + with pl.Config(trim_decimal_zeros=False): + df.show(trim_decimal_zeros=True) + out, _ = capsys.readouterr() + assert ( + out + == """shape: (2, 1) ┌──────────────┐ │ d │ │ --- │ @@ -642,4 +642,4 @@ def test_df_show_trim_decimal_zeros(capsys: pytest.CaptureFixture[str]) -> None: │ -5.6789 │ └──────────────┘ """ - ) + )