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 = se |
|
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 |
|
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 |
|
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 |
|
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 |
|
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, |
|
2154 | except (OverflowError, SyntaxError, ValueError, TypeError, | |
2152 |
|
|
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 |
|
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 |
|
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 |
|
2374 | |||
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