Commit 022f2037 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #17530: pprint now wraps long bytes objects and bytearrays.

parent 8e2aa88a
...@@ -283,6 +283,36 @@ class PrettyPrinter: ...@@ -283,6 +283,36 @@ class PrettyPrinter:
_dispatch[str.__repr__] = _pprint_str _dispatch[str.__repr__] = _pprint_str
def _pprint_bytes(self, object, stream, indent, allowance, context, level):
write = stream.write
if len(object) <= 4:
write(repr(object))
return
parens = level == 1
if parens:
indent += 1
allowance += 1
write('(')
delim = ''
for rep in _wrap_bytes_repr(object, self._width - indent, allowance):
write(delim)
write(rep)
if not delim:
delim = '\n' + ' '*indent
if parens:
write(')')
_dispatch[bytes.__repr__] = _pprint_bytes
def _pprint_bytearray(self, object, stream, indent, allowance, context, level):
write = stream.write
write('bytearray(')
self._pprint_bytes(bytes(object), stream, indent + 10,
allowance + 1, context, level + 1)
write(')')
_dispatch[bytearray.__repr__] = _pprint_bytearray
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
...@@ -463,5 +493,22 @@ def _perfcheck(object=None): ...@@ -463,5 +493,22 @@ def _perfcheck(object=None):
print("_safe_repr:", t2 - t1) print("_safe_repr:", t2 - t1)
print("pformat:", t3 - t2) print("pformat:", t3 - t2)
def _wrap_bytes_repr(object, width, allowance):
current = b''
last = len(object) // 4 * 4
for i in range(0, len(object), 4):
part = object[i: i+4]
candidate = current + part
if i == last:
width -= allowance
if len(repr(candidate)) > width:
if current:
yield repr(current)
current = part
else:
current = candidate
if current:
yield repr(current)
if __name__ == "__main__": if __name__ == "__main__":
_perfcheck() _perfcheck()
...@@ -658,6 +658,106 @@ frozenset2({0, ...@@ -658,6 +658,106 @@ frozenset2({0,
self.assertLessEqual(maxwidth, w) self.assertLessEqual(maxwidth, w)
self.assertGreater(maxwidth, w - 3) self.assertGreater(maxwidth, w - 3)
def test_bytes_wrap(self):
self.assertEqual(pprint.pformat(b'', width=1), "b''")
self.assertEqual(pprint.pformat(b'abcd', width=1), "b'abcd'")
letters = b'abcdefghijklmnopqrstuvwxyz'
self.assertEqual(pprint.pformat(letters, width=29), repr(letters))
self.assertEqual(pprint.pformat(letters, width=19), """\
(b'abcdefghijkl'
b'mnopqrstuvwxyz')""")
self.assertEqual(pprint.pformat(letters, width=18), """\
(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
self.assertEqual(pprint.pformat(letters, width=16), """\
(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
special = bytes(range(16))
self.assertEqual(pprint.pformat(special, width=61), repr(special))
self.assertEqual(pprint.pformat(special, width=48), """\
(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
self.assertEqual(pprint.pformat(special, width=32), """\
(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
self.assertEqual(pprint.pformat(special, width=1), """\
(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
width=21), """\
{'a': 1,
'b': b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz',
'c': 2}""")
self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
width=20), """\
{'a': 1,
'b': b'abcdefgh'
b'ijklmnop'
b'qrstuvwxyz',
'c': 2}""")
self.assertEqual(pprint.pformat([[[[[[letters]]]]]], width=25), """\
[[[[[[b'abcdefghijklmnop'
b'qrstuvwxyz']]]]]]""")
self.assertEqual(pprint.pformat([[[[[[special]]]]]], width=41), """\
[[[[[[b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f']]]]]]""")
# Check that the pprint is a usable repr
for width in range(1, 64):
formatted = pprint.pformat(special, width=width)
self.assertEqual(eval(formatted), special)
formatted = pprint.pformat([special] * 2, width=width)
self.assertEqual(eval(formatted), [special] * 2)
def test_bytearray_wrap(self):
self.assertEqual(pprint.pformat(bytearray(), width=1), "bytearray(b'')")
letters = bytearray(b'abcdefghijklmnopqrstuvwxyz')
self.assertEqual(pprint.pformat(letters, width=40), repr(letters))
self.assertEqual(pprint.pformat(letters, width=28), """\
bytearray(b'abcdefghijkl'
b'mnopqrstuvwxyz')""")
self.assertEqual(pprint.pformat(letters, width=27), """\
bytearray(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
self.assertEqual(pprint.pformat(letters, width=25), """\
bytearray(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz')""")
special = bytearray(range(16))
self.assertEqual(pprint.pformat(special, width=72), repr(special))
self.assertEqual(pprint.pformat(special, width=57), """\
bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
self.assertEqual(pprint.pformat(special, width=41), """\
bytearray(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
self.assertEqual(pprint.pformat(special, width=1), """\
bytearray(b'\\x00\\x01\\x02\\x03'
b'\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b'
b'\\x0c\\r\\x0e\\x0f')""")
self.assertEqual(pprint.pformat({'a': 1, 'b': letters, 'c': 2},
width=31), """\
{'a': 1,
'b': bytearray(b'abcdefghijkl'
b'mnopqrstuvwx'
b'yz'),
'c': 2}""")
self.assertEqual(pprint.pformat([[[[[letters]]]]], width=37), """\
[[[[[bytearray(b'abcdefghijklmnop'
b'qrstuvwxyz')]]]]]""")
self.assertEqual(pprint.pformat([[[[[special]]]]], width=50), """\
[[[[[bytearray(b'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07'
b'\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f')]]]]]""")
class DottedPrettyPrinter(pprint.PrettyPrinter): class DottedPrettyPrinter(pprint.PrettyPrinter):
......
...@@ -26,6 +26,8 @@ Core and Builtins ...@@ -26,6 +26,8 @@ Core and Builtins
Library Library
------- -------
- Issue #17530: pprint now wraps long bytes objects and bytearrays.
- Issue #22687: Fixed some corner cases in breaking words in tetxtwrap. - Issue #22687: Fixed some corner cases in breaking words in tetxtwrap.
Got rid of quadratic complexity in breaking long words. Got rid of quadratic complexity in breaking long words.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment