Patchwork D2987: stringutil: add function to pretty print an object

login
register
mail settings
Submitter phabricator
Date March 30, 2018, 9:16 p.m.
Message ID <differential-rev-PHID-DREV-f4qlqxnd3wynxzuqf52p-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/30028/
State Superseded
Headers show

Comments

phabricator - March 30, 2018, 9:16 p.m.
indygreg created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This is inspired by the pprint() module/function (which we can't
  use because the output is different on Python 2 and 3 - namely the
  use of b'' literals).
  
  We hook it up to `hg debugwireproto` for printing the response to
  a wire protocol command.
  
  This foreshadows future peer work, which will support decoding
  CBOR responses into rich data structures.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2987

AFFECTED FILES
  mercurial/debugcommands.py
  mercurial/utils/stringutil.py
  tests/test-http-protocol.t
  tests/test-ssh-proto.t

CHANGE DETAILS




To: indygreg, #hg-reviewers
Cc: mercurial-devel
phabricator - April 3, 2018, 4:42 p.m.
durin42 added inline comments.

INLINE COMMENTS

> stringutil.py:39
>  
> +def pprint(o):
> +    """Pretty print an object."""

Why this instead of pprint.pformat?

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2987

To: indygreg, #hg-reviewers
Cc: durin42, mercurial-devel
phabricator - April 3, 2018, 4:53 p.m.
indygreg added inline comments.

INLINE COMMENTS

> durin42 wrote in stringutil.py:39
> Why this instead of pprint.pformat?

Because of differences with `b''` in Python 3 :/

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2987

To: indygreg, #hg-reviewers
Cc: durin42, mercurial-devel

Patch

diff --git a/tests/test-ssh-proto.t b/tests/test-ssh-proto.t
--- a/tests/test-ssh-proto.t
+++ b/tests/test-ssh-proto.t
@@ -1345,7 +1345,7 @@ 
   o>     bookmarks	\n
   o>     namespaces	\n
   o>     phases	
-  response: bookmarks	\nnamespaces	\nphases	
+  response: b'bookmarks	\nnamespaces	\nphases	'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1376,7 +1376,7 @@ 
   o>     bookmarks	\n
   o>     namespaces	\n
   o>     phases	
-  response: bookmarks	\nnamespaces	\nphases	
+  response: b'bookmarks	\nnamespaces	\nphases	'
 
   $ cd ..
 
@@ -1421,7 +1421,7 @@ 
   i> flush() -> None
   o> bufferedreadline() -> 2:
   o>     0\n
-  response: 
+  response: b''
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1448,7 +1448,7 @@ 
   i> flush() -> None
   o> bufferedreadline() -> 2:
   o>     0\n
-  response: 
+  response: b''
 
 With a single bookmark set
 
@@ -1483,7 +1483,7 @@ 
   o> bufferedreadline() -> 3:
   o>     46\n
   o> bufferedread(46) -> 46: bookA	68986213bd4485ea51533535e3fc9e78007a711f
-  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f
+  response: b'bookA	68986213bd4485ea51533535e3fc9e78007a711f'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1511,7 +1511,7 @@ 
   o> bufferedreadline() -> 3:
   o>     46\n
   o> bufferedread(46) -> 46: bookA	68986213bd4485ea51533535e3fc9e78007a711f
-  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f
+  response: b'bookA	68986213bd4485ea51533535e3fc9e78007a711f'
 
 With multiple bookmarks set
 
@@ -1548,7 +1548,7 @@ 
   o> bufferedread(93) -> 93:
   o>     bookA	68986213bd4485ea51533535e3fc9e78007a711f\n
   o>     bookB	1880f3755e2e52e3199e0ee5638128b08642f34d
-  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f\nbookB	1880f3755e2e52e3199e0ee5638128b08642f34d
+  response: b'bookA	68986213bd4485ea51533535e3fc9e78007a711f\nbookB	1880f3755e2e52e3199e0ee5638128b08642f34d'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1578,7 +1578,7 @@ 
   o> bufferedread(93) -> 93:
   o>     bookA	68986213bd4485ea51533535e3fc9e78007a711f\n
   o>     bookB	1880f3755e2e52e3199e0ee5638128b08642f34d
-  response: bookA	68986213bd4485ea51533535e3fc9e78007a711f\nbookB	1880f3755e2e52e3199e0ee5638128b08642f34d
+  response: b'bookA	68986213bd4485ea51533535e3fc9e78007a711f\nbookB	1880f3755e2e52e3199e0ee5638128b08642f34d'
 
 Test pushkey for bookmarks
 
@@ -1624,7 +1624,7 @@ 
   o>     2\n
   o> bufferedread(2) -> 2:
   o>     1\n
-  response: 1\n
+  response: b'1\n'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1661,7 +1661,7 @@ 
   o>     2\n
   o> bufferedread(2) -> 2:
   o>     1\n
