Skip to content

BUG: pretty print all Mappings, not just dicts #57915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ MultiIndex
I/O
^^^
- Bug in :meth:`DataFrame.to_excel` when writing empty :class:`DataFrame` with :class:`MultiIndex` on both axes (:issue:`57696`)
- Now all ``Mapping`` s are pretty printed correctly. Before only literal ``dict`` s were. (:issue:`57915`)
-
-

Expand Down
10 changes: 5 additions & 5 deletions pandas/io/formats/printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ def pprint_thing(
_nest_lvl : internal use only. pprint_thing() is mutually-recursive
with pprint_sequence, this argument is used to keep track of the
current nesting level, and limit it.
escape_chars : list or dict, optional
Characters to escape. If a dict is passed the values are the
escape_chars : list[str] or Mapping[str, str], optional
Characters to escape. If a Mapping is passed the values are the
replacements
default_escapes : bool, default False
Whether the input escape characters replaces or adds to the defaults
Expand All @@ -204,11 +204,11 @@ def as_escaped_string(
thing: Any, escape_chars: EscapeChars | None = escape_chars
) -> str:
translate = {"\t": r"\t", "\n": r"\n", "\r": r"\r"}
if isinstance(escape_chars, dict):
if isinstance(escape_chars, Mapping):
if default_escapes:
translate.update(escape_chars)
else:
translate = escape_chars
translate = escape_chars # type: ignore[assignment]
escape_chars = list(escape_chars.keys())
else:
escape_chars = escape_chars or ()
Expand All @@ -220,7 +220,7 @@ def as_escaped_string(

if hasattr(thing, "__next__"):
return str(thing)
elif isinstance(thing, dict) and _nest_lvl < get_option(
elif isinstance(thing, Mapping) and _nest_lvl < get_option(
"display.pprint_nest_depth"
):
result = _pprint_dict(
Expand Down
18 changes: 18 additions & 0 deletions pandas/tests/io/formats/test_printing.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Note! This file is aimed specifically at pandas.io.formats.printing utility
# functions, not the general printing of pandas objects.
from collections.abc import Mapping
import string

import pandas._config.config as cf
Expand All @@ -16,6 +17,17 @@ def test_adjoin():
assert adjoined == expected


class MyMapping(Mapping):
def __getitem__(self, key):
return 4

def __iter__(self):
return iter(["a", "b"])

def __len__(self):
return 2


class TestPPrintThing:
def test_repr_binary_type(self):
letters = string.ascii_letters
Expand All @@ -42,6 +54,12 @@ def test_repr_obeys_max_seq_limit(self):
def test_repr_set(self):
assert printing.pprint_thing({1}) == "{1}"

def test_repr_dict(self):
assert printing.pprint_thing({"a": 4, "b": 4}) == "{'a': 4, 'b': 4}"

def test_repr_mapping(self):
assert printing.pprint_thing(MyMapping()) == "{'a': 4, 'b': 4}"


class TestFormatBase:
def test_adjoin(self):
Expand Down