mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-26 21:22:27 -06:00
170 lines
6.3 KiB
Python
170 lines
6.3 KiB
Python
"""Interpreter executes Python commands."""
|
|
|
|
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com> / "
|
|
__author__ += "David N. Mashburn <david.n.mashburn@gmail.com>"
|
|
|
|
|
|
import os
|
|
import sys
|
|
from code import InteractiveInterpreter, compile_command
|
|
from . import dispatcher
|
|
from . import introspect
|
|
import wx
|
|
import wx.lib.six
|
|
|
|
class Interpreter(InteractiveInterpreter):
|
|
"""Interpreter based on code.InteractiveInterpreter."""
|
|
|
|
|
|
def __init__(self, locals=None, rawin=None,
|
|
stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr,
|
|
showInterpIntro=True):
|
|
"""Create an interactive interpreter object."""
|
|
InteractiveInterpreter.__init__(self, locals=locals)
|
|
self.stdin = stdin
|
|
self.stdout = stdout
|
|
self.stderr = stderr
|
|
if rawin:
|
|
from wx.lib.six.moves import builtins
|
|
builtins.raw_input = rawin
|
|
del builtins
|
|
if showInterpIntro:
|
|
copyright = 'Type "help", "copyright", "credits" or "license"'
|
|
copyright += ' for more information.'
|
|
self.introText = 'Python %s on %s%s%s' % \
|
|
(sys.version, sys.platform, os.linesep, copyright)
|
|
try:
|
|
sys.ps1
|
|
except AttributeError:
|
|
sys.ps1 = '>>> '
|
|
try:
|
|
sys.ps2
|
|
except AttributeError:
|
|
sys.ps2 = '... '
|
|
self.more = 0
|
|
# List of lists to support recursive push().
|
|
self.commandBuffer = []
|
|
self.startupScript = None
|
|
|
|
def push(self, command, astMod=None):
|
|
"""Send command to the interpreter to be executed.
|
|
|
|
Because this may be called recursively, we append a new list
|
|
onto the commandBuffer list and then append commands into
|
|
that. If the passed in command is part of a multi-line
|
|
command we keep appending the pieces to the last list in
|
|
commandBuffer until we have a complete command. If not, we
|
|
delete that last list."""
|
|
|
|
# In case the command is unicode try encoding it
|
|
if not wx.lib.six.PY3:
|
|
if type(command) == unicode:
|
|
try:
|
|
command = command.encode('utf-8')
|
|
except UnicodeEncodeError:
|
|
pass # otherwise leave it alone
|
|
|
|
if not self.more:
|
|
try: del self.commandBuffer[-1]
|
|
except IndexError: pass
|
|
if not self.more: self.commandBuffer.append([])
|
|
self.commandBuffer[-1].append(command)
|
|
source = '\n'.join(self.commandBuffer[-1])
|
|
|
|
# If an ast code module is passed, pass it to runModule instead
|
|
more=False
|
|
if astMod != None:
|
|
self.runModule(astMod)
|
|
self.more=False
|
|
else:
|
|
more = self.more = self.runsource(source)
|
|
dispatcher.send(signal='Interpreter.push', sender=self,
|
|
command=command, more=more, source=source)
|
|
return more
|
|
|
|
def runsource(self, source):
|
|
"""Compile and run source code in the interpreter."""
|
|
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
|
|
sys.stdin, sys.stdout, sys.stderr = \
|
|
self.stdin, self.stdout, self.stderr
|
|
more = InteractiveInterpreter.runsource(self, source)
|
|
# this was a cute idea, but didn't work...
|
|
#more = self.runcode(compile(source,'',
|
|
# ('exec' if self.useExecMode else 'single')))
|
|
|
|
|
|
# If sys.std* is still what we set it to, then restore it.
|
|
# But, if the executed source changed sys.std*, assume it was
|
|
# meant to be changed and leave it. Power to the people.
|
|
if sys.stdin == self.stdin:
|
|
sys.stdin = stdin
|
|
else:
|
|
self.stdin = sys.stdin
|
|
if sys.stdout == self.stdout:
|
|
sys.stdout = stdout
|
|
else:
|
|
self.stdout = sys.stdout
|
|
if sys.stderr == self.stderr:
|
|
sys.stderr = stderr
|
|
else:
|
|
self.stderr = sys.stderr
|
|
return more
|
|
|
|
def runModule(self, mod):
|
|
"""Compile and run an ast module in the interpreter."""
|
|
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
|
|
sys.stdin, sys.stdout, sys.stderr = \
|
|
self.stdin, self.stdout, self.stderr
|
|
self.runcode(compile(mod,'','single'))
|
|
# If sys.std* is still what we set it to, then restore it.
|
|
# But, if the executed source changed sys.std*, assume it was
|
|
# meant to be changed and leave it. Power to the people.
|
|
if sys.stdin == self.stdin:
|
|
sys.stdin = stdin
|
|
else:
|
|
self.stdin = sys.stdin
|
|
if sys.stdout == self.stdout:
|
|
sys.stdout = stdout
|
|
else:
|
|
self.stdout = sys.stdout
|
|
if sys.stderr == self.stderr:
|
|
sys.stderr = stderr
|
|
else:
|
|
self.stderr = sys.stderr
|
|
return False
|
|
|
|
def getAutoCompleteKeys(self):
|
|
"""Return list of auto-completion keycodes."""
|
|
return [ord('.')]
|
|
|
|
def getAutoCompleteList(self, command='', *args, **kwds):
|
|
"""Return list of auto-completion options for a command.
|
|
|
|
The list of options will be based on the locals namespace."""
|
|
stdin, stdout, stderr = sys.stdin, sys.stdout, sys.stderr
|
|
sys.stdin, sys.stdout, sys.stderr = \
|
|
self.stdin, self.stdout, self.stderr
|
|
l = introspect.getAutoCompleteList(command, self.locals,
|
|
*args, **kwds)
|
|
sys.stdin, sys.stdout, sys.stderr = stdin, stdout, stderr
|
|
return l
|
|
|
|
def getCallTip(self, command='', *args, **kwds):
|
|
"""Return call tip text for a command.
|
|
|
|
Call tip information will be based on the locals namespace."""
|
|
return introspect.getCallTip(command, self.locals, *args, **kwds)
|
|
|
|
|
|
class InterpreterAlaCarte(Interpreter):
|
|
"""Demo Interpreter."""
|
|
|
|
def __init__(self, locals, rawin, stdin, stdout, stderr,
|
|
ps1='main prompt', ps2='continuation prompt'):
|
|
"""Create an interactive interpreter object."""
|
|
Interpreter.__init__(self, locals=locals, rawin=rawin,
|
|
stdin=stdin, stdout=stdout, stderr=stderr)
|
|
sys.ps1 = ps1
|
|
sys.ps2 = ps2
|
|
|
|
|