|
|
|
@ -1,38 +1,43 @@ |
|
|
|
|
''' Interactive Python interpreter ''' |
|
|
|
|
|
|
|
|
|
from typing import MutableMapping, Any, Callable, ContextManager, Dict, Optional |
|
|
|
|
from typing import MutableMapping, Set, Any |
|
|
|
|
|
|
|
|
|
import builtins |
|
|
|
|
import asyncio |
|
|
|
|
import sys |
|
|
|
|
import re |
|
|
|
|
|
|
|
|
|
from ptpython.repl import PythonRepl |
|
|
|
|
from prompt_toolkit.patch_stdout import patch_stdout as patch_stdout_context |
|
|
|
|
import ptpython.repl |
|
|
|
|
|
|
|
|
|
import zasd.entrypoint |
|
|
|
|
import zasd.config as config |
|
|
|
|
from zasd.filesystem import FilesystemRegistry |
|
|
|
|
|
|
|
|
|
@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 |
|
|
|
|
''' Launch an asynchronous ptpython REPL ''' |
|
|
|
|
|
|
|
|
|
glo: MutableMapping = dict( |
|
|
|
|
sys = sys, |
|
|
|
|
config = DictObject(config.reference(), 'config'), |
|
|
|
|
registry = FilesystemRegistry) |
|
|
|
|
loc: MutableMapping = dict() |
|
|
|
|
|
|
|
|
|
def configure(ptrepl): |
|
|
|
|
ptrepl.confirm_exit = False |
|
|
|
|
ptrepl.highlight_matching_parenthesis = True |
|
|
|
|
ptrepl.insert_blank_line_after_output = False |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
with patch_stdout_context(): |
|
|
|
|
await _repl.run_async() |
|
|
|
|
await ptpython.repl.embed( |
|
|
|
|
globals=glo, |
|
|
|
|
locals=loc, |
|
|
|
|
configure=configure, |
|
|
|
|
return_asyncio_coroutine=True, |
|
|
|
|
patch_stdout=True) |
|
|
|
|
except EOFError: |
|
|
|
|
quit() |
|
|
|
|
zasd.entrypoint.stop() |
|
|
|
|
|
|
|
|
|
class DictObject(): |
|
|
|
|
''' Class for wrapping dictionaries in objects ''' |
|
|
|
|
|
|
|
|
|
class DictObject: |
|
|
|
|
def __init__(self, dictionary: MutableMapping[str, Any], name): |
|
|
|
|
DictObject._dictionary = dictionary |
|
|
|
|
DictObject._name = name |
|
|
|
@ -50,24 +55,28 @@ class DictObject: |
|
|
|
|
raise AttributeError("name {} is not defined".format(name)) |
|
|
|
|
del self._dictionary[name] |
|
|
|
|
|
|
|
|
|
def __dir__(self): |
|
|
|
|
def __dir__(self) -> Set[str]: |
|
|
|
|
return DictObject._dictionary.keys() |
|
|
|
|
|
|
|
|
|
def __repr__(self): |
|
|
|
|
return DictObject.make_repr(DictObject._dictionary, DictObject._name) |
|
|
|
|
def __repr__(self) -> str: |
|
|
|
|
return DictObject.serialise(DictObject._dictionary, DictObject._name) |
|
|
|
|
|
|
|
|
|
@staticmethod |
|
|
|
|
def make_repr(obj, name, level=0, path=[]): |
|
|
|
|
def serialise(obj, name, level=0, path=None) -> str: |
|
|
|
|
''' Turn an object into a string recursively. ''' |
|
|
|
|
|
|
|
|
|
if not isinstance(obj, dict): |
|
|
|
|
# Output variables in 'object.name = value' format |
|
|
|
|
repstr = repr(obj) |
|
|
|
|
if re.search(r'^<.+>$', repstr): |
|
|
|
|
repstr = repstr[1:-1] |
|
|
|
|
return '{}.{} = {}'.format(name, '.'.join(path), repstr) |
|
|
|
|
return '{}.{} = {}'.format(name, '.'.join(path or []), repstr) |
|
|
|
|
else: |
|
|
|
|
# Separate dictionary entries with newlines |
|
|
|
|
keys = sorted(obj.keys()) |
|
|
|
|
strs = list() |
|
|
|
|
for key in keys: |
|
|
|
|
value = DictObject.make_repr( |
|
|
|
|
obj[key], name, level + 1, path = path + [key]) |
|
|
|
|
value = DictObject.serialise( |
|
|
|
|
obj[key], name, level + 1, path = (path or []) + [key]) |
|
|
|
|
strs.append(value) |
|
|
|
|
return '\n'.join(strs) |