from collections import OrderedDict def _log(od, methname, args, kwargs, *, err=None, _logfile=open('/tmp/odict.log', 'w')): import pprint import threading import traceback if methname == '__init__': _logfile.write('=======================================\n\n') _logfile.write('----------------------\n') _logfile.write('{}: {} {}\n'.format(id(od), methname, 'failed' if err else 'called')) _logfile.write(' thread {}\n'.format(threading.get_ident())) _logfile.write(' OrderedDict.{}({}\n'.format(methname, '' if args or kwargs else ')')) if args: _logfile.write(' {},\n'.format(', '.join(repr(v) for v in args))) if kwargs: _logfile.write(' {}\n'.format(', '.join('{}={!r}'.format(k, v) for k, v in kwargs.items()))) if args or kwargs: _logfile.write(' )\n') if err is None: _logfile.write('----------------------\n') pprint.pprint(od, stream=_logfile) _logfile.write('V----------------------\n') if err is None: traceback.print_stack(file=_logfile) else: traceback.print_exc(file=_logfile) _logfile.write('^----------------------\n\n') class _LoggingOrderedDict(OrderedDict): def __init__(self, *args, **kwargs): name = '__init__' _log(self, name, args, kwargs) try: OrderedDict.__init__(self, *args, **kwargs) except Exception as e: _log(self, name, args, kwargs, err=e) raise def __getattribute__(self, name): method = OrderedDict.__getattribute__(self, name) if name not in ('clear', 'move_to_end', 'pop', 'popitem', 'setdefault'): return method def wrapper(*args, **kwargs): _log(self, name, args, kwargs) try: return method(*args, **kwargs) except Exception as e: _log(self, name, args, kwargs, err=e) raise return wrapper def __setitem__(self, *args, **kwargs): name = '__setitem__' _log(self, name, args, kwargs) try: return OrderedDict.__setitem__(self, *args, **kwargs) except Exception as e: _log(self, name, args, kwargs, err=e) raise def __delitem__(self, *args, **kwargs): name = '__delitem__' _log(self, name, args, kwargs) try: return OrderedDict.__delitem__(self, *args, **kwargs) except Exception as e: _log(self, name, args, kwargs, err=e) raise