-  response: 1\n
+  response: b'1\n'
 
   $ hg bookmarks
      bookA                     0:68986213bd44
@@ -1707,7 +1707,7 @@ 
   o> bufferedreadline() -> 3:
   o>     15\n
   o> bufferedread(15) -> 15: publishing	True
-  response: publishing	True
+  response: b'publishing	True'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1735,7 +1735,7 @@ 
   o> bufferedreadline() -> 3:
   o>     15\n
   o> bufferedread(15) -> 15: publishing	True
-  response: publishing	True
+  response: b'publishing	True'
 
 Create some commits
 
@@ -1789,7 +1789,7 @@ 
   o>     20b8a89289d80036e6c4e87c2083e3bea1586637	1\n
   o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
   o>     publishing	True
-  response: 20b8a89289d80036e6c4e87c2083e3bea1586637	1\nc4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+  response: b'20b8a89289d80036e6c4e87c2083e3bea1586637	1\nc4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1820,7 +1820,7 @@ 
   o>     20b8a89289d80036e6c4e87c2083e3bea1586637	1\n
   o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
   o>     publishing	True
-  response: 20b8a89289d80036e6c4e87c2083e3bea1586637	1\nc4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+  response: b'20b8a89289d80036e6c4e87c2083e3bea1586637	1\nc4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True'
 
 Single draft head
 
@@ -1857,7 +1857,7 @@ 
   o> bufferedread(58) -> 58:
   o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
   o>     publishing	True
-  response: c4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+  response: b'c4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1887,7 +1887,7 @@ 
   o> bufferedread(58) -> 58:
   o>     c4750011d906c18ea2f0527419cbc1a544435150	1\n
   o>     publishing	True
-  response: c4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True
+  response: b'c4750011d906c18ea2f0527419cbc1a544435150	1\npublishing	True'
 
 All public heads
 
@@ -1922,7 +1922,7 @@ 
   o> bufferedreadline() -> 3:
   o>     15\n
   o> bufferedread(15) -> 15: publishing	True
-  response: publishing	True
+  response: b'publishing	True'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -1950,7 +1950,7 @@ 
   o> bufferedreadline() -> 3:
   o>     15\n
   o> bufferedread(15) -> 15: publishing	True
-  response: publishing	True
+  response: b'publishing	True'
 
 Setting public phase via pushkey
 
@@ -1999,7 +1999,7 @@ 
   o>     2\n
   o> bufferedread(2) -> 2:
   o>     1\n
-  response: 1\n
+  response: b'1\n'
   
   testing ssh2
   creating ssh peer from handshake results
@@ -2037,7 +2037,7 @@ 
   o>     2\n
   o> bufferedread(2) -> 2:
   o>     1\n
-  response: 1\n
+  response: b'1\n'
 
   $ hg phase .
   4: public
diff --git a/tests/test-http-protocol.t b/tests/test-http-protocol.t
--- a/tests/test-http-protocol.t
+++ b/tests/test-http-protocol.t
@@ -209,7 +209,7 @@ 
   s>     bookmarks	\n
   s>     namespaces	\n
   s>     phases	
-  response: bookmarks	\nnamespaces	\nphases	
+  response: b'bookmarks	\nnamespaces	\nphases	'
 
 Same thing, but with "httprequest" command
 
diff --git a/mercurial/utils/stringutil.py b/mercurial/utils/stringutil.py
--- a/mercurial/utils/stringutil.py
+++ b/mercurial/utils/stringutil.py
@@ -36,6 +36,20 @@ 
 
     return _DATA_ESCAPE_RE.sub(lambda m: _DATA_ESCAPE_MAP[m.group(0)], s)
 
+def pprint(o):
+    """Pretty print an object."""
+    if isinstance(o, (bytes, bytearray)):
+        return "b'%s'" % escapedata(o)
+    elif isinstance(o, list):
+        return '[%s]' % (b', '.join(pprint(a) for a in o))
+    elif isinstance(o, dict):
+        return '{%s}' % (b', '.join(
+            '%s: %s' % (pprint(k), pprint(v)) for k, v in sorted(o.items())))
+    elif isinstance(o, bool):
+        return b'True' if o else b'False'
+    else:
+        raise error.ProgrammingError('do not know how to format %r' % o)
+
 def binary(s):
     """return true if a string is binary data"""
     return bool(s and '\0' in s)
diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py
--- a/mercurial/debugcommands.py
+++ b/mercurial/debugcommands.py
@@ -2961,7 +2961,7 @@ 
                               stringutil.escapedata(output))
             else:
                 res = peer._call(command, **pycompat.strkwargs(args))
-                ui.status(_('response: %s\n') % stringutil.escapedata(res))
+                ui.status(_('response: %s\n') % stringutil.pprint(res))
 
         elif action == 'batchbegin':
             if batchedcommands is not None: