Issue #23741: Slightly refactor the pprint module to make it a little more

extesible.  No public API is added.
This commit is contained in:
Serhiy Storchaka 2015-03-24 18:45:23 +02:00
parent 72bd327db0
commit 8e2aa88a40

View file

@ -152,81 +152,91 @@ class PrettyPrinter:
return readable and not recursive return readable and not recursive
def _format(self, object, stream, indent, allowance, context, level): def _format(self, object, stream, indent, allowance, context, level):
level = level + 1
objid = id(object) objid = id(object)
if objid in context: if objid in context:
stream.write(_recursion(object)) stream.write(_recursion(object))
self._recursive = True self._recursive = True
self._readable = False self._readable = False
return return
rep = self._repr(object, context, level - 1) rep = self._repr(object, context, level)
typ = type(object)
max_width = self._width - indent - allowance max_width = self._width - indent - allowance
sepLines = len(rep) > max_width if len(rep) > max_width:
write = stream.write p = self._dispatch.get(type(object).__repr__, None)
if p is not None:
context[objid] = 1
p(self, object, stream, indent, allowance, context, level + 1)
del context[objid]
return
elif isinstance(object, dict):
context[objid] = 1
self._pprint_dict(object, stream, indent, allowance,
context, level + 1)
del context[objid]
return
stream.write(rep)
if sepLines: _dispatch = {}
r = getattr(typ, "__repr__", None)
if issubclass(typ, dict): def _pprint_dict(self, object, stream, indent, allowance, context, level):
write = stream.write
write('{') write('{')
if self._indent_per_level > 1: if self._indent_per_level > 1:
write((self._indent_per_level - 1) * ' ') write((self._indent_per_level - 1) * ' ')
length = len(object) length = len(object)
if length: if length:
context[objid] = 1 if isinstance(object, _OrderedDict):
if issubclass(typ, _OrderedDict):
items = list(object.items()) items = list(object.items())
else: else:
items = sorted(object.items(), key=_safe_tuple) items = sorted(object.items(), key=_safe_tuple)
self._format_dict_items(items, stream, self._format_dict_items(items, stream, indent, allowance + 1,
indent + self._indent_per_level,
allowance + 1,
context, level) context, level)
del context[objid]
write('}') write('}')
return
if ((issubclass(typ, list) and r is list.__repr__) or _dispatch[dict.__repr__] = _pprint_dict
(issubclass(typ, tuple) and r is tuple.__repr__) or _dispatch[_OrderedDict.__repr__] = _pprint_dict
(issubclass(typ, set) and r is set.__repr__) or
(issubclass(typ, frozenset) and r is frozenset.__repr__) def _pprint_list(self, object, stream, indent, allowance, context, level):
): stream.write('[')
length = len(object) self._format_items(object, stream, indent, allowance + 1,
if issubclass(typ, list): context, level)
write('[') stream.write(']')
endchar = ']'
elif issubclass(typ, tuple): _dispatch[list.__repr__] = _pprint_list
write('(')
if length == 1: def _pprint_tuple(self, object, stream, indent, allowance, context, level):
endchar = ',)' stream.write('(')
else: endchar = ',)' if len(object) == 1 else ')'
endchar = ')' self._format_items(object, stream, indent, allowance + len(endchar),
else: context, level)
if not length: stream.write(endchar)
write(rep)
_dispatch[tuple.__repr__] = _pprint_tuple
def _pprint_set(self, object, stream, indent, allowance, context, level):
if not len(object):
stream.write(repr(object))
return return
typ = object.__class__
if typ is set: if typ is set:
write('{') stream.write('{')
endchar = '}' endchar = '}'
else: else:
write(typ.__name__) stream.write(typ.__name__ + '({')
write('({')
endchar = '})' endchar = '})'
indent += len(typ.__name__) + 1 indent += len(typ.__name__) + 1
object = sorted(object, key=_safe_key) object = sorted(object, key=_safe_key)
if self._indent_per_level > 1: self._format_items(object, stream, indent, allowance + len(endchar),
write((self._indent_per_level - 1) * ' ')
if length:
context[objid] = 1
self._format_items(object, stream,
indent + self._indent_per_level,
allowance + len(endchar),
context, level) context, level)
del context[objid] stream.write(endchar)
write(endchar)
return
if issubclass(typ, str) and len(object) > 0 and r is str.__repr__: _dispatch[set.__repr__] = _pprint_set
_dispatch[frozenset.__repr__] = _pprint_set
def _pprint_str(self, object, stream, indent, allowance, context, level):
write = stream.write
if not len(object):
write(repr(object))
return
chunks = [] chunks = []
lines = object.splitlines(True) lines = object.splitlines(True)
if level == 1: if level == 1:
@ -270,12 +280,13 @@ class PrettyPrinter:
write(rep) write(rep)
if level == 1: if level == 1:
write(')') write(')')
return
write(rep) _dispatch[str.__repr__] = _pprint_str
def _format_dict_items(self, items, stream, indent, allowance, context, def _format_dict_items(self, items, stream, indent, allowance, context,
level): level):
write = stream.write write = stream.write
indent += self._indent_per_level
delimnl = ',\n' + ' ' * indent delimnl = ',\n' + ' ' * indent
last_index = len(items) - 1 last_index = len(items) - 1
for i, (key, ent) in enumerate(items): for i, (key, ent) in enumerate(items):
@ -291,6 +302,9 @@ class PrettyPrinter:
def _format_items(self, items, stream, indent, allowance, context, level): def _format_items(self, items, stream, indent, allowance, context, level):
write = stream.write write = stream.write
indent += self._indent_per_level
if self._indent_per_level > 1:
write((self._indent_per_level - 1) * ' ')
delimnl = ',\n' + ' ' * indent delimnl = ',\n' + ' ' * indent
delim = '' delim = ''
width = max_width = self._width - indent + 1 width = max_width = self._width - indent + 1