Skip to content

Commit 8a51e68

Browse files
authored
REF: share Index subclass formatting code (#44070)
1 parent 4f2b88a commit 8a51e68

File tree

5 files changed

+24
-39
lines changed

5 files changed

+24
-39
lines changed

pandas/core/indexes/base.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,11 +1247,11 @@ def _format_data(self, name=None) -> str_t:
12471247
line_break_each_value=self._is_multi,
12481248
)
12491249

1250-
def _format_attrs(self) -> list[tuple[str_t, str_t | int]]:
1250+
def _format_attrs(self) -> list[tuple[str_t, str_t | int | bool | None]]:
12511251
"""
12521252
Return a list of tuples of the (attr,formatted_value).
12531253
"""
1254-
attrs: list[tuple[str_t, str_t | int]] = []
1254+
attrs: list[tuple[str_t, str_t | int | bool | None]] = []
12551255

12561256
if not self._is_multi:
12571257
attrs.append(("dtype", f"'{self.dtype}'"))
@@ -1295,9 +1295,7 @@ def format(
12951295

12961296
return self._format_with_header(header, na_rep=na_rep)
12971297

1298-
def _format_with_header(
1299-
self, header: list[str_t], na_rep: str_t = "NaN"
1300-
) -> list[str_t]:
1298+
def _format_with_header(self, header: list[str_t], na_rep: str_t) -> list[str_t]:
13011299
from pandas.io.formats.format import format_array
13021300

13031301
values = self._values
@@ -1387,9 +1385,16 @@ def _summary(self, name=None) -> str_t:
13871385
head = self[0]
13881386
if hasattr(head, "format") and not isinstance(head, str):
13891387
head = head.format()
1388+
elif needs_i8_conversion(self.dtype):
1389+
# e.g. Timedelta, display as values, not quoted
1390+
head = self._formatter_func(head).replace("'", "")
13901391
tail = self[-1]
13911392
if hasattr(tail, "format") and not isinstance(tail, str):
13921393
tail = tail.format()
1394+
elif needs_i8_conversion(self.dtype):
1395+
# e.g. Timedelta, display as values, not quoted
1396+
tail = self._formatter_func(tail).replace("'", "")
1397+
13931398
index_summary = f", {head} to {tail}"
13941399
else:
13951400
index_summary = ""

pandas/core/indexes/category.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
inherit_names,
4545
)
4646

47+
from pandas.io.formats.printing import pprint_thing
48+
4749
_index_doc_kwargs: dict[str, str] = dict(ibase._index_doc_kwargs)
4850
_index_doc_kwargs.update({"target_klass": "CategoricalIndex"})
4951

@@ -180,6 +182,7 @@ def _can_hold_strings(self):
180182

181183
codes: np.ndarray
182184
categories: Index
185+
ordered: bool | None
183186
_data: Categorical
184187
_values: Categorical
185188

@@ -342,20 +345,18 @@ def _format_attrs(self):
342345
if get_option("display.max_categories") == 0
343346
else get_option("display.max_categories")
344347
)
348+
attrs: list[tuple[str, str | int | bool | None]]
345349
attrs = [
346350
(
347351
"categories",
348352
ibase.default_pprint(self.categories, max_seq_items=max_categories),
349353
),
350-
# error: "CategoricalIndex" has no attribute "ordered"
351-
("ordered", self.ordered), # type: ignore[attr-defined]
354+
("ordered", self.ordered),
352355
]
353356
extra = super()._format_attrs()
354357
return attrs + extra
355358

356-
def _format_with_header(self, header: list[str], na_rep: str = "NaN") -> list[str]:
357-
from pandas.io.formats.printing import pprint_thing
358-
359+
def _format_with_header(self, header: list[str], na_rep: str) -> list[str]:
359360
result = [
360361
pprint_thing(x, escape_chars=("\t", "\r", "\n")) if notna(x) else na_rep
361362
for x in self._values

pandas/core/indexes/datetimelike.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def format(
188188
def _format_with_header(
189189
self, header: list[str], na_rep: str = "NaT", date_format: str | None = None
190190
) -> list[str]:
191+
# matches base class except for whitespace padding and date_format
191192
return header + list(
192193
self._format_native_types(na_rep=na_rep, date_format=date_format)
193194
)
@@ -207,39 +208,15 @@ def _format_attrs(self):
207208
freq = self.freqstr
208209
if freq is not None:
209210
freq = repr(freq) # e.g. D -> 'D'
210-
# Argument 1 to "append" of "list" has incompatible type
211-
# "Tuple[str, Optional[str]]"; expected "Tuple[str, Union[str, int]]"
212-
attrs.append(("freq", freq)) # type: ignore[arg-type]
211+
attrs.append(("freq", freq))
213212
return attrs
214213

214+
@Appender(Index._summary.__doc__)
215215
def _summary(self, name=None) -> str:
216-
"""
217-
Return a summarized representation.
218-
219-
Parameters
220-
----------
221-
name : str
222-
Name to use in the summary representation.
223-
224-
Returns
225-
-------
226-
str
227-
Summarized representation of the index.
228-
"""
229-
formatter = self._formatter_func
230-
if len(self) > 0:
231-
index_summary = f", {formatter(self[0])} to {formatter(self[-1])}"
232-
else:
233-
index_summary = ""
234-
235-
if name is None:
236-
name = type(self).__name__
237-
result = f"{name}: {len(self)} entries{index_summary}"
216+
result = super()._summary(name=name)
238217
if self.freq:
239218
result += f"\nFreq: {self.freqstr}"
240219

241-
# display as values, not quoted
242-
result = result.replace("'", "")
243220
return result
244221

245222
# --------------------------------------------------------------------

pandas/core/indexes/interval.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -800,7 +800,8 @@ def length(self) -> Index:
800800
# Rendering Methods
801801
# __repr__ associated methods are based on MultiIndex
802802

803-
def _format_with_header(self, header: list[str], na_rep: str = "NaN") -> list[str]:
803+
def _format_with_header(self, header: list[str], na_rep: str) -> list[str]:
804+
# matches base class except for whitespace padding
804805
return header + list(self._format_native_types(na_rep=na_rep))
805806

806807
def _format_native_types(self, na_rep="NaN", quoting=None, **kwargs):

pandas/core/indexes/range.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ def _format_data(self, name=None):
214214
# we are formatting thru the attributes
215215
return None
216216

217-
def _format_with_header(self, header: list[str], na_rep: str = "NaN") -> list[str]:
217+
def _format_with_header(self, header: list[str], na_rep: str) -> list[str]:
218+
# Equivalent to Index implementation, but faster
218219
if not len(self._range):
219220
return header
220221
first_val_str = str(self._range[0])

0 commit comments

Comments
 (0)