''' Interactive Python interpreter ''' from typing import MutableMapping, Any import asyncio import ptpython.repl import re import zasd.config as config class DictObject: def __init__(self, dictionary: MutableMapping[str, Any], name): DictObject._dictionary = dictionary DictObject._name = name def __getattribute__(self, name): if not name in DictObject._dictionary: raise AttributeError("name '{}' is not defined".format(name)) return DictObject._dictionary[name] def __setattr__(self, name, value): DictObject._dictionary[name] = value def __delattr__(self, name): if not name in DictObject._dictionary: raise AttributeError("name {} is not defined".format(name)) del self._dictionary[name] def __dir__(self): return DictObject._dictionary.keys() def __repr__(self): return DictObject.make_repr(DictObject._dictionary, DictObject._name) @staticmethod def make_repr(obj, name, level=0, path=[]): if not isinstance(obj, dict): repstr = repr(obj) if re.search(r'^<.+>$', repstr): repstr = repstr[1:-1] return '{}.{} = {}'.format(name, '.'.join(path), repstr) else: keys = sorted(obj.keys()) strs = list() for key in keys: value = DictObject.make_repr( obj[key], name, level + 1, path = path + [key]) strs.append(value) return '\n'.join(strs) @asyncio.coroutine def repl(): _globals = dict( config = DictObject(config.reference(), 'config') ) _locals = dict() try: yield from ptpython.repl.embed( globals=_globals, locals=_locals, return_asyncio_coroutine=True, patch_stdout=True, vi_mode=True) except EOFError: asyncio.get_event_loop().stop()