Fixed execution of incomplete multiline code fragments.

This commit is contained in:
Dmitry Trofimov
2013-11-18 20:42:39 +01:00
parent 17c0f6cbd0
commit c8938aa135
2 changed files with 47 additions and 32 deletions
+23 -23
View File
@@ -136,6 +136,11 @@ class CodeFragment:
def __init__(self, text, is_single_line=True):
self.text = text
self.is_single_line = is_single_line
def append(self, code_fragment):
self.text = self.text + "\n" + code_fragment.text
if not code_fragment.is_single_line:
self.is_single_line = False
#=======================================================================================================================
# BaseInterpreterInterface
@@ -145,7 +150,7 @@ class BaseInterpreterInterface:
self.mainThread = mainThread
self.interruptable = False
self.exec_queue = _queue.Queue(0)
self.buffer = []
self.buffer = None
def needMoreForCode(self, source):
if hasattr(self.interpreter, 'is_complete'):
@@ -162,16 +167,15 @@ class BaseInterpreterInterface:
# Case 3
return False
def needMore(self, buffer, line):
if not buffer:
buffer = []
buffer.append(line)
source = "\n".join(buffer)
def needMore(self, code_fragment):
if self.buffer is None:
self.buffer = code_fragment
else:
self.buffer.append(code_fragment)
return self.needMoreForCode(source)
return self.needMoreForCode(code_fragment.text)
def addExec(self, codeFragment):
def addExec(self, code_fragment):
original_in = sys.stdin
try:
help = None
@@ -210,7 +214,7 @@ class BaseInterpreterInterface:
try:
self.startExec()
more = self.doAddExec(codeFragment)
more = self.doAddExec(code_fragment)
self.finishExec()
finally:
if help is not None:
@@ -231,9 +235,7 @@ class BaseInterpreterInterface:
traceback.print_exc()
#it's always false at this point
need_input = False
return more, need_input
return more
def doAddExec(self, codeFragment):
@@ -314,24 +316,22 @@ class BaseInterpreterInterface:
return ''
def execLine(self, line):
def doExecCode(self, code, is_single_line):
try:
more = self.needMore(self.buffer, line)
self.exec_queue.put(CodeFragment(line, True))
code_fragment = CodeFragment(code, is_single_line)
more = self.needMore(code_fragment)
self.exec_queue.put(code_fragment)
return more
except:
traceback.print_exc()
return False
def execLine(self, line):
return self.doExecCode(line, True)
def execMultipleLines(self, lines):
try:
more = self.needMoreForCode(lines)
self.exec_queue.put(CodeFragment(lines, False))
return more
except:
traceback.print_exc()
return False
return self.doExecCode(lines, False)
def interrupt(self):
+24 -9
View File
@@ -74,7 +74,7 @@ except ImportError:
class Command:
def __init__(self, interpreter, code_fragment):
def __init__(self, interpreter, code_fragment, buffer):
"""
:type code_fragment: CodeFragment
:type interpreter: InteractiveConsole
@@ -82,12 +82,25 @@ class Command:
self.interpreter = interpreter
self.code_fragment = code_fragment
self.more = None
self.buffer = buffer
@staticmethod
def symbol_for_fragment(code_fragment):
if code_fragment.is_single_line:
symbol = 'single'
else:
symbol = 'exec'
return symbol
def run(self):
if self.code_fragment.is_single_line:
self.more = self.interpreter.push(self.code_fragment.text)
if self.buffer is None:
text = self.code_fragment.text
symbol = self.symbol_for_fragment(self.code_fragment)
else:
self.more = self.interpreter.runsource(self.code_fragment.text, '<input>', 'exec')
text = self.buffer.text
symbol = self.symbol_for_fragment(self.buffer)
self.more = self.interpreter.runsource(text, '<input>', symbol)
try:
try:
@@ -119,7 +132,7 @@ class InterpreterInterface(BaseInterpreterInterface):
def doAddExec(self, codeFragment):
command = Command(self.interpreter, codeFragment)
command = Command(self.interpreter, codeFragment, self.buffer)
command.run()
return command.more
@@ -155,10 +168,12 @@ def process_exec_queue(interpreter):
except _queue.Empty:
continue
if not interpreter.addExec(codeFragment): #TODO: think about locks here
interpreter.buffer = []
more = interpreter.addExec(codeFragment)
if not more:
interpreter.buffer = None
except KeyboardInterrupt:
interpreter.buffer = []
interpreter.buffer = None
continue
except SystemExit:
raise
@@ -311,7 +326,7 @@ def exec_code(code, globals, locals):
interpreterInterface.interpreter.update(globals, locals)
res = interpreterInterface.needMore(None, code.text)
res = interpreterInterface.needMore(code)
if res:
return True