##// END OF EJS Templates
Make post-execution happen at the cell instead of the block level....
Fernando Perez -
Show More
@@ -272,7 +272,7 b' class InteractiveShell(Configurable, Magic):'
272 272 history_manager = Instance('IPython.core.history.HistoryManager')
273 273
274 274 # Private interface
275 _post_execute = set()
275 _post_execute = Instance(dict)
276 276
277 277 def __init__(self, config=None, ipython_dir=None,
278 278 user_ns=None, user_global_ns=None,
@@ -462,6 +462,9 b' class InteractiveShell(Configurable, Magic):'
462 462 # Indentation management
463 463 self.indent_current_nsp = 0
464 464
465 # Dict to track post-execution functions that have been registered
466 self._post_execute = {}
467
465 468 def init_environment(self):
466 469 """Any changes we need to make to the user's environment."""
467 470 pass
@@ -657,7 +660,7 b' class InteractiveShell(Configurable, Magic):'
657 660 """
658 661 if not callable(func):
659 662 raise ValueError('argument %s must be callable' % func)
660 self._post_execute.add(func)
663 self._post_execute[func] = True
661 664
662 665 #-------------------------------------------------------------------------
663 666 # Things related to the "main" module
@@ -1784,7 +1787,7 b' class InteractiveShell(Configurable, Magic):'
1784 1787 # Grab local namespace if we need it:
1785 1788 if getattr(fn, "needs_local_scope", False):
1786 1789 self._magic_locals = sys._getframe(1).f_locals
1787 with nested(self.builtin_trap,):
1790 with self.builtin_trap:
1788 1791 result = fn(magic_args)
1789 1792 # Ensure we're not keeping object references around:
1790 1793 self._magic_locals = {}
@@ -2001,7 +2004,7 b' class InteractiveShell(Configurable, Magic):'
2001 2004
2002 2005 def ex(self, cmd):
2003 2006 """Execute a normal python statement in user namespace."""
2004 with nested(self.builtin_trap,):
2007 with self.builtin_trap:
2005 2008 exec cmd in self.user_global_ns, self.user_ns
2006 2009
2007 2010 def ev(self, expr):
@@ -2009,7 +2012,7 b' class InteractiveShell(Configurable, Magic):'
2009 2012
2010 2013 Returns the result of evaluation
2011 2014 """
2012 with nested(self.builtin_trap,):
2015 with self.builtin_trap:
2013 2016 return eval(expr, self.user_global_ns, self.user_ns)
2014 2017
2015 2018 def safe_execfile(self, fname, *where, **kw):
@@ -2148,8 +2151,8 b' class InteractiveShell(Configurable, Magic):'
2148 2151 with self.display_trap:
2149 2152 try:
2150 2153 code_ast = ast.parse(cell, filename=cell_name)
2151 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2152 # Case 1
2154 except (OverflowError, SyntaxError, ValueError, TypeError,
2155 MemoryError):
2153 2156 self.showsyntaxerror()
2154 2157 self.execution_count += 1
2155 2158 return None
@@ -2159,6 +2162,17 b' class InteractiveShell(Configurable, Magic):'
2159 2162 interactivity = 'all' # Single line; run fully interactive
2160 2163
2161 2164 self.run_ast_nodes(code_ast.body, cell_name, interactivity)
2165
2166 # Execute any registered post-execution functions.
2167 for func, status in self._post_execute.iteritems():
2168 if not status:
2169 continue
2170 try:
2171 func()
2172 except:
2173 self.showtraceback()
2174 # Deactivate failing function
2175 self._post_execute[func] = False
2162 2176
2163 2177 if store_history:
2164 2178 # Write output to the database. Does nothing unless
@@ -2254,8 +2268,7 b' class InteractiveShell(Configurable, Magic):'
2254 2268 if more:
2255 2269 self.push_line('\n')
2256 2270
2257 def run_source(self, source, filename=None,
2258 symbol='single', post_execute=True):
2271 def run_source(self, source, filename=None, symbol='single'):
2259 2272 """Compile and run some source in the interpreter.
2260 2273
2261 2274 Arguments are as for compile_command().
@@ -2290,12 +2303,6 b' class InteractiveShell(Configurable, Magic):'
2290 2303 else:
2291 2304 usource = source
2292 2305
2293 if False: # dbg
2294 print 'Source:', repr(source) # dbg
2295 print 'USource:', repr(usource) # dbg
2296 print 'type:', type(source) # dbg
2297 print 'encoding', self.stdin_encoding # dbg
2298
2299 2306 try:
2300 2307 code_name = self.compile.cache(usource, self.execution_count)
2301 2308 code = self.compile(usource, code_name, symbol)
@@ -2315,7 +2322,7 b' class InteractiveShell(Configurable, Magic):'
2315 2322 # buffer attribute as '\n'.join(self.buffer).
2316 2323 self.code_to_run = code
2317 2324 # now actually execute the code object
2318 if self.run_code(code, post_execute) == 0:
2325 if self.run_code(code) == 0:
2319 2326 return False
2320 2327 else:
2321 2328 return None
@@ -2323,7 +2330,7 b' class InteractiveShell(Configurable, Magic):'
2323 2330 # For backwards compatibility
2324 2331 runsource = run_source
2325 2332
2326 def run_code(self, code_obj, post_execute=True):
2333 def run_code(self, code_obj):
2327 2334 """Execute a code object.
2328 2335
2329 2336 When an exception occurs, self.showtraceback() is called to display a
@@ -2366,22 +2373,6 b' class InteractiveShell(Configurable, Magic):'
2366 2373 if softspace(sys.stdout, 0):
2367 2374 print
2368 2375
2369 # Execute any registered post-execution functions. Here, any errors
2370 # are reported only minimally and just on the terminal, because the
2371 # main exception channel may be occupied with a user traceback.
2372 # FIXME: we need to think this mechanism a little more carefully.
2373 if post_execute:
2374 for func in self._post_execute:
2375 try:
2376 func()
2377 except:
2378 head = '[ ERROR ] Evaluating post_execute function: %s' % \
2379 func
2380 print >> io.Term.cout, head
2381 print >> io.Term.cout, self._simple_error()
2382 print >> io.Term.cout, 'Removing from post_execute'
2383 self._post_execute.remove(func)
2384
2385 2376 # Flush out code object which has been run (and source)
2386 2377 self.code_to_run = None
2387 2378 return outflag
General Comments 0
You need to be logged in to leave comments. Login now