''' Interactive Python interpreter ''' from typing import MutableMapping, Any, Callable, ContextManager, Dict, Optional import builtins import asyncio import re from ptpython.repl import PythonRepl from prompt_toolkit.patch_stdout import patch_stdout as patch_stdout_context import zasd.config as config @asyncio.coroutine async def repl(): _globals = dict( config = DictObject(config.reference(), 'config')) _locals = dict(a = 'b') # Create REPL. _repl = PythonRepl( get_globals=lambda: _globals, get_locals=lambda: _locals, vi_mode=True) _repl.confirm_exit = False _repl.highlight_matching_parenthesis = True _repl.insert_blank_line_after_output = False try: with patch_stdout_context(): await _repl.run_async() except EOFError: quit() 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)