def execution_loop(self):
"""loop on the main thread which is responsible for executing code"""
if sys.platform == 'cli' and sys.version_info[:3] < (2, 7, 1):
# IronPython doesn't support thread.interrupt_main until 2.7.1
import System
self.main_thread = System.Threading.Thread.CurrentThread
# save ourselves so global lookups continue to work (required pre-2.6)...
cur_modules = set()
try:
cur_ps1 = sys.ps1
cur_ps2 = sys.ps2
except:
# CPython/IronPython don't set sys.ps1 for non-interactive sessions, Jython and PyPy do
sys.ps1 = cur_ps1 = '>>> '
sys.ps2 = cur_ps2 = '... '
self.send_prompt(cur_ps1, cur_ps2, allow_multiple_statements=False)
while True:
exit, cur_modules, cur_ps1, cur_ps2 = self.run_one_command(cur_modules, cur_ps1, cur_ps2)
if exit:
return
python类ps1()的实例源码
def execution_loop(self):
"""loop on the main thread which is responsible for executing code"""
if sys.platform == 'cli' and sys.version_info[:3] < (2, 7, 1):
# IronPython doesn't support thread.interrupt_main until 2.7.1
import System
self.main_thread = System.Threading.Thread.CurrentThread
# save ourselves so global lookups continue to work (required pre-2.6)...
cur_modules = set()
try:
cur_ps1 = sys.ps1
cur_ps2 = sys.ps2
except:
# CPython/IronPython don't set sys.ps1 for non-interactive sessions, Jython and PyPy do
sys.ps1 = cur_ps1 = '>>> '
sys.ps2 = cur_ps2 = '... '
self.send_prompt(cur_ps1, cur_ps2, allow_multiple_statements=False)
while True:
exit, cur_modules, cur_ps1, cur_ps2 = self.run_one_command(cur_modules, cur_ps1, cur_ps2)
if exit:
return
def bash(command="bash"):
"""Start a bash shell and return a :class:`REPLWrapper` object."""
bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
encoding='utf-8')
# If the user runs 'env', the value of PS1 will be in the output. To avoid
# replwrap seeing that as the next prompt, we'll embed the marker characters
# for invisible characters in the prompt; these show up when inspecting the
# environment variable, but not when bash displays the prompt.
ps1 = PEXPECT_PROMPT[:5] + u'\[\]' + PEXPECT_PROMPT[5:]
ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\[\]' + PEXPECT_CONTINUATION_PROMPT[5:]
prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
return REPLWrapper(child, u'\$', prompt_change,
extra_init_cmd="export PAGER=cat")
def executeLine_(self, line):
if line == "help":
self.writeStdout_(documentation)
self.writeCode_("\n")
return
self._history.append(line)
self._historyIndex = len(self._history)
save = (sys.stdout, sys.stderr, self.rawText())
sys.stdout = self._stdout
sys.stderr = self._stderr
more = False
try:
more = self._console.push(line)
if more:
self._prompt = sys.ps2
else:
self._prompt = sys.ps1
except:
self._prompt = sys.ps1
finally:
sys.stdout, sys.stderr, previousRawText = save
self.previousOutput = self.rawText()[len(previousRawText):-1]
# Selection, Insertion Point
def bash(command="bash"):
"""Start a bash shell and return a :class:`REPLWrapper` object."""
bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
encoding='utf-8')
# If the user runs 'env', the value of PS1 will be in the output. To avoid
# replwrap seeing that as the next prompt, we'll embed the marker characters
# for invisible characters in the prompt; these show up when inspecting the
# environment variable, but not when bash displays the prompt.
ps1 = PEXPECT_PROMPT[:5] + u'\[\]' + PEXPECT_PROMPT[5:]
ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\[\]' + PEXPECT_CONTINUATION_PROMPT[5:]
prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
return REPLWrapper(child, u'\$', prompt_change,
extra_init_cmd="export PAGER=cat")
def init_prompts(self):
# Set system prompts, so that scripts can decide if they are running
# interactively.
sys.ps1 = 'In : '
sys.ps2 = '...: '
sys.ps3 = 'Out: '
def _display_completions(self, completions):
if not completions:
return
self.console.write('\n')
wmax = max(map(len, completions))
w, h = self.console.size()
cols = max(1, int((w-1) / (wmax+1)))
rows = int(math.ceil(float(len(completions)) / cols))
for row in range(rows):
s = ''
for col in range(cols):
i = col*rows + row
if i < len(completions):
self.console.write(completions[i].ljust(wmax+1))
self.console.write('\n')
if in_ironpython:
self.prompt=sys.ps1
self._print_prompt()
def _bash_repl(command="bash", remove_ansi=True):
"""Start a bash shell and return a :class:`REPLWrapper` object."""
# `repl_bashrc.sh` suppresses user-defined PS1
bashrc = os.path.join(os.path.dirname(__file__), 'repl_bashrc.sh')
child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
encoding='utf-8')
# If the user runs 'env', the value of PS1 will be in the output. To avoid
# replwrap seeing that as the next prompt, we'll embed the marker characters
# for invisible characters in the prompt; these show up when inspecting the
# environment variable, but not when bash displays the prompt.
ps1 = PEXPECT_PROMPT[:5] + u'\[\]' + PEXPECT_PROMPT[5:]
ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\[\]' + PEXPECT_CONTINUATION_PROMPT[5:]
prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
return REPLWrapper(child, u'\$', prompt_change,
remove_ansi=remove_ansi,
extra_init_cmd="export PAGER=cat")
def _display_completions(self, completions):
if not completions:
return
self.console.write('\n')
wmax = max(map(len, completions))
w, h = self.console.size()
cols = max(1, int((w-1) / (wmax+1)))
rows = int(math.ceil(float(len(completions)) / cols))
for row in range(rows):
s = ''
for col in range(cols):
i = col*rows + row
if i < len(completions):
self.console.write(completions[i].ljust(wmax+1))
self.console.write('\n')
if in_ironpython:
self.prompt=sys.ps1
self._print_prompt()
def AppendToPrompt(self,bufLines, oldPrompt = None):
" Take a command and stick it at the end of the buffer (with python prompts inserted if required)."
self.flush()
lastLineNo = self.GetLineCount()-1
line = self.DoGetLine(lastLineNo)
if oldPrompt and line==oldPrompt:
self.SetSel(self.GetTextLength()-len(oldPrompt), self.GetTextLength())
self.ReplaceSel(sys.ps1)
elif (line!=str(sys.ps1)):
if len(line)!=0: self.write('\n')
self.write(sys.ps1)
self.flush()
self.idle.text.mark_set("iomark", "end-1c")
if not bufLines:
return
terms = (["\n" + sys.ps2] * (len(bufLines)-1)) + ['']
for bufLine, term in zip(bufLines, terms):
if bufLine.strip():
self.write( bufLine + term )
self.flush()
def AppendToPrompt(self,bufLines, oldPrompt = None):
" Take a command and stick it at the end of the buffer (with python prompts inserted if required)."
self.flush()
lastLineNo = self.GetLineCount()-1
line = self.DoGetLine(lastLineNo)
if oldPrompt and line==oldPrompt:
self.SetSel(self.GetTextLength()-len(oldPrompt), self.GetTextLength())
self.ReplaceSel(sys.ps1)
elif (line!=str(sys.ps1)):
if len(line)!=0: self.write('\n')
self.write(sys.ps1)
self.flush()
self.idle.text.mark_set("iomark", "end-1c")
if not bufLines:
return
terms = (["\n" + sys.ps2] * (len(bufLines)-1)) + ['']
for bufLine, term in zip(bufLines, terms):
if bufLine.strip():
self.write( bufLine + term )
self.flush()
def bash(command="bash"):
"""Start a bash shell and return a :class:`REPLWrapper` object."""
bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
encoding='utf-8')
# If the user runs 'env', the value of PS1 will be in the output. To avoid
# replwrap seeing that as the next prompt, we'll embed the marker characters
# for invisible characters in the prompt; these show up when inspecting the
# environment variable, but not when bash displays the prompt.
ps1 = PEXPECT_PROMPT[:5] + u'\[\]' + PEXPECT_PROMPT[5:]
ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\[\]' + PEXPECT_CONTINUATION_PROMPT[5:]
prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
return REPLWrapper(child, u'\$', prompt_change,
extra_init_cmd="export PAGER=cat")
def bash(command="bash"):
"""Start a bash shell and return a :class:`REPLWrapper` object."""
bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
encoding='utf-8')
# If the user runs 'env', the value of PS1 will be in the output. To avoid
# replwrap seeing that as the next prompt, we'll embed the marker characters
# for invisible characters in the prompt; these show up when inspecting the
# environment variable, but not when bash displays the prompt.
ps1 = PEXPECT_PROMPT[:5] + u'\\[\\]' + PEXPECT_PROMPT[5:]
ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\\[\\]' + PEXPECT_CONTINUATION_PROMPT[5:]
prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
return REPLWrapper(child, u'\\$', prompt_change,
extra_init_cmd="export PAGER=cat")
def help(self):
line = readline.get_line_buffer().rstrip()
if line == '' or line[-1] != '(':
return
m = self.METHOD_PATTERN.search(line)
if not m:
return
try:
thisobject = eval(m.group(1), self.namespace)
except Exception:
return
if not inspect.ismethod(thisobject):
return
m = self.METHOD_DEF_PATTERN.match(inspect.getsource(thisobject))
if m:
print("")
print(m.group(1))
print(inspect.getdoc(thisobject).strip())
print(sys.ps1 + readline.get_line_buffer(), end='', flush=True)
def _display_completions(self, completions):
if not completions:
return
self.console.write('\n')
wmax = max(map(len, completions))
w, h = self.console.size()
cols = max(1, int((w - 1) / (wmax + 1)))
rows = int(math.ceil(float(len(completions)) / cols))
for row in range(rows):
s = ''
for col in range(cols):
i = col * rows + row
if i < len(completions):
self.console.write(completions[i].ljust(wmax + 1))
self.console.write('\n')
if in_ironpython:
self.prompt = sys.ps1
self._print_prompt()
def _display_completions(self, completions):
if not completions:
return
self.console.write('\n')
wmax = max(map(len, completions))
w, h = self.console.size()
cols = max(1, int((w-1) / (wmax+1)))
rows = int(math.ceil(float(len(completions)) / cols))
for row in range(rows):
s = ''
for col in range(cols):
i = col*rows + row
if i < len(completions):
self.console.write(completions[i].ljust(wmax+1))
self.console.write('\n')
if in_ironpython:
self.prompt=sys.ps1
self._print_prompt()
def _display_completions(self, completions):
if not completions:
return
self.console.write('\n')
wmax = max(list(map(len, completions)))
w, h = self.console.size()
cols = max(1, int((w-1) / (wmax+1)))
rows = int(math.ceil(float(len(completions)) / cols))
for row in range(rows):
s = ''
for col in range(cols):
i = col*rows + row
if i < len(completions):
self.console.write(completions[i].ljust(wmax+1))
self.console.write('\n')
if in_ironpython:
self.prompt=sys.ps1
self._print_prompt()
def bash(command="bash"):
"""Start a bash shell and return a :class:`REPLWrapper` object."""
bashrc = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
child = pexpect.spawn(command, ['--rcfile', bashrc], echo=False,
encoding='utf-8')
# If the user runs 'env', the value of PS1 will be in the output. To avoid
# replwrap seeing that as the next prompt, we'll embed the marker characters
# for invisible characters in the prompt; these show up when inspecting the
# environment variable, but not when bash displays the prompt.
ps1 = PEXPECT_PROMPT[:5] + u'\[\]' + PEXPECT_PROMPT[5:]
ps2 = PEXPECT_CONTINUATION_PROMPT[:5] + u'\[\]' + PEXPECT_CONTINUATION_PROMPT[5:]
prompt_change = u"PS1='{0}' PS2='{1}' PROMPT_COMMAND=''".format(ps1, ps2)
return REPLWrapper(child, u'\$', prompt_change,
extra_init_cmd="export PAGER=cat")
def runsource(self, source, filename="<input>", symbol="single"):
"""Compile and run some source in the interpreter.
Arguments are as for compile_command().
One several things can happen:
1) The input is incorrect; compile_command() raised an
exception (SyntaxError or OverflowError). A syntax traceback
will be printed by calling the showsyntaxerror() method.
2) The input is incomplete, and more input is required;
compile_command() returned None. Nothing happens.
3) The input is complete; compile_command() returned a code
object. The code is executed by calling self.runcode() (which
also handles run-time exceptions, except for SystemExit).
The return value is True in case 2, False in the other cases (unless
an exception is raised). The return value can be used to
decide whether to use sys.ps1 or sys.ps2 to prompt the next
line.
"""
try:
code = self.compile(source, filename, symbol)
except (OverflowError, SyntaxError, ValueError):
# Case 1
self.showsyntaxerror(filename)
return False
if code is None:
# Case 2
return True
# Case 3
self.runcode(code)
return False
def _load_prompt(self):
sys.ps1 = "> "
def _load_prompt(self):
sys.ps1 = "> "
def _prompt_changer(attr,val):
prompt = conf.prompt
try:
ct = val
if isinstance(ct, AnsiColorTheme) and ct.prompt(""):
## ^A and ^B delimit invisible caracters for readline to count right.
## And we need ct.prompt() to do change something or else ^A and ^B will be
## displayed
prompt = "\001%s\002" % ct.prompt("\002"+prompt+"\001")
else:
prompt = ct.prompt(prompt)
except:
pass
sys.ps1 = prompt
def _prompt_changer(attr,val):
prompt = conf.prompt
try:
ct = val
if isinstance(ct, AnsiColorTheme) and ct.prompt(""):
## ^A and ^B delimit invisible caracters for readline to count right.
## And we need ct.prompt() to do change something or else ^A and ^B will be
## displayed
prompt = "\001%s\002" % ct.prompt("\002"+prompt+"\001")
else:
prompt = ct.prompt(prompt)
except:
pass
sys.ps1 = prompt
def runsource(self, source, filename="<input>", symbol="single"):
"""Compile and run some source in the interpreter.
Arguments are as for compile_command().
One several things can happen:
1) The input is incorrect; compile_command() raised an
exception (SyntaxError or OverflowError). A syntax traceback
will be printed by calling the showsyntaxerror() method.
2) The input is incomplete, and more input is required;
compile_command() returned None. Nothing happens.
3) The input is complete; compile_command() returned a code
object. The code is executed by calling self.runcode() (which
also handles run-time exceptions, except for SystemExit).
The return value is True in case 2, False in the other cases (unless
an exception is raised). The return value can be used to
decide whether to use sys.ps1 or sys.ps2 to prompt the next
line.
"""
try:
code = self.compile(source, filename, symbol)
except (OverflowError, SyntaxError, ValueError):
# Case 1
self.showsyntaxerror(filename)
return False
if code is None:
# Case 2
return True
# Case 3
self.runcode(code)
return False
def send_prompt(self, ps1, ps2, allow_multiple_statements):
"""sends the current prompt to the interactive window"""
with self.send_lock:
write_bytes(self.conn, ReplBackend._PRPC)
write_string(self.conn, ps1)
write_string(self.conn, ps2)
write_int(self.conn, 1 if allow_multiple_statements else 0)
def send_prompt(self, ps1, ps2, allow_multiple_statements):
"""sends the current prompt to the interactive window"""
with self.send_lock:
write_bytes(self.conn, ReplBackend._PRPC)
write_string(self.conn, ps1)
write_string(self.conn, ps2)
write_int(self.conn, 1 if allow_multiple_statements else 0)
def __call__(self, value):
print()
print(' Previous:', self.previous_value)
print(' New :', value)
print()
if value != self.previous_value:
self.count += 1
sys.ps1 = '({:3d})> '.format(self.count)
self.previous_value = value
sys.__displayhook__(value)
def python(command="python"):
"""Start a Python shell and return a :class:`REPLWrapper` object."""
return REPLWrapper(command, u">>> ", u"import sys; sys.ps1={0!r}; sys.ps2={1!r}")
def _prompt_changer(attr,val):
prompt = conf.prompt
try:
ct = val
if isinstance(ct, AnsiColorTheme) and ct.prompt(""):
## ^A and ^B delimit invisible caracters for readline to count right.
## And we need ct.prompt() to do change something or else ^A and ^B will be
## displayed
prompt = "\001%s\002" % ct.prompt("\002"+prompt+"\001")
else:
prompt = ct.prompt(prompt)
except:
pass
sys.ps1 = prompt
def test_init_prompt(self):
self.assertRegexpMatches(
sys.ps1, '\001\033\[1;3[23]m\002>>> \001\033\[0m\002'
)
self.assertEqual(sys.ps2, '\001\033[1;31m\002... \001\033[0m\002')
with patch.dict(os.environ,
{'SSH_CONNECTION': '1.1.1.1 10240 127.0.0.1 22'}):
self.pymp.init_prompt()
self.assertIn('[127.0.0.1]>>> ', sys.ps1)
self.assertIn('[127.0.0.1]... ', sys.ps2)