[Python-checkins] cpython: Issue #17530: pprint now wraps long bytes objects and bytearrays.

serhiy.storchaka python-checkins at python.org
Tue Mar 24 18:23:27 CET 2015


https://hg.python.org/cpython/rev/976de10bf731
changeset:   95168:976de10bf731
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Tue Mar 24 19:22:37 2015 +0200
summary:
  Issue #17530: pprint now wraps long bytes objects and bytearrays.

files:
  Lib/pprint.py           |   47 +++++++++++++
  Lib/test/test_pprint.py |  100 ++++++++++++++++++++++++++++
  Misc/NEWS               |    2 +
  3 files changed, 149 insertions(+), 0 deletions(-)


diff --git a/Lib/pprint.py b/Lib/pprint.py
--- a/Lib/pprint.py
+++ b/Lib/pprint.py
@@ -283,6 +283,36 @@
 
     _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,
                            level):
         write = stream.write
@@ -463,5 +493,22 @@
     print("_safe_repr:", t2 - t1)
     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__":
     _perfcheck()
diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py
--- a/Lib/test/test_pprint.py
+++ b/Lib/test/test_pprint.py
@@ -658,6 +658,106 @@
             self.assertLessEqual(maxwidth, w)
             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):
 
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -26,6 +26,8 @@
 Library
 -------
 
+- Issue #17530: pprint now wraps long bytes objects and bytearrays.
+
 - Issue #22687: Fixed some corner cases in breaking words in tetxtwrap.
   Got rid of quadratic complexity in breaking long words.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list