8000 gh-90117: handle dict and mapping views in pprint (#30135) · python/cpython@c7f8e70 · GitHub
[go: up one dir, main page]

Skip to content

Commit c7f8e70

Browse files
devdanzinblurb-it[bot]merwokarhadthedevAA-Turner
authored
gh-90117: handle dict and mapping views in pprint (#30135)
* Teach pprint about dict views with PrettyPrinter._pprint_dict_view and ._pprint_dict_items_view. * Use _private names for _dict_*_view attributes of PrettyPrinter. * Use explicit 'items' keyword when calling _pprint_dict_view from _pprint_dict_items_view. * 📜🤖 Added by blurb_it. * Improve tests * Add tests for collections.abc.[Keys|Items|Mapping|Values]View support in pprint. * Add support for collections.abc.[Keys|Items|Mapping|Values]View in pprint. * Split _pprint_dict_view into _pprint_abc_view, so pretty-printing normal dict views and ABC views is handled in two simple methods. * Simplify redundant code. * Add collections.abc views to some existing pprint tests. * Test that views from collection.UserDict are correctly formatted by pprint. * Handle recursive dict and ABC views. * Test that subclasses of ABC views work in pprint. * Test dict views coming from collections.Counter. * Test ABC views coming from collections.ChainMap. * Test odict views coming from collections.OrderedDict. * Rename _pprint_abc_view to _pprint_mapping_abc_view. * Add pprint test for mapping ABC views where ._mapping has a custom __repr__ and fix ChainMap test. * When a mapping ABC view has a ._mapping that defines a custom __repr__, dispatch pretty-printing it by that __repr__. * Add tests for ABC mapping views subclasses that don't replace __repr__, also handling those that delete ._mapping on instances. * Simplify the pretty printing of ABC mapping views. * Add a test for depth handling when pretty printing dict views. * Fix checking whether the view type is a subclass of an items view, add a test. * Move construction of the views __repr__ set out of _safe_repr. --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Éric <merwok@netwok.org> Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net> Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Co-authored-by: Gregory P. Smith <greg@krypto.org>
1 parent 91e6a58 commit c7f8e70

File tree

3 files changed

+424
-2
lines changed

3 files changed

+424
-2
lines changed

Lib/pprint.py

Lines changed: 79 additions & 0 deletions
294
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,49 @@ def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level
248248

249249
_dispatch[_collections.OrderedDict.__repr__] = _pprint_ordered_dict
250250

251+
def _pprint_dict_view(self, object, stream, indent, allowance, context, level):
252+
"""Pretty print dict views (keys, values, items)."""
253+
if isinstance(object, self._dict_items_view):
254+
key = _safe_tuple
255+
else:
256+
key = _safe_key
257+
write = stream.write
258+
write(object.__class__.__name__ + '([')
259+
if self._indent_per_level > 1:
260+
write((self._indent_per_level - 1) * ' ')
261+
length = len(object)
262+
if length:
263+
if self._sort_dicts:
264+
entries = sorted(object, key=key)
265+
else:
266+
entries = object
267+
self._format_items(entries, stream, indent, allowance + 1,
268+
context, level)
269+
write('])')
270+
271+
def _pprint_mapping_abc_view(self, object, stream, indent, allowance, context, level):
272+
"""Pretty print mapping views from collections.abc."""
273+
write = stream.write
274+
write(object.__class__.__name__ + '(')
275+
# Dispatch formatting to the view's _mapping
276+
self._format(object._mapping, stream, indent, allowance, context, level)
277+
write(')')
278+
279+
_dict_keys_view = type({}.keys())
280+
_dispatch[_dict_keys_view.__repr__] = _pprint_dict_view
281+
282+
_dict_values_view = type({}.values())
283+
_dispatch[_dict_values_view.__repr__] = _pprint_dict_view
284+
285+
_dict_items_view = type({}.items())
286+
_dispatch[_dict_items_view.__repr__] = _pprint_dict_view
287+
288+
_dispatch[_collections.abc.MappingView.__repr__] = _pprint_mapping_abc_view
289+
290+
_view_reprs = {cls.__repr__ for cls in
291+
(_dict_keys_view, _dict_values_view, _dict_items_view,
292+
_collections.abc.MappingView)}
293+
251
def _pprint_list(self, object, stream, indent, allowance, context, level):
252295
stream.write('[')
253296
self._format_items(object, stream, indent, allowance + 1,
@@ -610,6 +653,42 @@ def _safe_repr(self, object, context, maxlevels, level):
610653
del context[objid]
611654
return "{%s}" % ", ".join(components), readable, recursive
612655

656+
if issubclass(typ, _collections.abc.MappingView) and r in self._view_reprs:
657+
objid = id(object)
658+
if maxlevels and level >= maxlevels:
659+
return "{...}", False, objid in context
660+
if objid in context:
661+
return _recursion(object), False, True
662+
key = _safe_key
663+
if issubclass(typ, (self._dict_items_view, _collections.abc.ItemsView)):
664+
key = _safe_tuple
665+
if hasattr(object, "_mapping"):
666+
# Dispatch formatting to the view's _mapping
667+
mapping_repr, readable, recursive = self.format(
668+
object._mapping, context, maxlevels, level)
669+
return (typ.__name__ + '(%s)' % mapping_repr), readable, recursive
670+
elif hasattr(typ, "_mapping"):
671+
# We have a view that somehow has lost its type's _mapping, raise
672+
# an error by calling repr() instead of failing cryptically later
673+
return repr(object), True, False
674+
if self._sort_dicts:
675+
object = sorted(object, key=key)
676+
context[objid] = 1
677+
readable = True
678+
recursive = False
679+
components = []
680+
append = components.append
681+
level += 1
682+
for val in object:
683+
vrepr, vreadable, vrecur = self.format(
684+
val, context, maxlevels, level)
685+
append(vrepr)
686+
readable = readable and vreadable
687+
if vrecur:
688+
recursive = True
689+
del context[objid]
690+
return typ.__name__ + '([%s])' % ", ".join(components), readable, recursive
691+
613692
if (issubclass(typ, list) and r is list.__repr__) or \
614693
(issubclass(typ, tuple) and r is tuple.__repr__):
615694
if issubclass(typ, list):

0 commit comments

Comments
 (0)
0