mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-01-10 23:40:58 +00:00
protobuf: improve prettyprint formatting
This commit is contained in:
parent
eed91db880
commit
1e4c1c093e
@ -41,7 +41,7 @@ required:
|
||||
|
||||
import binascii
|
||||
from io import BytesIO
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
_UVARINT_BUFFER = bytearray(1)
|
||||
|
||||
@ -348,37 +348,63 @@ def dump_message(writer, msg):
|
||||
raise TypeError
|
||||
|
||||
|
||||
def format_message(pb: MessageType, indent: int=0, sep: str= ' ' * 4) -> str:
|
||||
def format_message(pb: MessageType,
|
||||
indent: int = 0,
|
||||
sep: str = ' ' * 4,
|
||||
truncate_after: Optional[int] = 256,
|
||||
truncate_to: Optional[int] = 64,
|
||||
collapse_cointypes: bool = False) -> str:
|
||||
|
||||
def mostly_printable(bytes):
|
||||
if not bytes:
|
||||
return True
|
||||
printable = sum(1 for byte in bytes if 0x20 <= byte <= 0x7e)
|
||||
return printable / len(bytes) > 0.8
|
||||
|
||||
def pformat_value(value: Any, indent: int) -> str:
|
||||
level = sep * indent
|
||||
leadin = sep * (indent + 1)
|
||||
if isinstance(value, MessageType):
|
||||
return format_message(value, indent, sep)
|
||||
if isinstance(value, list):
|
||||
lines = []
|
||||
lines.append('[')
|
||||
lines += [leadin + pformat_value(x, indent + 1) + ',' for x in value]
|
||||
lines.append(level + ']')
|
||||
# short list of simple values
|
||||
if not value or not isinstance(value[0], MessageType):
|
||||
return repr(value)
|
||||
|
||||
# long list, one line per entry
|
||||
lines = ['[', level + ']']
|
||||
lines[1:1] = [leadin + pformat_value(x, indent + 1) + ',' for x in value]
|
||||
return '\n'.join(lines)
|
||||
if isinstance(value, dict):
|
||||
lines = []
|
||||
lines.append('{')
|
||||
lines = ['{']
|
||||
for key, val in sorted(value.items()):
|
||||
if val is None or val == []:
|
||||
continue
|
||||
if key == 'address_n' and isinstance(val, list):
|
||||
lines.append(leadin + key + ': ' + repr(val) + ',')
|
||||
else:
|
||||
lines.append(leadin + key + ': ' + pformat_value(val, indent + 1) + ',')
|
||||
lines.append(leadin + key + ': ' + pformat_value(val, indent + 1) + ',')
|
||||
lines.append(level + '}')
|
||||
return '\n'.join(lines)
|
||||
if isinstance(value, bytearray):
|
||||
return 'bytearray(0x{})'.format(binascii.hexlify(value).decode('ascii'))
|
||||
if isinstance(value, (bytes, bytearray)):
|
||||
length = len(value)
|
||||
suffix = ''
|
||||
if truncate_after and length > truncate_after:
|
||||
suffix = '...'
|
||||
value = value[:truncate_to or 0]
|
||||
if mostly_printable(value):
|
||||
output = repr(value)
|
||||
else:
|
||||
output = '0x' + binascii.hexlify(value).decode('ascii')
|
||||
return '{} bytes {}{}'.format(length, output, suffix)
|
||||
|
||||
return repr(value)
|
||||
|
||||
from .messages import Features
|
||||
pb_dict = pb.__dict__.copy()
|
||||
if collapse_cointypes and isinstance(pb, Features):
|
||||
del pb_dict['coins']
|
||||
pb_dict['coins (shortened)'] = ' '.join(coin.coin_shortcut for coin in pb.coins)
|
||||
|
||||
return '{name} ({size} bytes) {content}'.format(
|
||||
name=pb.__class__.__name__,
|
||||
size=pb.ByteSize(),
|
||||
content=pformat_value(pb.__dict__, indent)
|
||||
content=pformat_value(pb_dict, indent)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user