##// END OF EJS Templates
Merge pull request #2179 from dopplershift/pylab-switch...
Fernando Perez -
r8027:6dac6929 merge
parent child Browse files
Show More
@@ -0,0 +1,108 b''
1 {
2 "metadata": {
3 "name": "Pylab Switching"
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
9 "cells": [
10 {
11 "cell_type": "code",
12 "collapsed": false,
13 "input": [
14 "# Should pop up a GUI window\n",
15 "%pylab qt\n",
16 "plot([1,2,3])"
17 ],
18 "language": "python",
19 "metadata": {},
20 "outputs": [
21 {
22 "output_type": "stream",
23 "stream": "stdout",
24 "text": [
25 "\n",
26 "Welcome to pylab, a matplotlib-based Python environment [backend: Qt4Agg].\n",
27 "For more information, type 'help(pylab)'.\n"
28 ]
29 },
30 {
31 "output_type": "pyout",
32 "prompt_number": 3,
33 "text": [
34 "[<matplotlib.lines.Line2D at 0x4566850>]"
35 ]
36 }
37 ],
38 "prompt_number": 3
39 },
40 {
41 "cell_type": "code",
42 "collapsed": false,
43 "input": [
44 "# Should make an inline figure\n",
45 "%pylab inline\n",
46 "plot([1,2,3])"
47 ],
48 "language": "python",
49 "metadata": {},
50 "outputs": [
51 {
52 "output_type": "stream",
53 "stream": "stdout",
54 "text": [
55 "\n",
56 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline].\n",
57 "For more information, type 'help(pylab)'.\n"
58 ]
59 },
60 {
61 "output_type": "pyout",
62 "prompt_number": 4,
63 "text": [
64 "[<matplotlib.lines.Line2D at 0x4830ad0>]"
65 ]
66 },
67 {
68 "output_type": "display_data",
69 "png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAD9CAYAAACoXlzKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAESVJREFUeJzt3V9oVFcCx/HftBHqGKvmwQQmWQqNLRk1mcRCWNA6IlJi\nawhV1sqmDZqHEFatr8WHqhUpKEikIPYlIj5Y0EIDTYQ+OIpKDGK6lPpgLIZMomQNEjDQ4qhnH7Jm\nZ8xk/t6ZuX++Hxhwck/nHi53j1+ON7M+Y4wRAMA13ij1BAAA1mJhBwCXYWEHAJdhYQcAl2FhBwCX\nYWEHAJdJubD/9ddfam5uVigUUjAY1FdffZV03P79+7Vq1So1NDRoeHi4IBMFAGSmLNXBt956S1eu\nXJHf79fz58+1fv16Xb9+XevXr58b09/fr/v372tkZES3bt1Sd3e3BgcHCz5xAEByabdi/H6/JOnZ\ns2d68eKFKioqEo739fWpo6NDktTc3Kzp6WlNTk4WYKoAgEykLHZJevnypZqamvTHH3+ou7tbwWAw\n4fjExIRqamrm3ldXV2t8fFyVlZVzP/P5fBZOGQC8I5cvB0hb7G+88YZ+/fVXjY+P69q1a4pEImlP\nnGwhN8bwsuD19ddfl3wObnpxPbmednv95z9G//iH0fvv5/5tLxk/FbNs2TJ9/PHHun37dsLPA4GA\notHo3Pvx8XEFAoGcJwQAXnXpklRfL/3tb1I+z6GkXNinpqY0PT0tSfrzzz/1yy+/qLGxMWFMa2ur\nzp07J0kaHBzU8uXLE7ZhAACpPX4s7dwpHTwo/fijdPy4tHhx7p+Xco/90aNH6ujo0MuXL/Xy5Ut9\n/vnn2rx5s86cOSNJ6urq0tatW9Xf36/a2lotWbJEvb29uc8GaYXD4VJPwVW4ntbiembv0iVp716p\nvV06eza/Bf0VnzGm4F/b6/P5VITTAIBjPH48u6D/+99Sb6/097/PH5Pr2slvngJAkb2+l55sUc9H\n2scdAQDWiK/0H3+0fkF/hWIHgCIodKXHo9gBoICKVenxKHYAKJBiVno8ih0ALFaKSo9HsQOAhUpV\n6fEodgCwQKkrPR7FDgB5skOlx6PYASBHdqr0eBQ7AOTAbpUej2IHgCzYtdLjUewAkCE7V3o8ih0A\n0nBCpcej2AEgBadUejyKHQCScFqlx6PYAeA1Tqz0eBQ7APyPkys9HsUOAHJ+pcej2AF4mlsqPR7F\nDsCz3FTp8Sh2AJ7jxkqPR7ED8BS3Vno8ih2AJ7i90uNR7ABczwuVHo9iB+BaXqr0eBQ7AFfyWqXH\no9gBuIpXKz0exQ7ANbxc6fEodgCOR6UnotgBOBqVPh/FDsCRqPSFUewAHIdKT41iB+AYVHpmKHYA\njkClZ45iB2BrVHr2KHYAtkWl54ZiB2A7VHp+KHYAtkKl549iB2ALVLp1KHYAJUelW4tiB1AyVHph\nUOwASoJKLxyKHUBRUemFR7EDKBoqvTgodgAFR6UXF8UOoKCo9OJLubBHo1Ft2rRJq1ev1po1a3Tq\n1Kl5YyKRiJYtW6bGxkY1Njbq6NGjBZssAOd4/FjauVM6eHC20o8flxYvLvWsvCHlVsyiRYt08uRJ\nhUIhzczMaN26ddqyZYvq6uoSxm3cuFF9fX0FnSgA57h0aXbrpb1dOnuWBb3YUi7sVVVVqqqqkiSV\nl5errq5ODx8+nLewG2PSnujQoUNzfw6HwwqHw9nPFoCtsZeen0gkokgkkvfn+Ewmq7Kk0dFRbdy4\nUb///rvKy8vnfn716lV9+umnqq6uViAQ0IkTJxQMBhNP4vNltPgDcK74Sj9yhEq3Qq5rZ0ZPxczM\nzGjHjh3q6elJWNQlqampSdFoVH6/XwMDA2pra9O9e/eynggAZ6LS7SftUzGxWEzbt29Xe3u72tra\n5h1funSp/H6/JKmlpUWxWExPnjyxfqYAbIcnXuwpZbEbY9TZ2algMKgDBw4kHTM5OamVK1fK5/Np\naGhIxhhVVFQUZLIA7IFKt7eUC/uNGzd0/vx51dfXq7GxUZJ07NgxjY2NSZK6urp08eJFnT59WmVl\nZfL7/bpw4ULhZw2gZHjixf4y/sfTvE7CP54Cjhdf6b29VHox5Lp28punANJiL91Z+K4YAAtiL92Z\nKHYASVHpzkWxA0hApTsfxQ5gDpXuDhQ7ACrdZSh2wOOodPeh2AGPotLdi2IHPIhKdzeKHfAQKt0b\nKHbAI6h076DYAZej0r2HYgdcjEr3JoodcCEq3dsodsBlqHRQ7IBLUOl4hWIHXIBKRzyKHXAwKh3J\nUOyAQ1HpWAjFDjgMlY50KHbAQah0ZIJiBxyASkc2KHbA5qh0ZItiB2yKSkeuKHbAhqh05INiB2yE\nSocVKHbAJqh0WIViB0qMSofVKHaghKh0FALFDpQAlY5CotiBIqPSUWgUO1AkVDqKhWIHioBKRzFR\n7EABUekoBYodKBAqHaVCsQMWo9JRahQ7YCEqHXZAsQMWoNJhJxQ7kCcqHXZDsQM5otJhVxQ7kAMq\nHXZGsQNZoNLhBBQ7kCEqHU5BsQNpUOlwGoodSIFKhxNR7EASVDqcLGWxR6NRbdq0SatXr9aaNWt0\n6tSppOP279+vVatWqaGhQcPDwwWZKFAsVDqcLmWxL1q0SCdPnlQoFNLMzIzWrVunLVu2qK6ubm5M\nf3+/7t+/r5GREd26dUvd3d0aHBws+MQBq1HpcIuUxV5VVaVQKCRJKi8vV11dnR4+fJgwpq+vTx0d\nHZKk5uZmTU9Pa3JyskDTBQqDSoebZLzHPjo6quHhYTU3Nyf8fGJiQjU1NXPvq6urNT4+rsrKyoRx\nhw4dmvtzOBxWOBzObcaAhaampH/9i0qHPUQiEUUikbw/J6OFfWZmRjt27FBPT4/Ky8vnHTfGJLz3\n+XzzxsQv7IAdXLo0u/Xyz39KZ89KixeXekbwutej9/Dhwzl9TtqFPRaLafv27Wpvb1dbW9u844FA\nQNFodO79+Pi4AoFATpMBioG9dLhdyj12Y4w6OzsVDAZ14MCBpGNaW1t17tw5SdLg4KCWL18+bxsG\nsAv20uEFPvP6Pkqc69ev68MPP1R9ff3c9sqxY8c0NjYmSerq6pIk7d27V5cvX9aSJUvU29urpqam\nxJP4fPO2a4Biiq/03l4WdDhDrmtnyoXdKizsKKVXe+nt7dKRI+ylwzlyXTv5zVO4Fnvp8Cq+Kwau\nxF46vIxih6tQ6QDFDheh0oFZFDscj0oHElHscDQqHZiPYocjUenAwih2OA6VDqRGscMxqHQgMxQ7\nHIFKBzJHscPWqHQgexQ7bItKB3JDscN2qHQgPxQ7bIVKB/JHscMWqHTAOhQ7So5KB6xFsaNkqHSg\nMCh2lASVDhQOxY6iotKBwqPYUTRUOlAcFDsKjkoHiotiR0FR6UDxUewoCCodKB2KHZaj0oHSothh\nGSodsAeKHZag0gH7oNiRFyodsB+KHTmj0gF7otiRNSodsDeKHVmh0gH7o9iRESodcA6KHWlR6YCz\nUOxYEJUOOBPFjqSodMC5KHYkoNIB56PYMYdKB9yBYgeVDrgMxe5xVDrgPhS7R1HpgHtR7B5EpQPu\nRrF7CJUOeAPF7hFUOuAdFLvLUemA91DsLkalA95EsbsQlQ54G8XuMlQ6AIrdJah0AK+kLPY9e/ao\nsrJSa9euTXo8Eolo2bJlamxsVGNjo44ePVqQSSI1Kh1AvJTFvnv3bu3bt09ffPHFgmM2btyovr4+\nyyeG9Kh0AMmkLPYNGzZoxYoVKT/AGGPphJAZKh3AQvLaY/f5fLp586YaGhoUCAR04sQJBYPBpGMP\nHTo09+dwOKxwOJzPqT2LSgfcKxKJKBKJ5P05PpMmuUdHR7Vt2zb99ttv8449ffpUb775pvx+vwYG\nBvTll1/q3r1780/i81H2Frh0aXZRb2+XjhyRFi8u9YwAFFKua2dejzsuXbpUfr9fktTS0qJYLKYn\nT57k85FI4vFjaedO6eDB2Uo/fpxFHcDC8lrYJycn5/42GRoakjFGFRUVlkwMs9hLB5CtlHvsu3bt\n0tWrVzU1NaWamhodPnxYsVhMktTV1aWLFy/q9OnTKisrk9/v14ULF4oyaS9gLx1ArtLusVtyEvbY\ns8JeOgAp97WT3zy1ESodgBX4rhibYC8dgFUo9hKj0gFYjWIvISodQCFQ7CVApQMoJIq9yKh0AIVG\nsRcJlQ6gWCj2IqDSARQTxV5AVDqAUqDYC4RKB1AqFLvFqHQApUaxW4hKB2AHFLsFqHQAdkKx54lK\nB2A3FHuOqHQAdkWx54BKB2BnFHsWqHQATkCxZ4hKB+AUFHsaVDoAp6HYU6DSATgRxZ4ElQ7AySj2\n11DpAJyOYv8fKh2AW1DsotIBuIuni51KB+BGni12Kh2AW3mu2Kl0AG7nqWKn0gF4gSeKnUoH4CWu\nL3YqHYDXuLbYqXQAXuXKYqfSAXiZq4qdSgcAFxU7lQ4Asxxf7FQ6ACRydLFT6QAwnyOLnUoHgIU5\nrtipdABIzTHFTqUDQGYcUexUOgBkztbFTqUDQPZsW+xUOgDkxnbFTqUDQH5sVexUOgDkzxbFTqUD\ngHVKXuxUOgBYq2QL++PH0s6d0sGDs5V+/Li0eHGpZuMckUik1FNwFa6ntbie9pByYd+zZ48qKyu1\ndu3aBcfs379fq1atUkNDg4aHhzM6KZWeO/6HYy2up7W4nvaQcmHfvXu3Ll++vODx/v5+3b9/XyMj\nI/r+++/V3d2d8mRUOgAUXsqFfcOGDVqxYsWCx/v6+tTR0SFJam5u1vT0tCYnJ5OOpdIBoEhMGg8e\nPDBr1qxJeuyTTz4xN27cmHu/efNmc/v27XnjJPHixYsXrxxeucj7ccfZdfv/fD5f2jEAgMLJ66mY\nQCCgaDQ69358fFyBQCDvSQEAcpfXwt7a2qpz585JkgYHB7V8+XJVVlZaMjEAQG5SbsXs2rVLV69e\n1dTUlGpqanT48GHFYjFJUldXl7Zu3ar+/n7V1tZqyZIl6u3tLcqkAQAp5LQzv4CBgQHz/vvvm9ra\nWvPtt98mHbNv3z5TW1tr6uvrzZ07d6w8veuku55Xrlwxb7/9tgmFQiYUCplvvvmmBLN0ht27d5uV\nK1cu+CCAMdybmUp3LbkvszM2NmbC4bAJBoNm9erVpqenJ+m4bO5Pyxb258+fm3fffdc8ePDAPHv2\nzDQ0NJi7d+8mjPn5559NS0uLMcaYwcFB09zcbNXpXSeT63nlyhWzbdu2Es3QWa5du2bu3Lmz4GLE\nvZm5dNeS+zI7jx49MsPDw8YYY54+fWree++9vNdOy75SYGhoSLW1tXrnnXe0aNEiffbZZ/rpp58S\nxmTz3LvXZXI9JZ44ypSVv5PhdemupcR9mY2qqiqFQiFJUnl5uerq6vTw4cOEMdnen5Yt7BMTE6qp\nqZl7X11drYmJibRjxsfHrZqCq2RyPX0+n27evKmGhgZt3bpVd+/eLfY0XYN70zrcl7kbHR3V8PCw\nmpubE36e7f1p2df2Jnt+PZnX/ybP9L/zmkyuS1NTk6LRqPx+vwYGBtTW1qZ79+4VYXbuxL1pDe7L\n3MzMzGjHjh3q6elReXn5vOPZ3J+WFfvrz7RHo1FVV1enHMNz7wvL5HouXbpUfr9fktTS0qJYLKYn\nT54UdZ5uwb1pHe7L7MViMW3fvl3t7e1qa2ubdzzb+9Oyhf2DDz7QyMiIRkdH9ezZM/3www9qbW1N\nGMNz75nL5HpOTk7O/S0+NDQkY4wqKipKMV3H4960Dvdldowx6uzsVDAY1IEDB5KOyfb+tGwrpqys\nTN99950++ugjvXjxQp2dnaqrq9OZM2ck8dx7tjK5nhcvXtTp06dVVlYmv9+vCxculHjW9sXvZFgn\n3bXkvszOjRs3dP78edXX16uxsVGSdOzYMY2NjUnK7f70Gf75GgBcpeT/13gAAGuxsAOAy7CwA4DL\nsLADgMuwsAOAy7CwA4DL/BdtJN59CWl7cgAAAABJRU5ErkJggg==\n"
70 }
71 ],
72 "prompt_number": 4
73 },
74 {
75 "cell_type": "code",
76 "collapsed": false,
77 "input": [
78 "# New GUI window--should *NOT* have the visual settings of inline\n",
79 "%pylab qt\n",
80 "plot([1,2,3])"
81 ],
82 "language": "python",
83 "metadata": {},
84 "outputs": [
85 {
86 "output_type": "stream",
87 "stream": "stdout",
88 "text": [
89 "\n",
90 "Welcome to pylab, a matplotlib-based Python environment [backend: Qt4Agg].\n",
91 "For more information, type 'help(pylab)'.\n"
92 ]
93 },
94 {
95 "output_type": "pyout",
96 "prompt_number": 11,
97 "text": [
98 "[<matplotlib.lines.Line2D at 0x5253850>]"
99 ]
100 }
101 ],
102 "prompt_number": 11
103 }
104 ],
105 "metadata": {}
106 }
107 ]
108 } No newline at end of file
@@ -423,6 +423,9 b' class InteractiveShell(SingletonConfigurable):'
423 # Private interface
423 # Private interface
424 _post_execute = Instance(dict)
424 _post_execute = Instance(dict)
425
425
426 # Tracks any GUI loop loaded for pylab
427 pylab_gui_select = None
428
426 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
429 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
427 user_module=None, user_ns=None,
430 user_module=None, user_ns=None,
428 custom_exceptions=((), None)):
431 custom_exceptions=((), None)):
@@ -174,13 +174,16 b' def select_figure_format(shell, fmt):'
174 #-----------------------------------------------------------------------------
174 #-----------------------------------------------------------------------------
175
175
176
176
177 def find_gui_and_backend(gui=None):
177 def find_gui_and_backend(gui=None, gui_select=None):
178 """Given a gui string return the gui and mpl backend.
178 """Given a gui string return the gui and mpl backend.
179
179
180 Parameters
180 Parameters
181 ----------
181 ----------
182 gui : str
182 gui : str
183 Can be one of ('tk','gtk','wx','qt','qt4','inline').
183 Can be one of ('tk','gtk','wx','qt','qt4','inline').
184 gui_select : str
185 Can be one of ('tk','gtk','wx','qt','qt4','inline').
186 This is any gui already selected by the shell.
184
187
185 Returns
188 Returns
186 -------
189 -------
@@ -198,6 +201,13 b' def find_gui_and_backend(gui=None):'
198 # In this case, we need to find what the appropriate gui selection call
201 # In this case, we need to find what the appropriate gui selection call
199 # should be for IPython, so we can activate inputhook accordingly
202 # should be for IPython, so we can activate inputhook accordingly
200 gui = backend2gui.get(backend, None)
203 gui = backend2gui.get(backend, None)
204
205 # If we have already had a gui active, we need it and inline are the
206 # ones allowed.
207 if gui_select and gui != gui_select:
208 gui = gui_select
209 backend = backends[gui]
210
201 return gui, backend
211 return gui, backend
202
212
203
213
@@ -205,23 +215,20 b' def activate_matplotlib(backend):'
205 """Activate the given backend and set interactive to True."""
215 """Activate the given backend and set interactive to True."""
206
216
207 import matplotlib
217 import matplotlib
208 if backend.startswith('module://'):
209 # Work around bug in matplotlib: matplotlib.use converts the
210 # backend_id to lowercase even if a module name is specified!
211 matplotlib.rcParams['backend'] = backend
212 else:
213 matplotlib.use(backend)
214 matplotlib.interactive(True)
218 matplotlib.interactive(True)
215
219
220 # Matplotlib had a bug where even switch_backend could not force
221 # the rcParam to update. This needs to be set *before* the module
222 # magic of switch_backend().
223 matplotlib.rcParams['backend'] = backend
224
225 import matplotlib.pyplot
226 matplotlib.pyplot.switch_backend(backend)
227
216 # This must be imported last in the matplotlib series, after
228 # This must be imported last in the matplotlib series, after
217 # backend/interactivity choices have been made
229 # backend/interactivity choices have been made
218 import matplotlib.pylab as pylab
230 import matplotlib.pylab as pylab
219
231
220 # XXX For now leave this commented out, but depending on discussions with
221 # mpl-dev, we may be able to allow interactive switching...
222 #import matplotlib.pyplot
223 #matplotlib.pyplot.switch_backend(backend)
224
225 pylab.show._needmain = False
232 pylab.show._needmain = False
226 # We need to detect at runtime whether show() is called by the user.
233 # We need to detect at runtime whether show() is called by the user.
227 # For this, we wrap it into a decorator which adds a 'called' flag.
234 # For this, we wrap it into a decorator which adds a 'called' flag.
@@ -272,6 +279,7 b' def configure_inline_support(shell, backend, user_ns=None):'
272 from IPython.zmq.pylab.backend_inline import InlineBackend
279 from IPython.zmq.pylab.backend_inline import InlineBackend
273 except ImportError:
280 except ImportError:
274 return
281 return
282 from matplotlib import pyplot
275
283
276 user_ns = shell.user_ns if user_ns is None else user_ns
284 user_ns = shell.user_ns if user_ns is None else user_ns
277
285
@@ -282,12 +290,23 b' def configure_inline_support(shell, backend, user_ns=None):'
282
290
283 if backend == backends['inline']:
291 if backend == backends['inline']:
284 from IPython.zmq.pylab.backend_inline import flush_figures
292 from IPython.zmq.pylab.backend_inline import flush_figures
285 from matplotlib import pyplot
286 shell.register_post_execute(flush_figures)
293 shell.register_post_execute(flush_figures)
294
295 # Save rcParams that will be overwrittern
296 shell._saved_rcParams = dict()
297 for k in cfg.rc:
298 shell._saved_rcParams[k] = pyplot.rcParams[k]
287 # load inline_rc
299 # load inline_rc
288 pyplot.rcParams.update(cfg.rc)
300 pyplot.rcParams.update(cfg.rc)
289 # Add 'figsize' to pyplot and to the user's namespace
301 # Add 'figsize' to pyplot and to the user's namespace
290 user_ns['figsize'] = pyplot.figsize = figsize
302 user_ns['figsize'] = pyplot.figsize = figsize
303 else:
304 from IPython.zmq.pylab.backend_inline import flush_figures
305 if flush_figures in shell._post_execute:
306 shell._post_execute.pop(flush_figures)
307 if hasattr(shell, '_saved_rcParams'):
308 pyplot.rcParams.update(shell._saved_rcParams)
309 del shell._saved_rcParams
291
310
292 # Setup the default figure format
311 # Setup the default figure format
293 fmt = cfg.figure_format
312 fmt = cfg.figure_format
@@ -321,7 +340,18 b' def pylab_activate(user_ns, gui=None, import_all=True, shell=None):'
321 The actual gui used (if not given as input, it was obtained from matplotlib
340 The actual gui used (if not given as input, it was obtained from matplotlib
322 itself, and will be needed next to configure IPython's gui integration.
341 itself, and will be needed next to configure IPython's gui integration.
323 """
342 """
324 gui, backend = find_gui_and_backend(gui)
343 pylab_gui_select = shell.pylab_gui_select if shell is not None else None
344 # Try to find the appropriate gui and backend for the settings
345 gui, backend = find_gui_and_backend(gui, pylab_gui_select)
346 if shell is not None and gui != 'inline':
347 # If we have our first gui selection, store it
348 if pylab_gui_select is None:
349 shell.pylab_gui_select = gui
350 # Otherwise if they are different
351 elif gui != pylab_gui_select:
352 print ('Warning: Cannot change to a different GUI toolkit: %s.'
353 ' Using %s instead.' % (gui, pylab_gui_select))
354 gui, backend = find_gui_and_backend(pylab_gui_select)
325 activate_matplotlib(backend)
355 activate_matplotlib(backend)
326 import_pylab(user_ns, import_all)
356 import_pylab(user_ns, import_all)
327 if shell is not None:
357 if shell is not None:
@@ -61,3 +61,79 b' def test_import_pylab():'
61 pt.import_pylab(ns, import_all=False)
61 pt.import_pylab(ns, import_all=False)
62 nt.assert_true('plt' in ns)
62 nt.assert_true('plt' in ns)
63 nt.assert_equal(ns['np'], np)
63 nt.assert_equal(ns['np'], np)
64
65
66 class TestPylabSwitch(object):
67 class Shell(object):
68 pylab_gui_select = None
69
70 def setup(self):
71 import matplotlib
72 def act_mpl(backend):
73 matplotlib.rcParams['backend'] = backend
74
75 # Save rcParams since they get modified
76 self._saved_rcParams = matplotlib.rcParams
77 matplotlib.rcParams = dict(backend='Qt4Agg')
78
79 # Mock out functions
80 self._save_am = pt.activate_matplotlib
81 pt.activate_matplotlib = act_mpl
82 self._save_ip = pt.import_pylab
83 pt.import_pylab = lambda *a,**kw:None
84 self._save_cis = pt.configure_inline_support
85 pt.configure_inline_support = lambda *a,**kw:None
86
87 def teardown(self):
88 pt.activate_matplotlib = self._save_am
89 pt.import_pylab = self._save_ip
90 pt.configure_inline_support = self._save_cis
91 import matplotlib
92 matplotlib.rcParams = self._saved_rcParams
93
94 def test_qt(self):
95 s = self.Shell()
96 gui = pt.pylab_activate(dict(), None, False, s)
97 nt.assert_equal(gui, 'qt')
98 nt.assert_equal(s.pylab_gui_select, 'qt')
99
100 gui = pt.pylab_activate(dict(), 'inline', False, s)
101 nt.assert_equal(gui, 'inline')
102 nt.assert_equal(s.pylab_gui_select, 'qt')
103
104 gui = pt.pylab_activate(dict(), 'qt', False, s)
105 nt.assert_equal(gui, 'qt')
106 nt.assert_equal(s.pylab_gui_select, 'qt')
107
108 gui = pt.pylab_activate(dict(), 'inline', False, s)
109 nt.assert_equal(gui, 'inline')
110 nt.assert_equal(s.pylab_gui_select, 'qt')
111
112 gui = pt.pylab_activate(dict(), None, False, s)
113 nt.assert_equal(gui, 'qt')
114 nt.assert_equal(s.pylab_gui_select, 'qt')
115
116 def test_inline(self):
117 s = self.Shell()
118 gui = pt.pylab_activate(dict(), 'inline', False, s)
119 nt.assert_equal(gui, 'inline')
120 nt.assert_equal(s.pylab_gui_select, None)
121
122 gui = pt.pylab_activate(dict(), 'inline', False, s)
123 nt.assert_equal(gui, 'inline')
124 nt.assert_equal(s.pylab_gui_select, None)
125
126 gui = pt.pylab_activate(dict(), 'qt', False, s)
127 nt.assert_equal(gui, 'qt')
128 nt.assert_equal(s.pylab_gui_select, 'qt')
129
130 def test_qt_gtk(self):
131 s = self.Shell()
132 gui = pt.pylab_activate(dict(), 'qt', False, s)
133 nt.assert_equal(gui, 'qt')
134 nt.assert_equal(s.pylab_gui_select, 'qt')
135
136 gui = pt.pylab_activate(dict(), 'gtk', False, s)
137 nt.assert_equal(gui, 'qt')
138 nt.assert_equal(s.pylab_gui_select, 'qt')
139
@@ -218,6 +218,6 b' def enable_gui(gui, kernel=None):'
218 " and no IPython Application with a kernel appears to be running."
218 " and no IPython Application with a kernel appears to be running."
219 )
219 )
220 loop = loop_map[gui]
220 loop = loop_map[gui]
221 if kernel.eventloop is not None and kernel.eventloop is not loop:
221 if loop and kernel.eventloop is not None and kernel.eventloop is not loop:
222 raise RuntimeError("Cannot activate multiple GUI eventloops")
222 raise RuntimeError("Cannot activate multiple GUI eventloops")
223 kernel.eventloop = loop
223 kernel.eventloop = loop
@@ -254,8 +254,6 b' class Kernel(Configurable):'
254 self.eventloop = None
254 self.eventloop = None
255 break
255 break
256 self.log.info("exiting eventloop")
256 self.log.info("exiting eventloop")
257 # if eventloop exits, IOLoop should stop
258 ioloop.IOLoop.instance().stop()
259
257
260 def start(self):
258 def start(self):
261 """register dispatchers for streams"""
259 """register dispatchers for streams"""
General Comments 0
You need to be logged in to leave comments. Login now