From bff2411dc13af10d641ab8f24a42fb4aeb08b9ec Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 19 Oct 2022 13:35:59 +0200 Subject: [PATCH 01/22] group the variable names of common indexes --- xarray/core/formatting.py | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 268e2eb63b3..e950a77339a 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -409,14 +409,17 @@ def coords_repr(coords, col_width=None, max_rows=None): def summarize_index( - name: Hashable, index, col_width: int, max_width: int = None, is_index: bool = False + name: str, index, col_width: int, max_width: int = None, is_index: bool = False ): return pretty_print(f" {name} ", col_width) + f"{repr(index)}" -def nondefault_indexes(indexes): +def filter_nondefault_indexes(indexes, filter_indexes): from .indexes import PandasIndex, PandasMultiIndex + if not filter_indexes: + return indexes + default_indexes = (PandasIndex, PandasMultiIndex) return { @@ -426,9 +429,19 @@ def nondefault_indexes(indexes): } -def indexes_repr(indexes, col_width=None, max_rows=None): +def indexes_repr(indexes, max_rows=None): + def format_names(names): + if len(names) == 1: + return str(names[0]) + else: + return f"[{', '.join(str(n) for n in names)}]" + + indexes_ = {format_names(names): idx for names, idx in indexes.items()} + + col_width = _calculate_col_width(indexes_) + return _mapping_repr( - indexes, + indexes_, "Indexes", summarize_index, "display_expand_indexes", @@ -570,6 +583,12 @@ def short_data_repr(array): return f"[{array.size} values with dtype={array.dtype}]" +def _get_indexes_dict(indexes): + return { + tuple(index_vars.keys()): idx for idx, index_vars in indexes.group_by_index() + } + + @recursive_repr("") def array_repr(arr): from .variable import Variable @@ -614,15 +633,13 @@ def array_repr(arr): display_default_indexes = _get_boolean_with_default( "display_default_indexes", False ) - if display_default_indexes: - xindexes = arr.xindexes - else: - xindexes = nondefault_indexes(arr.xindexes) + + xindexes = filter_nondefault_indexes( + _get_indexes_dict(arr.xindexes), not display_default_indexes + ) if xindexes: - summary.append( - indexes_repr(xindexes, col_width=col_width, max_rows=max_rows) - ) + summary.append(indexes_repr(xindexes, max_rows=max_rows)) if arr.attrs: summary.append(attrs_repr(arr.attrs, max_rows=max_rows)) @@ -653,12 +670,11 @@ def dataset_repr(ds): display_default_indexes = _get_boolean_with_default( "display_default_indexes", False ) - if display_default_indexes: - xindexes = ds.xindexes - else: - xindexes = nondefault_indexes(ds.xindexes) + xindexes = filter_nondefault_indexes( + _get_indexes_dict(ds.xindexes), not display_default_indexes + ) if xindexes: - summary.append(indexes_repr(xindexes, col_width=col_width, max_rows=max_rows)) + summary.append(indexes_repr(xindexes, max_rows=max_rows)) if ds.attrs: summary.append(attrs_repr(ds.attrs, max_rows=max_rows)) From e29aeb9085bc677e16dabd4a2b94cf63d06c155e Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 13:40:53 +0200 Subject: [PATCH 02/22] implement option 1: separate with just newlines --- xarray/core/formatting.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index e4eddbbc40f..e6f38020ffc 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -419,15 +419,18 @@ def inline_index_repr(index, max_width=None): return repr_ -def summarize_index(name: Hashable, index, col_width: int, max_width: int = None): +def summarize_index( + names: tuple[Hashable], index, col_width: int, max_width: int = None +): if max_width is None: max_width = OPTIONS["display_width"] - preformatted = pretty_print(f" {name} ", col_width) + preformatted = [pretty_print(f" {name} ", col_width) for name in names] - index_width = max_width - len(preformatted) + head, *tail = preformatted + index_width = max_width - len(head) repr_ = inline_index_repr(index, max_width=index_width) - return preformatted + repr_ + return "\n".join([head + repr_] + [line.rstrip() for line in tail]) def filter_nondefault_indexes(indexes, filter_indexes): @@ -446,18 +449,10 @@ def filter_nondefault_indexes(indexes, filter_indexes): def indexes_repr(indexes, max_rows=None): - def format_names(names): - if len(names) == 1: - return str(names[0]) - else: - return f"[{', '.join(str(n) for n in names)}]" - - indexes_ = {format_names(names): idx for names, idx in indexes.items()} - - col_width = _calculate_col_width(indexes_) + col_width = _calculate_col_width(chain.from_iterable(indexes)) return _mapping_repr( - indexes_, + indexes, "Indexes", summarize_index, "display_expand_indexes", From 9b90f8bceda6f012c863927865cc638e0ff3fb88 Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 15:03:17 +0200 Subject: [PATCH 03/22] implement option 2: list-like presentation of the indexes --- xarray/core/formatting.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index e6f38020ffc..6875afa29b3 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -425,7 +425,10 @@ def summarize_index( if max_width is None: max_width = OPTIONS["display_width"] - preformatted = [pretty_print(f" {name} ", col_width) for name in names] + preformatted = [ + pretty_print(f" {'-' if index == 0 else ' '} {name} ", col_width) + for index, name in enumerate(names) + ] head, *tail = preformatted index_width = max_width - len(head) From 2cec070ebf4f1958d4ffef98d7649eda21ac09a3 Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 15:07:06 +0200 Subject: [PATCH 04/22] implement option 3: light box components in front of the coord names --- xarray/core/formatting.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 6875afa29b3..57bab84bb4d 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -425,8 +425,18 @@ def summarize_index( if max_width is None: max_width = OPTIONS["display_width"] + def prefix(index, length): + if index == 0 and length == 1: + return " " + elif index == 0: + return "┌" + elif index >= length - 1: + return "└" + else: + return "│" + preformatted = [ - pretty_print(f" {'-' if index == 0 else ' '} {name} ", col_width) + pretty_print(f" {prefix(index, len(names))} {name} ", col_width) for index, name in enumerate(names) ] From 492ab47ccce8c43d264d5c759841060d33cafe4d Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 15:15:13 +0200 Subject: [PATCH 05/22] implement option 4: light box components after the coord names --- xarray/core/formatting.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 57bab84bb4d..9aa9d438638 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -425,18 +425,18 @@ def summarize_index( if max_width is None: max_width = OPTIONS["display_width"] - def prefix(index, length): + def suffix(index, length): if index == 0 and length == 1: return " " elif index == 0: - return "┌" + return "┐" elif index >= length - 1: - return "└" + return "┘" else: return "│" preformatted = [ - pretty_print(f" {prefix(index, len(names))} {name} ", col_width) + pretty_print(f" {name} ", col_width) + suffix(index, len(names)) + " " for index, name in enumerate(names) ] From 56b621ff8cffb4f093ecde304d5e62082470c943 Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 15:27:05 +0200 Subject: [PATCH 06/22] fix the repr of `Indexes` --- xarray/core/indexes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xarray/core/indexes.py b/xarray/core/indexes.py index a18322fe06b..17064e949b3 100644 --- a/xarray/core/indexes.py +++ b/xarray/core/indexes.py @@ -1309,7 +1309,8 @@ def __getitem__(self, key) -> T_PandasOrXarrayIndex: return self._indexes[key] def __repr__(self): - return formatting.indexes_repr(self) + indexes = formatting._get_indexes_dict(self) + return formatting.indexes_repr(indexes) def default_indexes( From fa70fc5e369d84912dd9073539dd00bf338b40d3 Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 15:50:31 +0200 Subject: [PATCH 07/22] only add combine markers for xarray indexes --- xarray/core/formatting.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 9aa9d438638..f2c3dc3114d 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -422,6 +422,8 @@ def inline_index_repr(index, max_width=None): def summarize_index( names: tuple[Hashable], index, col_width: int, max_width: int = None ): + from .indexes import Index + if max_width is None: max_width = OPTIONS["display_width"] @@ -435,10 +437,12 @@ def suffix(index, length): else: return "│" - preformatted = [ - pretty_print(f" {name} ", col_width) + suffix(index, len(names)) + " " - for index, name in enumerate(names) - ] + preformatted = [pretty_print(f" {name}", col_width) for name in names] + if isinstance(index, Index): + preformatted = [ + f"{name} {suffix(position, len(names))} " + for position, name in enumerate(preformatted) + ] head, *tail = preformatted index_width = max_width - len(head) From 08b2504f53c9bef801fd61218666662799392723 Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 18:31:06 +0200 Subject: [PATCH 08/22] select option 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the box components should be common enough that we can use it (and the worst that can happen is that those characters are displayed with a replacement glyph – usually a diamond with a question mark) --- xarray/core/formatting.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index f2c3dc3114d..e95e2c77895 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -422,27 +422,23 @@ def inline_index_repr(index, max_width=None): def summarize_index( names: tuple[Hashable], index, col_width: int, max_width: int = None ): - from .indexes import Index - if max_width is None: max_width = OPTIONS["display_width"] - def suffix(index, length): + def prefix(index, length): if index == 0 and length == 1: return " " elif index == 0: - return "┐" + return "┌" elif index >= length - 1: - return "┘" + return "└" else: return "│" - preformatted = [pretty_print(f" {name}", col_width) for name in names] - if isinstance(index, Index): - preformatted = [ - f"{name} {suffix(position, len(names))} " - for position, name in enumerate(preformatted) - ] + preformatted = [ + pretty_print(f" {prefix(position, len(names))} {name}", col_width) + for position, name in enumerate(names) + ] head, *tail = preformatted index_width = max_width - len(head) From 62709567c8d5d8f7b2c3608387b3c568139f48ea Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 26 Oct 2022 20:57:43 +0200 Subject: [PATCH 09/22] improve typing Co-authored-by: Illviljan <14371165+Illviljan@users.noreply.github.com> --- xarray/core/formatting.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index e95e2c77895..130a32bd337 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -420,12 +420,12 @@ def inline_index_repr(index, max_width=None): def summarize_index( - names: tuple[Hashable], index, col_width: int, max_width: int = None -): + names: tuple[Hashable, ...], index, col_width: int, max_width: int | None = None +) -> str: if max_width is None: max_width = OPTIONS["display_width"] - def prefix(index, length): + def prefix(index: int, length: int) -> str: if index == 0 and length == 1: return " " elif index == 0: @@ -446,7 +446,7 @@ def prefix(index, length): return "\n".join([head + repr_] + [line.rstrip() for line in tail]) -def filter_nondefault_indexes(indexes, filter_indexes): +def filter_nondefault_indexes(indexes, filter_indexes: bool): from .indexes import PandasIndex, PandasMultiIndex if not filter_indexes: @@ -461,7 +461,7 @@ def filter_nondefault_indexes(indexes, filter_indexes): } -def indexes_repr(indexes, max_rows=None): +def indexes_repr(indexes, max_rows: int | None = None) -> str: col_width = _calculate_col_width(chain.from_iterable(indexes)) return _mapping_repr( From e3341ac44e58020d81ed0901068b3fa46cc55976 Mon Sep 17 00:00:00 2001 From: Keewis Date: Wed, 26 Oct 2022 20:59:11 +0200 Subject: [PATCH 10/22] whats-new.rst --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 04c814f9e00..ffbd2ae3dff 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -26,7 +26,7 @@ New Features - Add static typing to plot accessors (:issue:`6949`, :pull:`7052`). By `Michael Niklas `_. - Display the indexes in a new section of the text and HTML reprs - (:pull:`6795`, :pull:`7183`, :pull:`7185`) + (:pull:`6795`, :pull:`7183`, :pull:`7185`, :pull:`7225`) By `Justus Magin `_ and `Benoît Bovy `_. Breaking changes From 4c212d21b8fc294ba446e431abb1dc5301c6cab1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 13 Jul 2023 14:14:38 +0000 Subject: [PATCH 11/22] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- xarray/core/formatting.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 0c134e0f531..f6c91beabb2 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -424,7 +424,10 @@ def inline_index_repr(index, max_width=None): def summarize_index( - names: tuple[Hashable, ...], index: int, col_width: int, max_width: int | None = None + names: tuple[Hashable, ...], + index: int, + col_width: int, + max_width: int | None = None, ) -> str: if max_width is None: max_width = OPTIONS["display_width"] @@ -451,7 +454,7 @@ def prefix(index: int, length: int) -> str: def filter_nondefault_indexes(indexes, filter_indexes: bool): - from .indexes import PandasIndex, PandasMultiIndex + from xarray.core.indexes import PandasIndex, PandasMultiIndex if not filter_indexes: return indexes From 7936c5570ac703f82b8c381e01c126df0c6e1658 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 19:33:10 +0200 Subject: [PATCH 12/22] simplify the visual hint construction --- xarray/core/formatting.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index f6c91beabb2..876f7bd2d4a 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -432,19 +432,15 @@ def summarize_index( if max_width is None: max_width = OPTIONS["display_width"] - def prefix(index: int, length: int) -> str: - if index == 0 and length == 1: - return " " - elif index == 0: - return "┌" - elif index >= length - 1: - return "└" - else: - return "│" + def prefixes(length: int) -> list[str]: + if length in (0, 1): + return [" "] + + return ["┌"] + ["│"] * max(length - 2, 0) + ["└"] preformatted = [ - pretty_print(f" {prefix(position, len(names))} {name}", col_width) - for position, name in enumerate(names) + pretty_print(f" {prefix} {name}", col_width) + for prefix, name in zip(prefixes(len(names)), names) ] head, *tail = preformatted From bc1d61f36f6d66b9c3cd879d32bbdbb63fb45147 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 19:52:51 +0200 Subject: [PATCH 13/22] improve the existing index repr test --- xarray/tests/test_formatting.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index bf5f7d0bdc5..ddb9a5d1a0b 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -218,7 +218,7 @@ def test_attribute_repr(self) -> None: assert "\n" not in newlines assert "\t" not in tabs - def test_index_repr(self): + def test_index_repr(self) -> None: from xarray.core.indexes import Index class CustomIndex(Index): @@ -230,17 +230,18 @@ def __repr__(self): coord_names = ["x", "y"] index = CustomIndex(coord_names) - name = "x" + names = ["x"] - normal = formatting.summarize_index(name, index, col_width=20) - assert name in normal + normal = formatting.summarize_index(names, index, col_width=20) + assert names[0] in normal + assert len(normal.splitlines()) == len(names) assert "CustomIndex" in normal CustomIndex._repr_inline_ = ( lambda self, max_width: f"CustomIndex[{', '.join(self.names)}]" ) - inline = formatting.summarize_index(name, index, col_width=20) - assert name in inline + inline = formatting.summarize_index(names, index, col_width=20) + assert names[0] in inline assert index._repr_inline_(max_width=40) in inline def test_diff_array_repr(self) -> None: From e6e5313c9004ccdeb295247c704ad4f743177585 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 19:53:05 +0200 Subject: [PATCH 14/22] check that the hints are constructed correctly --- xarray/tests/test_formatting.py | 34 +++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index ddb9a5d1a0b..a87ecb3b6ad 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -244,6 +244,40 @@ def __repr__(self): assert names[0] in inline assert index._repr_inline_(max_width=40) in inline + @pytest.mark.parametrize( + "names", + ( + ["x"], + ["x", "y"], + ["x", "y", "z"], + ["x", "y", "z", "a"], + ), + ) + def test_index_repr_grouping(self, names) -> None: + from xarray.core.indexes import Index + + class CustomIndex(Index): + def __init__(self, names): + self.names = names + + def __repr__(self): + return f"CustomIndex(coords={self.names})" + + index = CustomIndex(names) + + normal = formatting.summarize_index(names, index, col_width=20) + assert all(name in normal for name in names) + assert len(normal.splitlines()) == len(names) + assert "CustomIndex" in normal + + hint_chars = [line[2] for line in normal.splitlines()] + + if len(names) <= 1: + assert hint_chars == [" "] + else: + assert hint_chars[0] == "┌" and hint_chars[-1] == "└" + assert len(names) == 2 or hint_chars[1:-1] == ["│"] * (len(names) - 2) + def test_diff_array_repr(self) -> None: da_a = xr.DataArray( np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"), From 66689ea0e0d42aeb5f10c21ed4105e4e36b9f419 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 20:08:22 +0200 Subject: [PATCH 15/22] convert the names to tuples --- xarray/tests/test_formatting.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index a87ecb3b6ad..f4879809da5 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -247,10 +247,10 @@ def __repr__(self): @pytest.mark.parametrize( "names", ( - ["x"], - ["x", "y"], - ["x", "y", "z"], - ["x", "y", "z", "a"], + ("x",), + ("x", "y"), + ("x", "y", "z"), + ("x", "y", "z", "a"), ), ) def test_index_repr_grouping(self, names) -> None: From 7e82e42f6daea85eac76d7c40eb359036dfee6b7 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 20:10:00 +0200 Subject: [PATCH 16/22] revert the typing of `index` --- xarray/core/formatting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 876f7bd2d4a..ebb9f1eb1a9 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -425,7 +425,7 @@ def inline_index_repr(index, max_width=None): def summarize_index( names: tuple[Hashable, ...], - index: int, + index, col_width: int, max_width: int | None = None, ) -> str: From ce8c129cd39b88e8f6d20c229d14da52904d8d40 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 20:10:46 +0200 Subject: [PATCH 17/22] more conversion to tuple --- xarray/tests/test_formatting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index f4879809da5..0da6027ec5e 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -230,7 +230,7 @@ def __repr__(self): coord_names = ["x", "y"] index = CustomIndex(coord_names) - names = ["x"] + names = ("x",) normal = formatting.summarize_index(names, index, col_width=20) assert names[0] in normal From 6d7cf71f4be6949a8519eba5eab491b753176522 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 20:19:36 +0200 Subject: [PATCH 18/22] type hint the instance variable --- xarray/tests/test_formatting.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index 0da6027ec5e..cf9db0810fd 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -222,6 +222,8 @@ def test_index_repr(self) -> None: from xarray.core.indexes import Index class CustomIndex(Index): + names: tuple[str, ...] + def __init__(self, names): self.names = names From f2c6683107cf766a07e3fe57bc93d60b75ab2657 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 13 Jul 2023 20:24:33 +0200 Subject: [PATCH 19/22] whats-new entry --- doc/whats-new.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 25993274679..27ca7c5a3c8 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -21,7 +21,8 @@ v2023.06.1 (unreleased) New Features ~~~~~~~~~~~~ - +- Visually group together coordinates with the same indexes in the index section of the text repr (:pull:`7225`). + By `Justus Magin `_. Breaking changes ~~~~~~~~~~~~~~~~ @@ -548,7 +549,7 @@ New Features - Add static typing to plot accessors (:issue:`6949`, :pull:`7052`). By `Michael Niklas `_. - Display the indexes in a new section of the text and HTML reprs - (:pull:`6795`, :pull:`7183`, :pull:`7185`, :pull:`7225`) + (:pull:`6795`, :pull:`7183`, :pull:`7185`) By `Justus Magin `_ and `Benoît Bovy `_. - Added methods :py:meth:`DataArrayGroupBy.cumprod` and :py:meth:`DatasetGroupBy.cumprod`. (:pull:`5816`) From f62c16f15ecc8d290016d53fcf41d6e8f04c093a Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 14 Jul 2023 11:43:26 +0200 Subject: [PATCH 20/22] don't type-check the monkeypatching --- xarray/tests/test_formatting.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index cf9db0810fd..104d7380f1a 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -239,7 +239,7 @@ def __repr__(self): assert len(normal.splitlines()) == len(names) assert "CustomIndex" in normal - CustomIndex._repr_inline_ = ( + CustomIndex._repr_inline_ = ( # type: ignore lambda self, max_width: f"CustomIndex[{', '.join(self.names)}]" ) inline = formatting.summarize_index(names, index, col_width=20) From 279f9485d82b14832af164216a34ae8db38b30c4 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 14 Jul 2023 11:50:51 +0200 Subject: [PATCH 21/22] adjust the typing, again --- xarray/tests/test_formatting.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index 104d7380f1a..3039ba941fd 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -224,13 +224,13 @@ def test_index_repr(self) -> None: class CustomIndex(Index): names: tuple[str, ...] - def __init__(self, names): + def __init__(self, names: tuple[str, ...]): self.names = names def __repr__(self): return f"CustomIndex(coords={self.names})" - coord_names = ["x", "y"] + coord_names = ("x", "y") index = CustomIndex(coord_names) names = ("x",) @@ -240,7 +240,7 @@ def __repr__(self): assert "CustomIndex" in normal CustomIndex._repr_inline_ = ( # type: ignore - lambda self, max_width: f"CustomIndex[{', '.join(self.names)}]" + lambda self, max_width: f"CustomIndex[{', '.join(self.names)}]" # type: ignore ) inline = formatting.summarize_index(names, index, col_width=20) assert names[0] in inline From e05228333732835ae4b429080beab6d04e8fa8ec Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Tue, 18 Jul 2023 15:58:35 +0200 Subject: [PATCH 22/22] use a subclass instead of monkeypatching and type-ignores --- xarray/tests/test_formatting.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index 3039ba941fd..7670b77322c 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -239,9 +239,11 @@ def __repr__(self): assert len(normal.splitlines()) == len(names) assert "CustomIndex" in normal - CustomIndex._repr_inline_ = ( # type: ignore - lambda self, max_width: f"CustomIndex[{', '.join(self.names)}]" # type: ignore - ) + class IndexWithInlineRepr(CustomIndex): + def _repr_inline_(self, max_width: int): + return f"CustomIndex[{', '.join(self.names)}]" + + index = IndexWithInlineRepr(coord_names) inline = formatting.summarize_index(names, index, col_width=20) assert names[0] in inline assert index._repr_inline_(max_width=40) in inline