Files
pysim-local/pySim/pprint.py
Harald Welte 3b4a673de4 add contrib/saip-tool.py
This is a tool to work with eSIM profiles in SAIP format.  It allows
to dump the contents, run constraint checkers as well as splitting
of the PE-Sequence into the individual PEs.

Change-Id: I396bcd594e0628dfc26bd90233317a77e2f91b20
2024-06-10 08:59:39 +02:00

78 lines
2.4 KiB
Python

import pprint
from pprint import PrettyPrinter
from functools import singledispatch, wraps
from typing import get_type_hints
from pySim.utils import b2h
def common_container_checks(f):
type_ = get_type_hints(f)['object']
base_impl = type_.__repr__
empty_repr = repr(type_()) # {}, [], ()
too_deep_repr = f'{empty_repr[0]}...{empty_repr[-1]}' # {...}, [...], (...)
@wraps(f)
def wrapper(object, context, maxlevels, level):
if type(object).__repr__ is not base_impl: # subclassed repr
return repr(object)
if not object: # empty, short-circuit
return empty_repr
if maxlevels and level >= maxlevels: # exceeding the max depth
return too_deep_repr
oid = id(object)
if oid in context: # self-reference
return pprint._recursion(object)
context[oid] = 1
result = f(object, context, maxlevels, level)
del context[oid]
return result
return wrapper
@singledispatch
def saferepr(object, context, maxlevels, level):
return repr(object)
@saferepr.register
def _handle_bytes(object: bytes, *args):
if len(object) <= 40:
return '"%s"' % b2h(object)
else:
return '"%s...%s"' % (b2h(object[:20]), b2h(object[-20:]))
@saferepr.register
@common_container_checks
def _handle_dict(object: dict, context, maxlevels, level):
level += 1
contents = [
f'{saferepr(k, context, maxlevels, level)}: '
f'{saferepr(v, context, maxlevels, level)}'
for k, v in sorted(object.items(), key=pprint._safe_tuple)
]
return f'{{{", ".join(contents)}}}'
@saferepr.register
@common_container_checks
def _handle_list(object: list, context, maxlevels, level):
level += 1
contents = [
f'{saferepr(v, context, maxlevels, level)}'
for v in object
]
return f'[{", ".join(contents)}]'
@saferepr.register
@common_container_checks
def _handle_tuple(object: tuple, context, maxlevels, level):
level += 1
if len(object) == 1:
return f'({saferepr(object[0], context, maxlevels, level)},)'
contents = [
f'{saferepr(v, context, maxlevels, level)}'
for v in object
]
return f'({", ".join(contents)})'
class HexBytesPrettyPrinter(PrettyPrinter):
def format(self, *args):
# it doesn't matter what the boolean values are here
return saferepr(*args), True, False