wireproto: implement custom __repr__ for frame
This version won't print the full payload (which could be large).
It also prints human friendly values for types and flags.
Differential Revision: https://phab.mercurial-scm.org/D2985
--- a/mercurial/wireprotoframing.py Wed Mar 28 12:44:35 2018 -0700
+++ b/mercurial/wireprotoframing.py Wed Mar 28 13:01:28 2018 -0700
@@ -106,6 +106,15 @@
ARGUMENT_RECORD_HEADER = struct.Struct(r'<HH')
+def humanflags(mapping, value):
+ """Convert a numeric flags value to a human value, using a mapping table."""
+ flags = []
+ for val, name in sorted({v: k for k, v in mapping.iteritems()}.iteritems()):
+ if value & val:
+ flags.append(name)
+
+ return b'|'.join(flags)
+
@attr.s(slots=True)
class frameheader(object):
"""Represents the data in a frame header."""
@@ -117,7 +126,7 @@
typeid = attr.ib()
flags = attr.ib()
-@attr.s(slots=True)
+@attr.s(slots=True, repr=False)
class frame(object):
"""Represents a parsed frame."""
@@ -128,6 +137,19 @@
flags = attr.ib()
payload = attr.ib()
+ def __repr__(self):
+ typename = '<unknown>'
+ for name, value in FRAME_TYPES.iteritems():
+ if value == self.typeid:
+ typename = name
+ break
+
+ return ('frame(size=%d; request=%d; stream=%d; streamflags=%s; '
+ 'type=%s; flags=%s)' % (
+ len(self.payload), self.requestid, self.streamid,
+ humanflags(STREAM_FLAGS, self.streamflags), typename,
+ humanflags(FRAME_TYPE_FLAGS[self.typeid], self.flags)))
+
def makeframe(requestid, streamid, streamflags, typeid, flags, payload):
"""Assemble a frame into a byte array."""
# TODO assert size of payload.