Skip to content

Commit 7379923

Browse files
authored
use _repr_inline_ for indexes that define it (#7183)
* use the inline repr, if available * remove the unused max_width argument * also remove the unused is_index parameter * add tests for the index summarizer * add a basic _repr_inline_ implementation * don't delegate to __repr__ since _repr_inline_ is now guaranteed to exist * update the test to check the default implementation * don't strip the `Index` suffix * undo the code simplification: pandas indexes use the same code path and the raw pandas indexes don't define `_repr_inline_`. * move the inline index repr formatting to a separate function * properly use the max_width setting * fix the definition of the `_repr_inline_` method * disable `mypy` for the index formatting test It does not allow reassigning the method, and it also complains about an attribute created in the constructor. * styling [skip-ci] * trigger CI * add a comment explaining why we need the `repr` fallback
1 parent 89f7de8 commit 7379923

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

xarray/core/formatting.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,26 @@ def coords_repr(coords, col_width=None, max_rows=None):
408408
)
409409

410410

411-
def summarize_index(
412-
name: Hashable, index, col_width: int, max_width: int = None, is_index: bool = False
413-
):
414-
return pretty_print(f" {name} ", col_width) + f"{repr(index)}"
411+
def inline_index_repr(index, max_width=None):
412+
if hasattr(index, "_repr_inline_"):
413+
repr_ = index._repr_inline_(max_width=max_width)
414+
else:
415+
# fallback for the `pandas.Index` subclasses from
416+
# `Indexes.get_pandas_indexes` / `xr_obj.indexes`
417+
repr_ = repr(index)
418+
419+
return repr_
420+
421+
422+
def summarize_index(name: Hashable, index, col_width: int, max_width: int = None):
423+
if max_width is None:
424+
max_width = OPTIONS["display_width"]
425+
426+
preformatted = pretty_print(f" {name} ", col_width)
427+
428+
index_width = max_width - len(preformatted)
429+
repr_ = inline_index_repr(index, max_width=index_width)
430+
return preformatted + repr_
415431

416432

417433
def nondefault_indexes(indexes):

xarray/core/indexes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ def _copy(self, deep: bool = True, memo: dict[int, Any] | None = None) -> Index:
133133
def __getitem__(self, indexer: Any):
134134
raise NotImplementedError()
135135

136+
def _repr_inline_(self, max_width):
137+
return self.__class__.__name__
138+
136139

137140
def _maybe_cast_to_cftimeindex(index: pd.Index) -> pd.Index:
138141
from ..coding.cftimeindex import CFTimeIndex

xarray/tests/test_formatting.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,31 @@ def test_attribute_repr(self) -> None:
219219
assert "\n" not in newlines
220220
assert "\t" not in tabs
221221

222+
def test_index_repr(self):
223+
from xarray.core.indexes import Index
224+
225+
class CustomIndex(Index):
226+
def __init__(self, names):
227+
self.names = names
228+
229+
def __repr__(self):
230+
return f"CustomIndex(coords={self.names})"
231+
232+
coord_names = ["x", "y"]
233+
index = CustomIndex(coord_names)
234+
name = "x"
235+
236+
normal = formatting.summarize_index(name, index, col_width=20)
237+
assert name in normal
238+
assert "CustomIndex" in normal
239+
240+
CustomIndex._repr_inline_ = (
241+
lambda self, max_width: f"CustomIndex[{', '.join(self.names)}]"
242+
)
243+
inline = formatting.summarize_index(name, index, col_width=20)
244+
assert name in inline
245+
assert index._repr_inline_(max_width=40) in inline
246+
222247
def test_diff_array_repr(self) -> None:
223248
da_a = xr.DataArray(
224249
np.array([[1, 2, 3], [4, 5, 6]], dtype="int64"),

0 commit comments

Comments
 (0)