Skip to content

Prevent prefilter from crashing IPython #415

Merged
merged 2 commits into from May 9, 2011
View
61 IPython/core/interactiveshell.py
@@ -38,7 +38,7 @@
from IPython.core import prefilter
from IPython.core import shadowns
from IPython.core import ultratb
-from IPython.core.alias import AliasManager
+from IPython.core.alias import AliasManager, AliasError
from IPython.core.autocall import ExitAutocall
from IPython.core.builtin_trap import BuiltinTrap
from IPython.core.compilerop import CachingCompiler
@@ -2129,40 +2129,51 @@ def run_cell(self, raw_cell, store_history=True):
cell = self.input_splitter.source_reset()
with self.builtin_trap:
+ prefilter_failed = False
if len(cell.splitlines()) == 1:
- cell = self.prefilter_manager.prefilter_lines(cell)
-
+ try:
+ cell = self.prefilter_manager.prefilter_lines(cell)
+ except AliasError as e:
+ error(e)
+ prefilter_failed=True
+ except Exception:
+ # don't allow prefilter errors to crash IPython
+ self.showtraceback()
+ prefilter_failed = True
+
# Store raw and processed history
if store_history:
self.history_manager.store_inputs(self.execution_count,
cell, raw_cell)
self.logger.log(cell, raw_cell)
- cell_name = self.compile.cache(cell, self.execution_count)
+ if not prefilter_failed:
+ # don't run if prefilter failed
+ cell_name = self.compile.cache(cell, self.execution_count)
- with self.display_trap:
- try:
- code_ast = ast.parse(cell, filename=cell_name)
- except (OverflowError, SyntaxError, ValueError, TypeError,
- MemoryError):
- self.showsyntaxerror()
- self.execution_count += 1
- return None
-
- self.run_ast_nodes(code_ast.body, cell_name,
- interactivity="last_expr")
-
- # Execute any registered post-execution functions.
- for func, status in self._post_execute.iteritems():
- if not status:
- continue
+ with self.display_trap:
try:
- func()
- except:
- self.showtraceback()
- # Deactivate failing function
- self._post_execute[func] = False
+ code_ast = ast.parse(cell, filename=cell_name)
+ except (OverflowError, SyntaxError, ValueError, TypeError,
+ MemoryError):
+ self.showsyntaxerror()
+ self.execution_count += 1
+ return None
+
+ self.run_ast_nodes(code_ast.body, cell_name,
+ interactivity="last_expr")
+
+ # Execute any registered post-execution functions.
+ for func, status in self._post_execute.iteritems():
+ if not status:
+ continue
+ try:
+ func()
+ except:
+ self.showtraceback()
+ # Deactivate failing function
+ self._post_execute[func] = False
if store_history:
# Write output to the database. Does nothing unless
View
16 IPython/core/tests/test_interactiveshell.py
@@ -20,7 +20,10 @@
#-----------------------------------------------------------------------------
# stdlib
import unittest
+from cStringIO import StringIO
+
from IPython.testing import decorators as dec
+from IPython.utils import io
#-----------------------------------------------------------------------------
# Tests
@@ -91,3 +94,16 @@ def test_magic_names_in_string(self):
ip = get_ipython()
ip.run_cell('a = """\n%exit\n"""')
self.assertEquals(ip.user_ns['a'], '\n%exit\n')
+
+ def test_alias_crash(self):
+ """Errors in prefilter can't crash IPython"""
+ ip = get_ipython()
+ ip.run_cell('%alias parts echo first %s second %s')
+ # capture stderr:
+ save_err = io.stderr
+ io.stderr = StringIO()
+ ip.run_cell('parts 1')
+ err = io.stderr.getvalue()
+ io.stderr = save_err
+ self.assertEquals(err.split(':')[0], 'ERROR')
+
Something went wrong with that request. Please try again.