mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-03-16 18:38:32 +03:00
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
78 lines
2.4 KiB
Python
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
|