[pypy-svn] r53464 - in pypy/dist/pypy: lib translator/goal
arigo at codespeak.net
arigo at codespeak.net
Sun Apr 6 17:41:53 CEST 2008
Author: arigo
Date: Sun Apr 6 17:41:52 2008
New Revision: 53464
Added:
pypy/dist/pypy/lib/_pypy_interact.py (contents, props changed)
Modified:
pypy/dist/pypy/lib/readline.py
pypy/dist/pypy/translator/goal/app_main.py
Log:
* Move interactive_console() to its own module for easier experimentation.
* Extend the pyrepl-based readline with a multiline_input() function.
* Use it for multiline inputs in the default pypy-c prompt. Yay :-)
Added: pypy/dist/pypy/lib/_pypy_interact.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/_pypy_interact.py Sun Apr 6 17:41:52 2008
@@ -0,0 +1,74 @@
+"""Imported by app_main.py when PyPy needs to fire up the interactive console.
+"""
+import sys
+
+
+def interactive_console(mainmodule=None):
+ import code
+ if mainmodule is None:
+ import __main__ as mainmodule
+ console = code.InteractiveConsole(mainmodule.__dict__)
+ try:
+ from readline import multiline_input
+ except ImportError:
+ run_simple_interactive_console(console)
+ else:
+ run_multiline_interactive_console(console)
+
+def run_simple_interactive_console(console):
+ # some parts of code.py are copied here because it seems to be impossible
+ # to start an interactive console without printing at least one line
+ # of banner
+ more = 0
+ while 1:
+ try:
+ if more:
+ prompt = getattr(sys, 'ps2', '... ')
+ else:
+ prompt = getattr(sys, 'ps1', '>>> ')
+ try:
+ line = raw_input(prompt)
+ except EOFError:
+ console.write("\n")
+ break
+ else:
+ more = console.push(line)
+ except KeyboardInterrupt:
+ console.write("\nKeyboardInterrupt\n")
+ console.resetbuffer()
+ more = 0
+
+def run_multiline_interactive_console(console):
+ from readline import multiline_input
+
+ def more_lines(unicodetext):
+ # ooh, look at the hack:
+ src = "#coding:utf-8\n"+unicodetext.encode('utf-8')
+ try:
+ code = console.compile(src, '<input>', 'single')
+ except (OverflowError, SyntaxError, ValueError):
+ return False
+ else:
+ return code is None
+
+ while 1:
+ try:
+ ps1 = getattr(sys, 'ps1', '>>> ')
+ ps2 = getattr(sys, 'ps2', '... ')
+ try:
+ statement = multiline_input(more_lines, ps1, ps2)
+ except EOFError:
+ break
+ more = console.push(statement)
+ assert not more
+ except KeyboardInterrupt:
+ console.write("\nKeyboardInterrupt\n")
+ console.resetbuffer()
+
+# ____________________________________________________________
+
+if __name__ == '__main__': # for testing
+ import os
+ if os.getenv('PYTHONSTARTUP'):
+ execfile(os.getenv('PYTHONSTARTUP'))
+ interactive_console()
Modified: pypy/dist/pypy/lib/readline.py
==============================================================================
--- pypy/dist/pypy/lib/readline.py (original)
+++ pypy/dist/pypy/lib/readline.py Sun Apr 6 17:41:52 2008
@@ -45,6 +45,38 @@
cut = 0
return self.history[cut:]
+ # --- simplified support for reading multiline Python statements ---
+
+ # This duplicates small parts of pyrepl.python_reader. I'm not
+ # reusing the PythonicReader class directly for two reasons. One is
+ # to try to keep as close as possible to CPython's prompt. The
+ # other is that it is the readline module that we are ultimately
+ # implementing here, and I don't want the built-in raw_input() to
+ # start trying to read multiline inputs just because what the user
+ # typed look like valid but incomplete Python code. So we get the
+ # multiline feature only when using the multiline_input() function
+ # directly (see _pypy_interact.py).
+
+ more_lines = None
+
+ def collect_keymap(self):
+ return super(_ReaderMixin, self).collect_keymap() + (
+ (r'\n', 'maybe-accept'),)
+
+ def __init__(self, console):
+ super(_ReaderMixin, self).__init__(console)
+ from pyrepl import commands
+ class maybe_accept(commands.Command):
+ def do(self):
+ r = self.reader
+ text = r.get_unicode()
+ if r.more_lines is not None and r.more_lines(text):
+ r.insert("\n")
+ else:
+ self.finish = 1
+ self.commands['maybe_accept'] = maybe_accept
+ self.commands['maybe-accept'] = maybe_accept
+
# ____________________________________________________________
class _ReadlineWrapper(object):
@@ -72,6 +104,27 @@
reader.ps1 = prompt
return reader.readline()
+ def multiline_input(self, more_lines, ps1, ps2):
+ """Read an input on possibly multiple lines, asking for more
+ lines as long as 'more_lines(unicodetext)' returns an object whose
+ boolean value is true.
+ """
+ reader = self.get_reader()
+ saved = reader.more_lines
+ try:
+ reader.more_lines = more_lines
+ reader.ps1 = reader.ps2 = ps1
+ reader.ps3 = reader.ps4 = ps2
+ return reader.readline()
+ finally:
+ reader.more_lines = saved
+
+ def compiler(self, textstring):
+ if self.pyconsole is None:
+ return True
+ else:
+ return self.pyconsole.compile(textstring, '<input>', 'single')
+
def parse_and_bind(self, string):
pass # XXX we don't support parsing GNU-readline-style init files
@@ -172,6 +225,9 @@
add_history = _wrapper.add_history
set_startup_hook = _wrapper.set_startup_hook
+# Extension
+multiline_input = _wrapper.multiline_input
+
# ____________________________________________________________
# Stubs
@@ -225,11 +281,3 @@
__builtin__.raw_input = _wrapper.raw_input
_setup()
-
-if __name__ == '__main__': # for testing
- import __main__
- sys.modules['readline'] = __main__
- if os.getenv('PYTHONSTARTUP'):
- execfile(os.getenv('PYTHONSTARTUP'))
- import code
- code.interact()
Modified: pypy/dist/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/dist/pypy/translator/goal/app_main.py (original)
+++ pypy/dist/pypy/translator/goal/app_main.py Sun Apr 6 17:41:52 2008
@@ -337,6 +337,7 @@
success = run_toplevel(execfile, sys.argv[0], mainmodule.__dict__)
if is_interactive():
+ from _pypy_interact import interactive_console
success = run_toplevel(interactive_console, mainmodule)
except SystemExit, e:
return e.code
@@ -363,35 +364,6 @@
print ('Type "help", "copyright", "credits" or '
'"license" for more information.')
-def interactive_console(mainmodule):
- # some parts of code.py are copied here because it seems to be impossible
- # to start an interactive console without printing at least one line
- # of banner
- import code
- console = code.InteractiveConsole(mainmodule.__dict__)
- try:
- import readline
- except ImportError:
- pass
- more = 0
- while 1:
- try:
- if more:
- prompt = sys.ps2
- else:
- prompt = sys.ps1
- try:
- line = raw_input(prompt)
- except EOFError:
- console.write("\n")
- break
- else:
- more = console.push(line)
- except KeyboardInterrupt:
- console.write("\nKeyboardInterrupt\n")
- console.resetbuffer()
- more = 0
-
if __name__ == '__main__':
import autopath
More information about the Pypy-commit
mailing list