diff --git a/IPython/core/inputsplitter.py b/IPython/core/inputsplitter.py index 6028266..97c199d 100644 --- a/IPython/core/inputsplitter.py +++ b/IPython/core/inputsplitter.py @@ -486,17 +486,19 @@ class IPythonInputSplitter(InputSplitter): if physical_line_transforms is not None: self.physical_line_transforms = physical_line_transforms else: - self.physical_line_transforms = [leading_indent(), + self.physical_line_transforms = [ + leading_indent(), classic_prompt(), ipy_prompt(), strip_encoding_cookie(), + cellmagic(end_on_blank_line=line_input_checker), ] self.assemble_logical_lines = assemble_logical_lines() if logical_line_transforms is not None: self.logical_line_transforms = logical_line_transforms else: - self.logical_line_transforms = [cellmagic(end_on_blank_line=line_input_checker), + self.logical_line_transforms = [ help_end(), escaped_commands(), assign_from_magic(), diff --git a/IPython/core/inputtransformer.py b/IPython/core/inputtransformer.py index 95abe72..1a5f1bb 100644 --- a/IPython/core/inputtransformer.py +++ b/IPython/core/inputtransformer.py @@ -227,6 +227,8 @@ 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) @@ -272,7 +274,8 @@ _help_end_re = re.compile(r"""(%{0,2} [a-zA-Z_*][\w*]* # Variable name (\.[a-zA-Z_*][\w*]*)* # .etc.etc ) - (\?\??)$ # ? or ??""", + (\?\??)$ # ? or ?? + """, re.VERBOSE) def has_comment(src): @@ -328,7 +331,14 @@ def cellmagic(end_on_blank_line=False): line = '' while True: line = (yield line) - if (not line) or (not line.startswith(ESC_MAGIC2)): + # consume leading empty lines + while not line: + line = (yield line) + + if not line.startswith(ESC_MAGIC2): + # This isn't a cell magic, idle waiting for reset then start over + while line is not None: + line = (yield line) continue if cellmagic_help_re.match(line): diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index db88ce5..7bc69a7 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -1672,7 +1672,13 @@ class InteractiveShell(SingletonConfigurable): return etype, value, tb - + def show_usage_error(self, exc): + """Show a short message for UsageErrors + + These are special exceptions that shouldn't show a traceback. + """ + self.write_err("UsageError: %s" % exc) + def showtraceback(self,exc_tuple = None,filename=None,tb_offset=None, exception_only=False): """Display the exception that just occurred. @@ -1698,7 +1704,7 @@ class InteractiveShell(SingletonConfigurable): # line, there may be SyntaxError cases with imported code. self.showsyntaxerror(filename) elif etype is UsageError: - self.write_err("UsageError: %s" % value) + self.show_usage_error(value) else: if exception_only: stb = ['An exception has occurred, use %tb to see ' diff --git a/IPython/core/tests/test_inputsplitter.py b/IPython/core/tests/test_inputsplitter.py index e163fb8..9508979 100644 --- a/IPython/core/tests/test_inputsplitter.py +++ b/IPython/core/tests/test_inputsplitter.py @@ -446,6 +446,24 @@ class IPythonInputTestCase(InputSplitterTestCase): out = isp.transform_cell(raw) # Match ignoring trailing whitespace self.assertEqual(out.rstrip(), out_t.rstrip()) + + def test_cellmagic_preempt(self): + isp = self.isp + for raw, name, line, cell in [ + ("%%cellm a\nIn[1]:", u'cellm', u'a', u'In[1]:'), + ("%%cellm \nline\n>>>hi", u'cellm', u'', u'line\n>>>hi'), + (">>>%%cellm \nline\n>>>hi", u'cellm', u'', u'line\nhi'), + ("%%cellm \n>>>hi", u'cellm', u'', u'hi'), + ("%%cellm \nline1\nline2", u'cellm', u'', u'line1\nline2'), + ("%%cellm \nline1\\\\\nline2", u'cellm', u'', u'line1\\\\\nline2'), + ]: + expected = "get_ipython().run_cell_magic(%r, %r, %r)" % ( + name, line, cell + ) + out = isp.transform_cell(raw) + self.assertEqual(out.rstrip(), expected.rstrip()) + + #----------------------------------------------------------------------------- # Main - use as a script, mostly for developer experiments diff --git a/IPython/core/tests/test_inputtransformer.py b/IPython/core/tests/test_inputtransformer.py index 373aa5f..56d4c55 100644 --- a/IPython/core/tests/test_inputtransformer.py +++ b/IPython/core/tests/test_inputtransformer.py @@ -259,6 +259,9 @@ syntax_ml = \ (u'hello', None), (None , u_fmt("get_ipython().run_cell_magic({u}'bar', {u}'123', {u}'hello')")), ], + [(u'a=5', 'a=5'), + (u'%%cellmagic', '%%cellmagic'), + ], ], escaped =