|
|
|
#!/usr/bin/env python3
|
|
|
|
# (c) 2015 Taeyeon Mori
|
|
|
|
# execute a python file as if the lines were entered into an interactive prompt
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import io
|
|
|
|
import code
|
|
|
|
|
|
|
|
try:
|
|
|
|
import pygments, pygments.lexers, pygments.formatters
|
|
|
|
except:
|
|
|
|
hl = None
|
|
|
|
else:
|
|
|
|
pyg_lex = pygments.lexers.PythonLexer()
|
|
|
|
pyg_fmt = pygments.formatters.Terminal256Formatter()
|
|
|
|
def hl(code):
|
|
|
|
return pygments.highlight(code, pyg_lex, pyg_fmt)
|
|
|
|
|
|
|
|
|
|
|
|
class IOIPythonPrefix:
|
|
|
|
def __init__(self, init=1):
|
|
|
|
self.count = init
|
|
|
|
self.ctx = ""
|
|
|
|
self.__enter__()
|
|
|
|
|
|
|
|
def inc(self, by=1):
|
|
|
|
self.count += by
|
|
|
|
|
|
|
|
def __call__(self, ctx):
|
|
|
|
self.ctx = ctx
|
|
|
|
return self
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
self.prefix = "%s\033[0m[\033[31m%2d\033[0m] " % (self.ctx, self.count)
|
|
|
|
|
|
|
|
def __exit__(self, *a):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class IOPrefixWrapper:
|
|
|
|
def __init__(self, parent, pfx):
|
|
|
|
self.parent = parent
|
|
|
|
self.prefix = pfx
|
|
|
|
self.nl = True
|
|
|
|
|
|
|
|
def write(self, text):
|
|
|
|
lines = text.splitlines(True)
|
|
|
|
if lines:
|
|
|
|
if self.nl:
|
|
|
|
self.parent.write(self.prefix.prefix)
|
|
|
|
self.parent.write(lines[0])
|
|
|
|
for line in lines[1:]:
|
|
|
|
self.parent.write(self.prefix.prefix)
|
|
|
|
self.parent.write(line)
|
|
|
|
self.nl = lines[-1].endswith("\n")
|
|
|
|
|
|
|
|
def flush(self):
|
|
|
|
return self.parent.flush()
|
|
|
|
|
|
|
|
|
|
|
|
xcount = IOIPythonPrefix()
|
|
|
|
sys.stdout = IOPrefixWrapper(sys.stdout, xcount)
|
|
|
|
interp = code.InteractiveInterpreter()
|
|
|
|
|
|
|
|
|
|
|
|
def print_in_x(cmd_lines):
|
|
|
|
with xcount("\033[34mIn "):
|
|
|
|
print(">>>", cmd_lines[0], end="")
|
|
|
|
for line in cmd_lines[1:]:
|
|
|
|
print("...", line, end="")
|
|
|
|
|
|
|
|
def print_in_hl(cmd_lines):
|
|
|
|
print_in_x(hl("".join(cmd_lines)).splitlines(True))
|
|
|
|
|
|
|
|
if hl:
|
|
|
|
print_in = print_in_hl
|
|
|
|
else:
|
|
|
|
print_in = print_in_x
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def compile_lines(lines):
|
|
|
|
return code.compile_command("".join(lines))
|
|
|
|
|
|
|
|
def isindent(c):
|
|
|
|
return c in " \t"
|
|
|
|
|
|
|
|
|
|
|
|
with open(sys.argv[1]) as f:
|
|
|
|
ln = 0
|
|
|
|
peekbuf = []
|
|
|
|
|
|
|
|
def readline():
|
|
|
|
global ln, peekbuf
|
|
|
|
ln += 1
|
|
|
|
if peekbuf:
|
|
|
|
l = peekbuf.pop(0)
|
|
|
|
else:
|
|
|
|
l = f.readline()
|
|
|
|
if not l:
|
|
|
|
raise SystemExit()
|
|
|
|
return l
|
|
|
|
|
|
|
|
def peekline(n=0):
|
|
|
|
global peekbuf
|
|
|
|
while len(peekbuf) <= n:
|
|
|
|
peekbuf.append(f.readline())
|
|
|
|
return peekbuf[n]
|
|
|
|
|
|
|
|
def peekindent():
|
|
|
|
i = 0
|
|
|
|
while not peekline(i).strip():
|
|
|
|
i += 1
|
|
|
|
return isindent(peekline(i)[0])
|
|
|
|
|
|
|
|
while True:
|
|
|
|
cmd_lines = [readline()]
|
|
|
|
|
|
|
|
c = compile_lines(cmd_lines)
|
|
|
|
if not c:
|
|
|
|
while not c:
|
|
|
|
cmd_lines.append(readline())
|
|
|
|
while peekindent():
|
|
|
|
cmd_lines.append(readline())
|
|
|
|
c = compile_lines(cmd_lines)
|
|
|
|
|
|
|
|
print_in(cmd_lines)
|
|
|
|
|
|
|
|
with xcount("\033[33mOut"):
|
|
|
|
interp.runcode(c)
|
|
|
|
#sys.stdout.parent.write("\n")
|
|
|
|
xcount.inc()
|
|
|
|
|