comparison mercurial/wireprotoframing.py @ 37298:5ef2da00e935

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
author Gregory Szorc <gregory.szorc@gmail.com>
date Wed, 28 Mar 2018 13:01:28 -0700
parents 3d0e2cd86e05
children e9aadee698cf
comparison
equal deleted inserted replaced
37297:97eedbd5a56c 37298:5ef2da00e935
104 FRAME_TYPE_STREAM_SETTINGS: {}, 104 FRAME_TYPE_STREAM_SETTINGS: {},
105 } 105 }
106 106
107 ARGUMENT_RECORD_HEADER = struct.Struct(r'<HH') 107 ARGUMENT_RECORD_HEADER = struct.Struct(r'<HH')
108 108
109 def humanflags(mapping, value):
110 """Convert a numeric flags value to a human value, using a mapping table."""
111 flags = []
112 for val, name in sorted({v: k for k, v in mapping.iteritems()}.iteritems()):
113 if value & val:
114 flags.append(name)
115
116 return b'|'.join(flags)
117
109 @attr.s(slots=True) 118 @attr.s(slots=True)
110 class frameheader(object): 119 class frameheader(object):
111 """Represents the data in a frame header.""" 120 """Represents the data in a frame header."""
112 121
113 length = attr.ib() 122 length = attr.ib()
115 streamid = attr.ib() 124 streamid = attr.ib()
116 streamflags = attr.ib() 125 streamflags = attr.ib()
117 typeid = attr.ib() 126 typeid = attr.ib()
118 flags = attr.ib() 127 flags = attr.ib()
119 128
120 @attr.s(slots=True) 129 @attr.s(slots=True, repr=False)
121 class frame(object): 130 class frame(object):
122 """Represents a parsed frame.""" 131 """Represents a parsed frame."""
123 132
124 requestid = attr.ib() 133 requestid = attr.ib()
125 streamid = attr.ib() 134 streamid = attr.ib()
126 streamflags = attr.ib() 135 streamflags = attr.ib()
127 typeid = attr.ib() 136 typeid = attr.ib()
128 flags = attr.ib() 137 flags = attr.ib()
129 payload = attr.ib() 138 payload = attr.ib()
139
140 def __repr__(self):
141 typename = '<unknown>'
142 for name, value in FRAME_TYPES.iteritems():
143 if value == self.typeid:
144 typename = name
145 break
146
147 return ('frame(size=%d; request=%d; stream=%d; streamflags=%s; '
148 'type=%s; flags=%s)' % (
149 len(self.payload), self.requestid, self.streamid,
150 humanflags(STREAM_FLAGS, self.streamflags), typename,
151 humanflags(FRAME_TYPE_FLAGS[self.typeid], self.flags)))
130 152
131 def makeframe(requestid, streamid, streamflags, typeid, flags, payload): 153 def makeframe(requestid, streamid, streamflags, typeid, flags, payload):
132 """Assemble a frame into a byte array.""" 154 """Assemble a frame into a byte array."""
133 # TODO assert size of payload. 155 # TODO assert size of payload.
134 frame = bytearray(FRAME_HEADER_SIZE + len(payload)) 156 frame = bytearray(FRAME_HEADER_SIZE + len(payload))