From f65ca97347633a3e2796d6f0dbc70c7efb7231b4 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Sun, 1 Dec 2024 17:48:09 +0800 Subject: [PATCH 1/6] Add test --- pandas/tests/io/formats/test_format.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 0dc16e1ebc723..8d616ca65d810 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -129,6 +129,13 @@ def test_repr_truncation_preserves_na(self): with option_context("display.max_rows", 2, "display.show_dimensions", False): assert repr(df) == " a\n0 \n.. ...\n9 " + def test_repr_truncation_dataframe_attrs(self): + # 60455 + df = DataFrame([[0] * 10]) + df.attrs["b"] = DataFrame([]) + with option_context("display.max_columns", 2, "display.show_dimensions", False): + assert repr(df) == " 0 ... 9\n0 0 ... 0" + def test_max_colwidth_negative_int_raises(self): # Deprecation enforced from: # https://github.com/pandas-dev/pandas/issues/31532 From b48fc35dc4cc4a5f413ad1b905d38408a796699d Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Sun, 1 Dec 2024 17:48:41 +0800 Subject: [PATCH 2/6] replace concat with np --- pandas/io/formats/format.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 4f87b1a30ca61..9d6d4560a350e 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -669,9 +669,9 @@ def _truncate_horizontally(self) -> None: assert self.max_cols_fitted is not None col_num = self.max_cols_fitted // 2 if col_num >= 1: - left = self.tr_frame.iloc[:, :col_num] - right = self.tr_frame.iloc[:, -col_num:] - self.tr_frame = concat((left, right), axis=1) + _len = len(self.tr_frame.columns) + _slice = np.hstack([np.arange(col_num), np.arange(_len - col_num, _len)]) + self.tr_frame = self.tr_frame.iloc[:, _slice] # truncate formatter if isinstance(self.formatters, (list, tuple)): From 6b45ac5dd8c1f985f2eaa7ec376fbf6c9799b6c5 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Sun, 1 Dec 2024 19:28:04 +0800 Subject: [PATCH 3/6] Revert "replace concat with np" This reverts commit b48fc35dc4cc4a5f413ad1b905d38408a796699d. --- pandas/io/formats/format.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 9d6d4560a350e..4f87b1a30ca61 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -669,9 +669,9 @@ def _truncate_horizontally(self) -> None: assert self.max_cols_fitted is not None col_num = self.max_cols_fitted // 2 if col_num >= 1: - _len = len(self.tr_frame.columns) - _slice = np.hstack([np.arange(col_num), np.arange(_len - col_num, _len)]) - self.tr_frame = self.tr_frame.iloc[:, _slice] + left = self.tr_frame.iloc[:, :col_num] + right = self.tr_frame.iloc[:, -col_num:] + self.tr_frame = concat((left, right), axis=1) # truncate formatter if isinstance(self.formatters, (list, tuple)): From cf4e042738e70fe1509f33f25a6ebf2ae2b7fa94 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Sun, 1 Dec 2024 20:04:47 +0800 Subject: [PATCH 4/6] Revert "Revert "replace concat with np"" This reverts commit 6b45ac5dd8c1f985f2eaa7ec376fbf6c9799b6c5. --- pandas/io/formats/format.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 4f87b1a30ca61..9d6d4560a350e 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -669,9 +669,9 @@ def _truncate_horizontally(self) -> None: assert self.max_cols_fitted is not None col_num = self.max_cols_fitted // 2 if col_num >= 1: - left = self.tr_frame.iloc[:, :col_num] - right = self.tr_frame.iloc[:, -col_num:] - self.tr_frame = concat((left, right), axis=1) + _len = len(self.tr_frame.columns) + _slice = np.hstack([np.arange(col_num), np.arange(_len - col_num, _len)]) + self.tr_frame = self.tr_frame.iloc[:, _slice] # truncate formatter if isinstance(self.formatters, (list, tuple)): From 2f378fdcb8f891f13d7ee9e4c3c84d31fc9566f7 Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Mon, 2 Dec 2024 20:16:44 +0800 Subject: [PATCH 5/6] try fixing mypy error --- pandas/io/formats/format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 9d6d4560a350e..17460eae8c049 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -682,7 +682,7 @@ def _truncate_horizontally(self) -> None: else: col_num = cast(int, self.max_cols) self.tr_frame = self.tr_frame.iloc[:, :col_num] - self.tr_col_num = col_num + self.tr_col_num: int = col_num def _truncate_vertically(self) -> None: """Remove rows, which are not to be displayed. From 2cb7a2a5a795610d3ae44fa3b24ed9dbb7d0dbdf Mon Sep 17 00:00:00 2001 From: yuanx749 Date: Tue, 3 Dec 2024 10:03:43 +0800 Subject: [PATCH 6/6] Add whatsnew --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/tests/io/formats/test_format.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 83638ce87f7ac..bb9f48d17b2e1 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -797,6 +797,7 @@ Other - Bug in :meth:`read_csv` where chained fsspec TAR file and ``compression="infer"`` fails with ``tarfile.ReadError`` (:issue:`60028`) - Bug in Dataframe Interchange Protocol implementation was returning incorrect results for data buffers' associated dtype, for string and datetime columns (:issue:`54781`) - Bug in ``Series.list`` methods not preserving the original :class:`Index`. (:issue:`58425`) +- Bug in printing a :class:`DataFrame` with a :class:`DataFrame` stored in :attr:`DataFrame.attrs` raised a ``ValueError`` (:issue:`60455`) .. ***DO NOT USE THIS SECTION*** diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 8d616ca65d810..d7db3d5082135 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -130,7 +130,7 @@ def test_repr_truncation_preserves_na(self): assert repr(df) == " a\n0 \n.. ...\n9 " def test_repr_truncation_dataframe_attrs(self): - # 60455 + # GH#60455 df = DataFrame([[0] * 10]) df.attrs["b"] = DataFrame([]) with option_context("display.max_columns", 2, "display.show_dimensions", False):