Counter prettyprinter should sort entries by count
- PrettyPrinter version: 0.17.0
- Python version: 3.7
- Operating System: linux
Description
PrettyPrinter does not sort Counter()s entries by count, unlike Counter.__str__ which explicitly does so.
What I Did
In [1]: prettyprinter.pformat(collections.Counter({"a": 1, "b": 200}))
Out[1]: "collections.Counter({'a': 1, 'b': 200})"
In [2]: str(collections.Counter({"a": 1, "b": 200}))
Out[2]: "Counter({'b': 200, 'a': 1})"
I think the sorted form is clearly more useful (well, at least, it matches the intent of whoever wrote the stdlib's Counter.__str__).
On Py3.6+ I think it's just a matter of
diff --git i/prettyprinter/pretty_stdlib.py w/prettyprinter/pretty_stdlib.py
index 273ee0e..9c66171 100644
--- i/prettyprinter/pretty_stdlib.py
+++ w/prettyprinter/pretty_stdlib.py
@@ -296,7 +296,7 @@ def pretty_ordereddict(d, ctx):
@register_pretty(Counter)
def pretty_counter(counter, ctx):
- return pretty_call_alt(ctx, type(counter), args=(dict(counter), ))
+ return pretty_call_alt(ctx, type(counter), args=(dict(counter.most_common()), ))
@register_pretty('enum.Enum')
(well the stdlib's version has additionally some handling when most_common() fails due to unorderable values, but you get the idea) but I'm not sure how to make this work on Py3.5.
I think this sounds good. I believe we'll need to extract logic from pretty_dict to a utility function that takes an iterable of key-value pairs instead of a dict, called something like pretty_dict_from_pairs so that we can use that function both here and in the implementation of pretty_dict. This will ensure Python 3.5 can correctly render the output in the most common order. Then the actual pretty printer for Counter can be implemented as
build_fncall(
ctx,
type(counter),
argdocs=(
pretty_dict_from_pairs(ctx, counter.most_common()),
),
hug_sole_arg=True
)