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