##// 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 history_manager = Instance('IPython.core.history.HistoryManager')
272 history_manager = Instance('IPython.core.history.HistoryManager')
273
273
274 # Private interface
274 # Private interface
275 _post_execute = set()
275 _post_execute = Instance(dict)
276
276
277 def __init__(self, config=None, ipython_dir=None,
277 def __init__(self, config=None, ipython_dir=None,
278 user_ns=None, user_global_ns=None,
278 user_ns=None, user_global_ns=None,
@@ -462,6 +462,9 b' class InteractiveShell(Configurable, Magic):'
462 # Indentation management
462 # Indentation management
463 self.indent_current_nsp = 0
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 def init_environment(self):
468 def init_environment(self):
466 """Any changes we need to make to the user's environment."""
469 """Any changes we need to make to the user's environment."""
467 pass
470 pass
@@ -657,7 +660,7 b' class InteractiveShell(Configurable, Magic):'
657 """
660 """
658 if not callable(func):
661 if not callable(func):
659 raise ValueError('argument %s must be callable' % func)
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 # Things related to the "main" module
666 # Things related to the "main" module
@@ -1784,7 +1787,7 b' class InteractiveShell(Configurable, Magic):'
1784 # Grab local namespace if we need it:
1787 # Grab local namespace if we need it:
1785 if getattr(fn, "needs_local_scope", False):
1788 if getattr(fn, "needs_local_scope", False):
1786 self._magic_locals = sys._getframe(1).f_locals
1789 self._magic_locals = sys._getframe(1).f_locals
1787 with nested(self.builtin_trap,):
1790 with self.builtin_trap:
1788 result = fn(magic_args)
1791 result = fn(magic_args)
1789 # Ensure we're not keeping object references around:
1792 # Ensure we're not keeping object references around:
1790 self._magic_locals = {}
1793 self._magic_locals = {}
@@ -2001,7 +2004,7 b' class InteractiveShell(Configurable, Magic):'
2001
2004
2002 def ex(self, cmd):
2005 def ex(self, cmd):
2003 """Execute a normal python statement in user namespace."""
2006 """Execute a normal python statement in user namespace."""
2004 with nested(self.builtin_trap,):
2007 with self.builtin_trap:
2005 exec cmd in self.user_global_ns, self.user_ns
2008 exec cmd in self.user_global_ns, self.user_ns
2006
2009
2007 def ev(self, expr):
2010 def ev(self, expr):
@@ -2009,7 +2012,7 b' class InteractiveShell(Configurable, Magic):'
2009
2012
2010 Returns the result of evaluation
2013 Returns the result of evaluation
2011 """
2014 """
2012 with nested(self.builtin_trap,):
2015 with self.builtin_trap:
2013 return eval(expr, self.user_global_ns, self.user_ns)
2016 return eval(expr, self.user_global_ns, self.user_ns)
2014
2017
2015 def safe_execfile(self, fname, *where, **kw):
2018 def safe_execfile(self, fname, *where, **kw):
@@ -2148,8 +2151,8 b' class InteractiveShell(Configurable, Magic):'
2148 with self.display_trap:
2151 with self.display_trap:
2149 try:
2152 try:
2150 code_ast = ast.parse(cell, filename=cell_name)
2153 code_ast = ast.parse(cell, filename=cell_name)
2151 except (OverflowError, SyntaxError, ValueError, TypeError, MemoryError):
2154 except (OverflowError, SyntaxError, ValueError, TypeError,
2152 # Case 1
2155 MemoryError):
2153 self.showsyntaxerror()
2156 self.showsyntaxerror()
2154 self.execution_count += 1
2157 self.execution_count += 1
2155 return None
2158 return None
@@ -2159,6 +2162,17 b' class InteractiveShell(Configurable, Magic):'
2159 interactivity = 'all' # Single line; run fully interactive
2162 interactivity = 'all' # Single line; run fully interactive
2160
2163
2161 self.run_ast_nodes(code_ast.body, cell_name, interactivity)
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 if store_history:
2177 if store_history:
2164 # Write output to the database. Does nothing unless
2178 # Write output to the database. Does nothing unless
@@ -2254,8 +2268,7 b' class InteractiveShell(Configurable, Magic):'
2254 if more:
2268 if more:
2255 self.push_line('\n')
2269 self.push_line('\n')
2256
2270
2257 def run_source(self, source, filename=None,
2271 def run_source(self, source, filename=None, symbol='single'):
2258 symbol='single', post_execute=True):
2259 """Compile and run some source in the interpreter.
2272 """Compile and run some source in the interpreter.
2260
2273
2261 Arguments are as for compile_command().
2274 Arguments are as for compile_command().
@@ -2290,12 +2303,6 b' class InteractiveShell(Configurable, Magic):'
2290 else:
2303 else:
2291 usource = source
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 try:
2306 try:
2300 code_name = self.compile.cache(usource, self.execution_count)
2307 code_name = self.compile.cache(usource, self.execution_count)
2301 code = self.compile(usource, code_name, symbol)
2308 code = self.compile(usource, code_name, symbol)
@@ -2315,7 +2322,7 b' class InteractiveShell(Configurable, Magic):'
2315 # buffer attribute as '\n'.join(self.buffer).
2322 # buffer attribute as '\n'.join(self.buffer).
2316 self.code_to_run = code
2323 self.code_to_run = code
2317 # now actually execute the code object
2324 # now actually execute the code object
2318 if self.run_code(code, post_execute) == 0:
2325 if self.run_code(code) == 0:
2319 return False
2326 return False
2320 else:
2327 else:
2321 return None
2328 return None
@@ -2323,7 +2330,7 b' class InteractiveShell(Configurable, Magic):'
2323 # For backwards compatibility
2330 # For backwards compatibility
2324 runsource = run_source
2331 runsource = run_source
2325
2332
2326 def run_code(self, code_obj, post_execute=True):
2333 def run_code(self, code_obj):
2327 """Execute a code object.
2334 """Execute a code object.
2328
2335
2329 When an exception occurs, self.showtraceback() is called to display a
2336 When an exception occurs, self.showtraceback() is called to display a
@@ -2366,22 +2373,6 b' class InteractiveShell(Configurable, Magic):'
2366 if softspace(sys.stdout, 0):
2373 if softspace(sys.stdout, 0):
2367 print
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 # Flush out code object which has been run (and source)
2376 # Flush out code object which has been run (and source)
2386 self.code_to_run = None
2377 self.code_to_run = None
2387 return outflag
2378 return outflag
General Comments 0
You need to be logged in to leave comments. Login now