diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 0cfd0e970a44c..7a42a37e6f6d1 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1247,11 +1247,11 @@ def _format_data(self, name=None) -> str_t: line_break_each_value=self._is_multi, ) - def _format_attrs(self) -> list[tuple[str_t, str_t | int]]: + def _format_attrs(self) -> list[tuple[str_t, str_t | int | bool | None]]: """ Return a list of tuples of the (attr,formatted_value). """ - attrs: list[tuple[str_t, str_t | int]] = [] + attrs: list[tuple[str_t, str_t | int | bool | None]] = [] if not self._is_multi: attrs.append(("dtype", f"'{self.dtype}'")) @@ -1295,9 +1295,7 @@ def format( return self._format_with_header(header, na_rep=na_rep) - def _format_with_header( - self, header: list[str_t], na_rep: str_t = "NaN" - ) -> list[str_t]: + def _format_with_header(self, header: list[str_t], na_rep: str_t) -> list[str_t]: from pandas.io.formats.format import format_array values = self._values @@ -1387,9 +1385,16 @@ def _summary(self, name=None) -> str_t: head = self[0] if hasattr(head, "format") and not isinstance(head, str): head = head.format() + elif needs_i8_conversion(self.dtype): + # e.g. Timedelta, display as values, not quoted + head = self._formatter_func(head).replace("'", "") tail = self[-1] if hasattr(tail, "format") and not isinstance(tail, str): tail = tail.format() + elif needs_i8_conversion(self.dtype): + # e.g. Timedelta, display as values, not quoted + tail = self._formatter_func(tail).replace("'", "") + index_summary = f", {head} to {tail}" else: index_summary = "" diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 02bbfe69be1b8..bd76f214e0261 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -44,6 +44,8 @@ inherit_names, ) +from pandas.io.formats.printing import pprint_thing + _index_doc_kwargs: dict[str, str] = dict(ibase._index_doc_kwargs) _index_doc_kwargs.update({"target_klass": "CategoricalIndex"}) @@ -180,6 +182,7 @@ def _can_hold_strings(self): codes: np.ndarray categories: Index + ordered: bool | None _data: Categorical _values: Categorical @@ -342,20 +345,18 @@ def _format_attrs(self): if get_option("display.max_categories") == 0 else get_option("display.max_categories") ) + attrs: list[tuple[str, str | int | bool | None]] attrs = [ ( "categories", ibase.default_pprint(self.categories, max_seq_items=max_categories), ), - # error: "CategoricalIndex" has no attribute "ordered" - ("ordered", self.ordered), # type: ignore[attr-defined] + ("ordered", self.ordered), ] extra = super()._format_attrs() return attrs + extra - def _format_with_header(self, header: list[str], na_rep: str = "NaN") -> list[str]: - from pandas.io.formats.printing import pprint_thing - + def _format_with_header(self, header: list[str], na_rep: str) -> list[str]: result = [ pprint_thing(x, escape_chars=("\t", "\r", "\n")) if notna(x) else na_rep for x in self._values diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 4cff33f96de27..b5c68fb7ada54 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -188,6 +188,7 @@ def format( def _format_with_header( self, header: list[str], na_rep: str = "NaT", date_format: str | None = None ) -> list[str]: + # matches base class except for whitespace padding and date_format return header + list( self._format_native_types(na_rep=na_rep, date_format=date_format) ) @@ -207,39 +208,15 @@ def _format_attrs(self): freq = self.freqstr if freq is not None: freq = repr(freq) # e.g. D -> 'D' - # Argument 1 to "append" of "list" has incompatible type - # "Tuple[str, Optional[str]]"; expected "Tuple[str, Union[str, int]]" - attrs.append(("freq", freq)) # type: ignore[arg-type] + attrs.append(("freq", freq)) return attrs + @Appender(Index._summary.__doc__) def _summary(self, name=None) -> str: - """ - Return a summarized representation. - - Parameters - ---------- - name : str - Name to use in the summary representation. - - Returns - ------- - str - Summarized representation of the index. - """ - formatter = self._formatter_func - if len(self) > 0: - index_summary = f", {formatter(self[0])} to {formatter(self[-1])}" - else: - index_summary = "" - - if name is None: - name = type(self).__name__ - result = f"{name}: {len(self)} entries{index_summary}" + result = super()._summary(name=name) if self.freq: result += f"\nFreq: {self.freqstr}" - # display as values, not quoted - result = result.replace("'", "") return result # -------------------------------------------------------------------- diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 165048e2a591a..72398ab9d43f6 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -800,7 +800,8 @@ def length(self) -> Index: # Rendering Methods # __repr__ associated methods are based on MultiIndex - def _format_with_header(self, header: list[str], na_rep: str = "NaN") -> list[str]: + def _format_with_header(self, header: list[str], na_rep: str) -> list[str]: + # matches base class except for whitespace padding return header + list(self._format_native_types(na_rep=na_rep)) def _format_native_types(self, na_rep="NaN", quoting=None, **kwargs): diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 9eb086ed97180..36997481b82dd 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -214,7 +214,8 @@ def _format_data(self, name=None): # we are formatting thru the attributes return None - def _format_with_header(self, header: list[str], na_rep: str = "NaN") -> list[str]: + def _format_with_header(self, header: list[str], na_rep: str) -> list[str]: + # Equivalent to Index implementation, but faster if not len(self._range): return header first_val_str = str(self._range[0])