pretty printing protobufs

This commit is contained in:
matejcik 2018-02-28 14:04:34 +01:00 committed by matejcik
parent 95603b85dd
commit 07ceb9aacc
2 changed files with 35 additions and 3 deletions

View File

@ -28,7 +28,7 @@ import json
import os
import sys
from trezorlib.client import TrezorClient, TrezorClientVerbose, CallException
from trezorlib.client import TrezorClient, TrezorClientVerbose, CallException, format_protobuf
from trezorlib.device import TrezorDevice
from trezorlib import messages as proto
from trezorlib import protobuf
@ -80,7 +80,7 @@ def cli(ctx, path, verbose, is_json):
@cli.resultcallback()
def print_result(res, path, verbose, is_json):
if is_json:
if issubclass(res.__class__, protobuf.MessageType):
if isinstance(res, protobuf.MessageType):
click.echo(json.dumps({res.__class__.__name__: res.__dict__}))
else:
click.echo(json.dumps(res, sort_keys=True, indent=4))
@ -95,6 +95,8 @@ def print_result(res, path, verbose, is_json):
click.echo('%s.%s: %s' % (k, kk, vv))
else:
click.echo('%s: %s' % (k, v))
elif isinstance(res, protobuf.MessageType):
click.echo(format_protobuf(res))
else:
click.echo(res)

View File

@ -36,6 +36,7 @@ from . import tools
from . import mapping
from .coins import coins_slip44
from .debuglink import DebugLink
from .protobuf import MessageType
# Python2 vs Python3
try:
@ -86,13 +87,42 @@ def get_buttonrequest_value(code):
return [k for k in dir(proto.ButtonRequestType) if getattr(proto.ButtonRequestType, k) == code][0]
def format_protobuf(pb, indent=0, sep=' '*4):
def pformat_value(value, indent):
level = sep * indent
leadin = sep * (indent + 1)
if isinstance(value, MessageType):
return format_protobuf(value, indent, sep)
if isinstance(value, list):
lines = []
lines.append('[')
lines += [leadin + pformat_value(x, indent + 1) + ',' for x in value]
lines.append(level + ']')
return '\n'.join(lines)
if isinstance(value, dict):
lines = []
lines.append('{')
for key, val in sorted(value.items()):
if val is None or val == []:
continue
lines.append(leadin + key + ': ' + pformat_value(val, indent + 1) + ',')
lines.append(level + '}')
return '\n'.join(lines)
if isinstance(value, bytes) or isinstance(value, bytearray):
return '{type}(0x{hex})'.format(type=type(value).__name__, hex=value.hex())
return repr(value)
return pb.__class__.__name__ + ' ' + pformat_value(pb.__dict__, indent)
def pprint(msg):
msg_class = msg.__class__.__name__
msg_size = msg.ByteSize()
if isinstance(msg, proto.FirmwareUpload) or isinstance(msg, proto.SelfTest):
return "<%s> (%d bytes):\n" % (msg_class, msg_size)
else:
return "<%s> (%d bytes):\n%s" % (msg_class, msg_size, msg)
return "<%s> (%d bytes):\n%s" % (msg_class, msg_size, format_protobuf(msg))
def log(msg):