##// END OF EJS Templates
Merge pull request #1020 from takluyver/dollar-formatter...
Merge pull request #1020 from takluyver/dollar-formatter Dollar formatter for ! shell calls. This uses a subclass of `FullEvalFormatter` for filling in variables in shell commands like `!echo $spam`, instead of Itpl. I've retained the `{foo}` style standard formatting for complex expressions, so it can be picked up by the more powerful built in parser. `$foo` works for names and attribute access. FullEvalFormatter now always outputs unicode, even if you gave it a bytes string. This avoids problems when you mix 8-bit non-ascii strings and unicode (which e.g. `StringIO.StringIO` suffers from). Closes #822 (test was added in 31ab23f).

File last commit:

r4872:34c10438
r5358:09c9952f merge
Show More
prefilterfrontend.py
256 lines | 9.6 KiB | text/x-python | PythonLexer
Gael Varoquaux
Add forgotten file.
r1385 """
Frontend class that uses IPython0 to prefilter the inputs.
Using the IPython0 mechanism gives us access to the magics.
gvaroquaux
Clean up code, names, and docstrings.
r1455
This is a transitory class, used here to do the transition between
ipython0 and ipython1. This class is meant to be short-lived as more
functionnality is abstracted out of ipython0 in reusable functions and
is added on the interpreter. This class can be a used to guide this
refactoring.
Gael Varoquaux
Add forgotten file.
r1385 """
#-------------------------------------------------------------------------------
# Copyright (C) 2008 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# Imports
#-------------------------------------------------------------------------------
import sys
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840 import pydoc
import os
Gael Varoquaux
ENH: Add continuation prompts
r1884 import re
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840 import __builtin__
Gael Varoquaux
Add forgotten file.
r1385
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 from IPython.core.iplib import InteractiveShell
Gael Varoquaux
Make the OS-level stdout/stderr capture work in the frontends.
r1423 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
Gael Varoquaux
Add forgotten file.
r1385
Gael Varoquaux
First cut of subprocess execution with redirection of stdin/stdout.
r1437 from IPython.kernel.core.sync_traceback_trap import SyncTracebackTrap
Brian Granger
Changing how IPython.utils.io.Term is handled....
r2775 import IPython.utils.io
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840
from linefrontendbase import LineFrontEndBase, common_prefix
gvaroquaux
Clean up code, names, and docstrings.
r1455
Fernando Perez
Work in multiple places to improve state of the test suite....
r2398 #-----------------------------------------------------------------------------
# Utility functions
#-----------------------------------------------------------------------------
Gael Varoquaux
Add forgotten file.
r1385
Gael Varoquaux
First cut of subprocess execution with redirection of stdin/stdout.
r1437 def mk_system_call(system_call_function, command):
""" given a os.system replacement, and a leading string command,
returns a function that will execute the command with the given
argument string.
Gael Varoquaux
Tweak magics.
r1424 """
def my_system_call(args):
Gael Varoquaux
First cut of subprocess execution with redirection of stdin/stdout.
r1437 system_call_function("%s %s" % (command, args))
gvaroquaux
Add a docstring to magics to fix the broken "%magic" magic.
r1730
my_system_call.__doc__ = "Calls %s" % command
Gael Varoquaux
Tweak magics.
r1424 return my_system_call
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 #-----------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872 # Frontend class using ipython0 to do the prefiltering.
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 #-----------------------------------------------------------------------------
Gael Varoquaux
Add forgotten file.
r1385 class PrefilterFrontEnd(LineFrontEndBase):
gvaroquaux
Clean up code, names, and docstrings.
r1455 """ Class that uses ipython0 to do prefilter the input, do the
completion and the magics.
The core trick is to use an ipython0 instance to prefilter the
input, and share the namespace between the interpreter instance used
to execute the statements and the ipython0 used for code
completion...
"""
Gael Varoquaux
Fix a completion crasher (index error during completion)....
r1624
debug = False
Bernardo B. Marques
remove all trailling spaces
r4872
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 def __init__(self, ipython0=None, *args, **kwargs):
Fernando Perez
Small fixes to get a cleaner doc build, and junk removal....
r2109 """ Parameters
----------
Gael Varoquaux
Make the prefilterfrontend take an optional ipython0 instance as the...
r1504
ipython0: an optional ipython0 instance to use for command
prefiltering and completion.
"""
Gael Varoquaux
Fix a completion crasher (index error during completion)....
r1624 LineFrontEndBase.__init__(self, *args, **kwargs)
self.shell.output_trap = RedirectorOutputTrap(
out_callback=self.write,
err_callback=self.write,
)
self.shell.traceback_trap = SyncTracebackTrap(
formatters=self.shell.traceback_trap.formatters,
)
# Start the ipython0 instance:
Gael Varoquaux
Isolate the displayhook created by ipython0. This fixes a test not...
r1472 self.save_output_hooks()
Gael Varoquaux
Make the prefilterfrontend take an optional ipython0 instance as the...
r1504 if ipython0 is None:
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 # Instanciate an IPython0 InteractiveShell to be able to use the
Gael Varoquaux
Make the prefilterfrontend take an optional ipython0 instance as the...
r1504 # prefiltering.
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840 # Suppress all key input, to avoid waiting
def my_rawinput(x=None):
return '\n'
old_rawinput = __builtin__.raw_input
__builtin__.raw_input = my_rawinput
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 ipython0 = InteractiveShell(
parent=None, user_ns=self.shell.user_ns,
user_global_ns=self.shell.user_global_ns
)
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840 __builtin__.raw_input = old_rawinput
Brian Granger
More work addressing review comments for Fernando's branch....
r2499 self.ipython0 = ipython0
Gael Varoquaux
Add forgotten file.
r1385 # Set the pager:
Bernardo B. Marques
remove all trailling spaces
r4872 self.ipython0.set_hook('show_in_pager',
Gael Varoquaux
Make the prefilterfrontend take an optional ipython0 instance as the...
r1504 lambda s, string: self.write("\n" + string))
Gael Varoquaux
Add forgotten file.
r1385 self.ipython0.write = self.write
Brian Granger
Continuing a massive refactor of everything.
r2205 self._ip = _ip = self.ipython0
Gael Varoquaux
Add forgotten file.
r1385 # Make sure the raw system call doesn't get called, as we don't
# have a stdin accessible.
Gael Varoquaux
First cut of subprocess execution with redirection of stdin/stdout.
r1437 self._ip.system = self.system_call
Gael Varoquaux
Tweak magics.
r1424 # XXX: Muck around with magics so that they work better
# in our environment
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840 if not sys.platform.startswith('win'):
Bernardo B. Marques
remove all trailling spaces
r4872 self.ipython0.magic_ls = mk_system_call(self.system_call,
Gael Varoquaux
BUG: Fix minor frontend bugs
r1840 'ls -CF')
Gael Varoquaux
Isolate the displayhook created by ipython0. This fixes a test not...
r1472 # And now clean up the mess created by ipython0
self.release_output()
Gael Varoquaux
Fix a completion crasher (index error during completion)....
r1624
Gael Varoquaux
Fix tests when ipdoctest nose plugin is enable (Grrr, no isolation at...
r1505 if not 'banner' in kwargs and self.banner is None:
Fernando Perez
A few small fixes so ipythonx works, and PEP-8 cleanups I found along the way.
r2400 self.banner = self.ipython0.banner
Gael Varoquaux
Add a banner.
r1495
Gael Varoquaux
ENH: Add continuation prompts
r1884 # FIXME: __init__ and start should be two different steps
Gael Varoquaux
Fix a completion crasher (index error during completion)....
r1624 self.start()
Gael Varoquaux
Add forgotten file.
r1385
gvaroquaux
Clean up code, names, and docstrings.
r1455 #--------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872 # FrontEndBase interface
gvaroquaux
Clean up code, names, and docstrings.
r1455 #--------------------------------------------------------------------------
Gael Varoquaux
Add forgotten file.
r1385
def show_traceback(self):
gvaroquaux
Clean up code, names, and docstrings.
r1455 """ Use ipython0 to capture the last traceback and display it.
"""
Gael Varoquaux
Isolate better traceback printing
r1825 # Don't do the capture; the except_hook has already done some
# modifications to the IO streams, if we store them, we'll be
# storing the wrong ones.
#self.capture_output()
gvaroquaux
Better display of exception: do not display the calling code in the...
r1640 self.ipython0.showtraceback(tb_offset=-1)
Gael Varoquaux
Add forgotten file.
r1385 self.release_output()
Gael Varoquaux
Add demo app. Add callback for exit to the ipython0 code.
r1391 def execute(self, python_string, raw_string=None):
gvaroquaux
Better fonts on MacOSX....
r1502 if self.debug:
print 'Executing Python code:', repr(python_string)
Gael Varoquaux
Add demo app. Add callback for exit to the ipython0 code.
r1391 self.capture_output()
LineFrontEndBase.execute(self, python_string,
raw_string=raw_string)
self.release_output()
Gael Varoquaux
Isolate the displayhook created by ipython0. This fixes a test not...
r1472 def save_output_hooks(self):
""" Store all the output hooks we can think of, to be able to
Bernardo B. Marques
remove all trailling spaces
r4872 restore them.
Gael Varoquaux
Isolate the displayhook created by ipython0. This fixes a test not...
r1472 We need to do this early, as starting the ipython0 instance will
screw ouput hooks.
"""
self.__old_cout_write = Term.cout.write
self.__old_cerr_write = Term.cerr.write
self.__old_stdout = sys.stdout
self.__old_stderr= sys.stderr
self.__old_help_output = pydoc.help.output
self.__old_display_hook = sys.displayhook
Gael Varoquaux
Add forgotten file.
r1385 def capture_output(self):
Gael Varoquaux
Add demo app. Add callback for exit to the ipython0 code.
r1391 """ Capture all the output mechanisms we can think of.
Gael Varoquaux
Add forgotten file.
r1385 """
Gael Varoquaux
Isolate the displayhook created by ipython0. This fixes a test not...
r1472 self.save_output_hooks()
Gael Varoquaux
Add forgotten file.
r1385 Term.cout.write = self.write
Term.cerr.write = self.write
sys.stdout = Term.cout
sys.stderr = Term.cerr
Gael Varoquaux
Add demo app. Add callback for exit to the ipython0 code.
r1391 pydoc.help.output = self.shell.output_trap.out
Gael Varoquaux
Make "help()" work.
r1390
Gael Varoquaux
Add forgotten file.
r1385
def release_output(self):
Gael Varoquaux
Add demo app. Add callback for exit to the ipython0 code.
r1391 """ Release all the different captures we have made.
Gael Varoquaux
Add forgotten file.
r1385 """
Term.cout.write = self.__old_cout_write
Gael Varoquaux
Isolate the displayhook created by ipython0. This fixes a test not...
r1472 Term.cerr.write = self.__old_cerr_write
Gael Varoquaux
Add forgotten file.
r1385 sys.stdout = self.__old_stdout
sys.stderr = self.__old_stderr
Bernardo B. Marques
remove all trailling spaces
r4872 pydoc.help.output = self.__old_help_output
sys.displayhook = self.__old_display_hook
Gael Varoquaux
Add forgotten file.
r1385
def complete(self, line):
Gael Varoquaux
Fix a completion crasher (index error during completion)....
r1624 # FIXME: This should be factored out in the linefrontendbase
# method.
Gael Varoquaux
ENH: Add continuation prompts
r1884 word = self._get_completion_text(line)
Gael Varoquaux
Add forgotten file.
r1385 completions = self.ipython0.complete(word)
Gael Varoquaux
Modified OutputTrap to accept a file-like object and use it instead of...
r1407 # FIXME: The proper sort should be done in the complete method.
Gael Varoquaux
Add forgotten file.
r1385 key = lambda x: x.replace('_', '')
completions.sort(key=key)
if completions:
Bernardo B. Marques
remove all trailling spaces
r4872 prefix = common_prefix(completions)
Gael Varoquaux
Add forgotten file.
r1385 line = line[:-len(word)] + prefix
Fernando Perez
Work in multiple places to improve state of the test suite....
r2398 return line, completions
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Clean up code, names, and docstrings.
r1455 #--------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872 # LineFrontEndBase interface
gvaroquaux
Clean up code, names, and docstrings.
r1455 #--------------------------------------------------------------------------
def prefilter_input(self, input_string):
""" Using IPython0 to prefilter the commands to turn them
in executable statements that are valid Python strings.
"""
input_string = LineFrontEndBase.prefilter_input(self, input_string)
filtered_lines = []
# The IPython0 prefilters sometime produce output. We need to
# capture it.
self.capture_output()
self.last_result = dict(number=self.prompt_number)
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Clean up code, names, and docstrings.
r1455 try:
Fernando Perez
Partial fixes for 2.4 compatibility. Unfinished....
r1706 try:
for line in input_string.split('\n'):
Fernando Perez
Work in multiple places to improve state of the test suite....
r2398 pf = self.ipython0.prefilter_manager.prefilter_lines
filtered_lines.append(pf(line, False).rstrip())
Fernando Perez
Partial fixes for 2.4 compatibility. Unfinished....
r1706 except:
# XXX: probably not the right thing to do.
self.ipython0.showsyntaxerror()
self.after_execute()
gvaroquaux
Clean up code, names, and docstrings.
r1455 finally:
self.release_output()
gvaroquaux
Better fonts on MacOSX....
r1502 # Clean up the trailing whitespace, to avoid indentation errors
gvaroquaux
Clean up code, names, and docstrings.
r1455 filtered_string = '\n'.join(filtered_lines)
return filtered_string
#--------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872 # PrefilterFrontEnd interface
gvaroquaux
Clean up code, names, and docstrings.
r1455 #--------------------------------------------------------------------------
Bernardo B. Marques
remove all trailling spaces
r4872
gvaroquaux
Clean up code, names, and docstrings.
r1455 def system_call(self, command_string):
""" Allows for frontend to define their own system call, to be
able capture output and redirect input.
"""
return os.system(command_string)
Gael Varoquaux
Add demo app. Add callback for exit to the ipython0 code.
r1391 def do_exit(self):
""" Exit the shell, cleanup and save the history.
"""
self.ipython0.atexit_operations()
Gael Varoquaux
ENH: Add continuation prompts
r1884 def _get_completion_text(self, line):
""" Returns the text to be completed by breaking the line at specified
delimiters.
"""
# Break at: spaces, '=', all parentheses (except if balanced).
# FIXME2: In the future, we need to make the implementation similar to
# that in the 'pyreadline' module (modes/basemode.py) where we break at
# each delimiter and try to complete the residual line, until we get a
# successful list of completions.
Bernardo B. Marques
remove all trailling spaces
r4872 expression = '\s|=|,|:|\((?!.*\))|\[(?!.*\])|\{(?!.*\})'
Gael Varoquaux
ENH: Add continuation prompts
r1884 complete_sep = re.compile(expression)
text = complete_sep.split(line)[-1]
return text