diff --git a/xarray/core/formatting.py b/xarray/core/formatting.py index 268e2eb63b3..e9aebe2f7c5 100644 --- a/xarray/core/formatting.py +++ b/xarray/core/formatting.py @@ -408,10 +408,26 @@ 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 -): - return pretty_print(f" {name} ", col_width) + f"{repr(index)}" +def inline_index_repr(index, max_width=None): + if hasattr(index, "_repr_inline_"): + repr_ = index._repr_inline_(max_width=max_width) + else: + # fallback for the `pandas.Index` subclasses from + # `Indexes.get_pandas_indexes` / `xr_obj.indexes` + repr_ = repr(index) + + return repr_ + + +def summarize_index(name: 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) + + index_width = max_width - len(preformatted) + repr_ = inline_index_repr(index, max_width=index_width) + return preformatted + repr_ def nondefault_indexes(indexes): diff --git a/xarray/core/indexes.py b/xarray/core/indexes.py index 3751903812f..a18322fe06b 100644 --- a/xarray/core/indexes.py +++ b/xarray/core/indexes.py @@ -133,6 +133,9 @@ def _copy(self, deep: bool = True, memo: dict[int, Any] | None = None) -> Index: def __getitem__(self, indexer: Any): raise NotImplementedError() + def _repr_inline_(self, max_width): + return self.__class__.__name__ + def _maybe_cast_to_cftimeindex(index: pd.Index) -> pd.Index: from ..coding.cftimeindex import CFTimeIndex diff --git a/xarray/tests/test_formatting.py b/xarray/tests/test_formatting.py index abbff51e0f9..39212c7964a 100644 --- a/xarray/tests/test_formatting.py +++ b/xarray/tests/test_formatting.py @@ -219,6 +219,31 @@ def test_attribute_repr(self) -> None: assert "\n" not in newlines assert "\t" not in tabs + def test_index_repr(self): + 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})" + + coord_names = ["x", "y"] + index = CustomIndex(coord_names) + name = "x" + + normal = formatting.summarize_index(name, index, col_width=20) + assert name in normal + 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 + assert index._repr_inline_(max_width=40) in inline + def test_diff_array_repr(self) -> None: da_a = xr.DataArray( np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"),