mirror of
https://github.com/python/cpython.git
synced 2025-08-02 08:02:56 +00:00
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>
This commit is contained in:
parent
91e6a58e2d
commit
c7f8e706e1
3 changed files with 424 additions and 2 deletions
|
@ -248,6 +248,49 @@ class PrettyPrinter:
|
|||
|
||||
_dispatch[_collections.OrderedDict.__repr__] = _pprint_ordered_dict
|
||||
|
||||
def _pprint_dict_view(self, object, stream, indent, allowance, context, level):
|
||||
"""Pretty print dict views (keys, values, items)."""
|
||||
if isinstance(object, self._dict_items_view):
|
||||
key = _safe_tuple
|
||||
else:
|
||||
key = _safe_key
|
||||
write = stream.write
|
||||
write(object.__class__.__name__ + '([')
|
||||
if self._indent_per_level > 1:
|
||||
write((self._indent_per_level - 1) * ' ')
|
||||
length = len(object)
|
||||
if length:
|
||||
if self._sort_dicts:
|
||||
entries = sorted(object, key=key)
|
||||
else:
|
||||
entries = object
|
||||
self._format_items(entries, stream, indent, allowance + 1,
|
||||
context, level)
|
||||
write('])')
|
||||
|
||||
def _pprint_mapping_abc_view(self, object, stream, indent, allowance, context, level):
|
||||
"""Pretty print mapping views from collections.abc."""
|
||||
write = stream.write
|
||||
write(object.__class__.__name__ + '(')
|
||||
# Dispatch formatting to the view's _mapping
|
||||
self._format(object._mapping, stream, indent, allowance, context, level)
|
||||
write(')')
|
||||
|
||||
_dict_keys_view = type({}.keys())
|
||||
_dispatch[_dict_keys_view.__repr__] = _pprint_dict_view
|
||||
|
||||
_dict_values_view = type({}.values())
|
||||
_dispatch[_dict_values_view.__repr__] = _pprint_dict_view
|
||||
|
||||
_dict_items_view = type({}.items())
|
||||
_dispatch[_dict_items_view.__repr__] = _pprint_dict_view
|
||||
|
||||
_dispatch[_collections.abc.MappingView.__repr__] = _pprint_mapping_abc_view
|
||||
|
||||
_view_reprs = {cls.__repr__ for cls in
|
||||
(_dict_keys_view, _dict_values_view, _dict_items_view,
|
||||
_collections.abc.MappingView)}
|
||||
|
||||
def _pprint_list(self, object, stream, indent, allowance, context, level):
|
||||
stream.write('[')
|
||||
self._format_items(object, stream, indent, allowance + 1,
|
||||
|
@ -610,6 +653,42 @@ class PrettyPrinter:
|
|||
del context[objid]
|
||||
return "{%s}" % ", ".join(components), readable, recursive
|
||||
|
||||
if issubclass(typ, _collections.abc.MappingView) and r in self._view_reprs:
|
||||
objid = id(object)
|
||||
if maxlevels and level >= maxlevels:
|
||||
return "{...}", False, objid in context
|
||||
if objid in context:
|
||||
return _recursion(object), False, True
|
||||
key = _safe_key
|
||||
if issubclass(typ, (self._dict_items_view, _collections.abc.ItemsView)):
|
||||
key = _safe_tuple
|
||||
if hasattr(object, "_mapping"):
|
||||
# Dispatch formatting to the view's _mapping
|
||||
mapping_repr, readable, recursive = self.format(
|
||||
object._mapping, context, maxlevels, level)
|
||||
return (typ.__name__ + '(%s)' % mapping_repr), readable, recursive
|
||||
elif hasattr(typ, "_mapping"):
|
||||
# We have a view that somehow has lost its type's _mapping, raise
|
||||
# an error by calling repr() instead of failing cryptically later
|
||||
return repr(object), True, False
|
||||
if self._sort_dicts:
|
||||
object = sorted(object, key=key)
|
||||
context[objid] = 1
|
||||
readable = True
|
||||
recursive = False
|
||||
components = []
|
||||
append = components.append
|
||||
level += 1
|
||||
for val in object:
|
||||
vrepr, vreadable, vrecur = self.format(
|
||||
val, context, maxlevels, level)
|
||||
append(vrepr)
|
||||
readable = readable and vreadable
|
||||
if vrecur:
|
||||
recursive = True
|
||||
del context[objid]
|
||||
return typ.__name__ + '([%s])' % ", ".join(components), readable, recursive
|
||||
|
||||
if (issubclass(typ, list) and r is list.__repr__) or \
|
||||
(issubclass(typ, tuple) and r is tuple.__repr__):
|
||||
if issubclass(typ, list):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue