##// END OF EJS Templates
Merge pull request #1155 from minrk/postexec...
Fernando Perez -
r5737:2c683b72 merge
parent child Browse files
Show More
@@ -261,6 +261,9 b' class InteractiveShell(SingletonConfigurable, Magic):'
261 deep_reload will still be available as dreload().
261 deep_reload will still be available as dreload().
262 """
262 """
263 )
263 )
264 disable_failing_post_execute = CBool(False, config=True,
265 help="Don't call post-execute functions that have failed in the past."""
266 )
264 display_formatter = Instance(DisplayFormatter)
267 display_formatter = Instance(DisplayFormatter)
265 displayhook_class = Type(DisplayHook)
268 displayhook_class = Type(DisplayHook)
266 display_pub_class = Type(DisplayPublisher)
269 display_pub_class = Type(DisplayPublisher)
@@ -749,7 +752,7 b' class InteractiveShell(SingletonConfigurable, Magic):'
749 if not callable(func):
752 if not callable(func):
750 raise ValueError('argument %s must be callable' % func)
753 raise ValueError('argument %s must be callable' % func)
751 self._post_execute[func] = True
754 self._post_execute[func] = True
752
755
753 #-------------------------------------------------------------------------
756 #-------------------------------------------------------------------------
754 # Things related to the "main" module
757 # Things related to the "main" module
755 #-------------------------------------------------------------------------
758 #-------------------------------------------------------------------------
@@ -2426,17 +2429,22 b' class InteractiveShell(SingletonConfigurable, Magic):'
2426
2429
2427 # Execute any registered post-execution functions.
2430 # Execute any registered post-execution functions.
2428 for func, status in self._post_execute.iteritems():
2431 for func, status in self._post_execute.iteritems():
2429 if not status:
2432 if self.disable_failing_post_execute and not status:
2430 continue
2433 continue
2431 try:
2434 try:
2432 func()
2435 func()
2433 except KeyboardInterrupt:
2436 except KeyboardInterrupt:
2434 print >> io.stderr, "\nKeyboardInterrupt"
2437 print >> io.stderr, "\nKeyboardInterrupt"
2435 except Exception:
2438 except Exception:
2436 print >> io.stderr, "Disabling failed post-execution function: %s" % func
2439 # register as failing:
2437 self.showtraceback()
2438 # Deactivate failing function
2439 self._post_execute[func] = False
2440 self._post_execute[func] = False
2441 self.showtraceback()
2442 print >> io.stderr, '\n'.join([
2443 "post-execution function %r produced an error." % func,
2444 "If this problem persists, you can disable failing post-exec functions with:",
2445 "",
2446 " get_ipython().disable_failing_post_execute = True"
2447 ])
2440
2448
2441 if store_history:
2449 if store_history:
2442 # Write output to the database. Does nothing unless
2450 # Write output to the database. Does nothing unless
@@ -140,19 +140,43 b' def flush_figures():'
140
140
141 This is meant to be called automatically and will call show() if, during
141 This is meant to be called automatically and will call show() if, during
142 prior code execution, there had been any calls to draw_if_interactive.
142 prior code execution, there had been any calls to draw_if_interactive.
143
144 This function is meant to be used as a post_execute callback in IPython,
145 so user-caused errors are handled with showtraceback() instead of being
146 allowed to raise. If this function is not called from within IPython,
147 then these exceptions will raise.
143 """
148 """
144 if not show._draw_called:
149 if not show._draw_called:
145 return
150 return
146
151
147 if InlineBackend.instance().close_figures:
152 if InlineBackend.instance().close_figures:
148 # ignore the tracking, just draw and close all figures
153 # ignore the tracking, just draw and close all figures
149 return show(True)
154 try:
150
155 return show(True)
156 except Exception as e:
157 # safely show traceback if in IPython, else raise
158 try:
159 get_ipython
160 except NameError:
161 raise e
162 else:
163 get_ipython().showtraceback()
164 return
151 try:
165 try:
152 # exclude any figures that were closed:
166 # exclude any figures that were closed:
153 active = set([fm.canvas.figure for fm in Gcf.get_all_fig_managers()])
167 active = set([fm.canvas.figure for fm in Gcf.get_all_fig_managers()])
154 for fig in [ fig for fig in show._to_draw if fig in active ]:
168 for fig in [ fig for fig in show._to_draw if fig in active ]:
155 send_figure(fig)
169 try:
170 send_figure(fig)
171 except Exception as e:
172 # safely show traceback if in IPython, else raise
173 try:
174 get_ipython
175 except NameError:
176 raise e
177 else:
178 get_ipython().showtraceback()
179 break
156 finally:
180 finally:
157 # clear flags for next round
181 # clear flags for next round
158 show._to_draw = []
182 show._to_draw = []
@@ -162,12 +186,11 b' def flush_figures():'
162 def send_figure(fig):
186 def send_figure(fig):
163 """Draw the current figure and send it as a PNG payload.
187 """Draw the current figure and send it as a PNG payload.
164 """
188 """
165 # For an empty figure, don't even bother calling figure_to_svg, to avoid
166 # big blank spaces in the qt console
167 if not fig.axes:
168 return
169 fmt = InlineBackend.instance().figure_format
189 fmt = InlineBackend.instance().figure_format
170 data = print_figure(fig, fmt)
190 data = print_figure(fig, fmt)
191 # print_figure will return None if there's nothing to draw:
192 if data is None:
193 return
171 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
194 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
172 mime = mimetypes[fmt]
195 mime = mimetypes[fmt]
173 # flush text streams before sending figures, helps a little with output
196 # flush text streams before sending figures, helps a little with output
General Comments 0
You need to be logged in to leave comments. Login now