diff --git a/IPython/core/inputtransformer.py b/IPython/core/inputtransformer.py index 8973ab6..9f46713 100644 --- a/IPython/core/inputtransformer.py +++ b/IPython/core/inputtransformer.py @@ -3,6 +3,7 @@ import functools import re from StringIO import StringIO +from IPython.core.error import UsageError from IPython.core.splitinput import LineInfo from IPython.utils import tokenize2 from IPython.utils.openpy import cookie_comment_re @@ -227,9 +228,20 @@ def _tr_help(line_info): def _tr_magic(line_info): "Translate lines escaped with: %" tpl = '%sget_ipython().magic(%r)' + if line_info.line.startswith(ESC_MAGIC2): + return line_info.line cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip() return tpl % (line_info.pre, cmd) +def _tr_cellmagic(line_info): + """Translate lines escaped with %% + + Only happens when cell magics are mid-cell, which is an error. + """ + raise UsageError("Cannot call cell magics (%s%s) mid-cell" % + (ESC_MAGIC2, line_info.ifun) + ) + def _tr_quote(line_info): "Translate lines escaped with: ," return '%s%s("%s")' % (line_info.pre, line_info.ifun, @@ -250,6 +262,7 @@ tr = { ESC_SHELL : _tr_system, ESC_HELP : _tr_help, ESC_HELP2 : _tr_help, ESC_MAGIC : _tr_magic, + ESC_MAGIC2 : _tr_cellmagic, ESC_QUOTE : _tr_quote, ESC_QUOTE2 : _tr_quote2, ESC_PAREN : _tr_paren } diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index db88ce5..f7fe355 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2593,10 +2593,14 @@ class InteractiveShell(SingletonConfigurable): if silent: store_history = False - - self.input_transformer_manager.push(raw_cell) - cell = self.input_transformer_manager.source_reset() - + + try: + self.input_transformer_manager.push(raw_cell) + cell = self.input_transformer_manager.source_reset() + except UsageError: + self.showtraceback() + return + # Our own compiler remembers the __future__ environment. If we want to # run code with a separate __future__ environment, use the default # compiler diff --git a/IPython/core/splitinput.py b/IPython/core/splitinput.py index 7b95772..fd8df7c 100644 --- a/IPython/core/splitinput.py +++ b/IPython/core/splitinput.py @@ -43,7 +43,7 @@ from IPython.utils.encoding import get_stream_enc line_split = re.compile(""" ^(\s*) # any leading space - ([,;/%]|!!?|\?\??)? # escape character or characters + ([,;/]|%%?|!!?|\?\??)? # escape character or characters \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading % # to correctly treat things like '?%magic' (.*?$|$) # rest of line