Show More
@@ -0,0 +1,146 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | """Pylab (matplotlib) support utilities. | |||
|
3 | ||||
|
4 | Authors | |||
|
5 | ------- | |||
|
6 | Fernando Perez. | |||
|
7 | """ | |||
|
8 | ||||
|
9 | #----------------------------------------------------------------------------- | |||
|
10 | # Copyright (C) 2009 The IPython Development Team | |||
|
11 | # | |||
|
12 | # Distributed under the terms of the BSD License. The full license is in | |||
|
13 | # the file COPYING, distributed as part of this software. | |||
|
14 | #----------------------------------------------------------------------------- | |||
|
15 | #----------------------------------------------------------------------------- | |||
|
16 | # Imports | |||
|
17 | #----------------------------------------------------------------------------- | |||
|
18 | from IPython.utils.genutils import flag_calls | |||
|
19 | ||||
|
20 | #----------------------------------------------------------------------------- | |||
|
21 | # Main classes and functions | |||
|
22 | #----------------------------------------------------------------------------- | |||
|
23 | ||||
|
24 | def pylab_activate(user_ns, gui=None, import_all=True): | |||
|
25 | """Activate pylab mode in the user's namespace. | |||
|
26 | ||||
|
27 | Loads and initializes numpy, matplotlib and friends for interactive use. | |||
|
28 | ||||
|
29 | Parameters | |||
|
30 | ---------- | |||
|
31 | user_ns : dict | |||
|
32 | Namespace where the imports will occur. | |||
|
33 | ||||
|
34 | gui : optional, string | |||
|
35 | A valid gui name following the conventions of the %gui magic. | |||
|
36 | ||||
|
37 | import_all : optional, boolean | |||
|
38 | If true, an 'import *' is done from numpy and pylab. | |||
|
39 | ||||
|
40 | Returns | |||
|
41 | ------- | |||
|
42 | The actual gui used (if not given as input, it was obtained from matplotlib | |||
|
43 | itself, and will be needed next to configure IPython's gui integration. | |||
|
44 | """ | |||
|
45 | ||||
|
46 | # Initialize matplotlib to interactive mode always | |||
|
47 | import matplotlib | |||
|
48 | ||||
|
49 | # If user specifies a GUI, that dictates the backend, otherwise we read the | |||
|
50 | # user's mpl default from the mpl rc structure | |||
|
51 | g2b = {'tk': 'TkAgg', | |||
|
52 | 'gtk': 'GTKAgg', | |||
|
53 | 'wx': 'WXAgg', | |||
|
54 | 'qt': 'Qt4Agg', # qt3 not supported | |||
|
55 | 'qt4': 'Qt4Agg' } | |||
|
56 | ||||
|
57 | if gui: | |||
|
58 | # select backend based on requested gui | |||
|
59 | backend = g2b[gui] | |||
|
60 | else: | |||
|
61 | backend = matplotlib.rcParams['backend'] | |||
|
62 | # In this case, we need to find what the appropriate gui selection call | |||
|
63 | # should be for IPython, so we can activate inputhook accordingly | |||
|
64 | b2g = dict(zip(g2b.values(),g2b.keys())) | |||
|
65 | gui = b2g[backend] | |||
|
66 | ||||
|
67 | # We must set the desired backend before importing pylab | |||
|
68 | matplotlib.use(backend) | |||
|
69 | ||||
|
70 | # This must be imported last in the matplotlib series, after | |||
|
71 | # backend/interactivity choices have been made | |||
|
72 | import matplotlib.pylab as pylab | |||
|
73 | ||||
|
74 | # XXX For now leave this commented out, but depending on discussions with | |||
|
75 | # mpl-dev, we may be able to allow interactive switching... | |||
|
76 | #import matplotlib.pyplot | |||
|
77 | #matplotlib.pyplot.switch_backend(backend) | |||
|
78 | ||||
|
79 | pylab.show._needmain = False | |||
|
80 | # We need to detect at runtime whether show() is called by the user. | |||
|
81 | # For this, we wrap it into a decorator which adds a 'called' flag. | |||
|
82 | pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) | |||
|
83 | ||||
|
84 | # Import numpy as np/pyplot as plt are conventions we're trying to | |||
|
85 | # somewhat standardize on. Making them available to users by default | |||
|
86 | # will greatly help this. | |||
|
87 | exec ("import numpy\n" | |||
|
88 | "import matplotlib\n" | |||
|
89 | "from matplotlib import pylab, mlab, pyplot\n" | |||
|
90 | "np = numpy\n" | |||
|
91 | "plt = pyplot\n" | |||
|
92 | ) in user_ns | |||
|
93 | ||||
|
94 | if import_all: | |||
|
95 | exec("from matplotlib.pylab import *\n" | |||
|
96 | "from numpy import *\n") in user_ns | |||
|
97 | ||||
|
98 | matplotlib.interactive(True) | |||
|
99 | ||||
|
100 | print """ | |||
|
101 | Welcome to pylab, a matplotlib-based Python environment. | |||
|
102 | Backend in use: %s | |||
|
103 | For more information, type 'help(pylab)'.""" % backend | |||
|
104 | ||||
|
105 | return gui | |||
|
106 | ||||
|
107 | # We need a little factory function here to create the closure where | |||
|
108 | # safe_execfile can live. | |||
|
109 | def mpl_runner(safe_execfile): | |||
|
110 | """Factory to return a matplotlib-enabled runner for %run. | |||
|
111 | ||||
|
112 | Parameters | |||
|
113 | ---------- | |||
|
114 | safe_execfile : function | |||
|
115 | This must be a function with the same interface as the | |||
|
116 | :meth:`safe_execfile` method of IPython. | |||
|
117 | ||||
|
118 | Returns | |||
|
119 | ------- | |||
|
120 | A function suitable for use as the ``runner`` argument of the %run magic | |||
|
121 | function. | |||
|
122 | """ | |||
|
123 | ||||
|
124 | def mpl_execfile(fname,*where,**kw): | |||
|
125 | """matplotlib-aware wrapper around safe_execfile. | |||
|
126 | ||||
|
127 | Its interface is identical to that of the :func:`execfile` builtin. | |||
|
128 | ||||
|
129 | This is ultimately a call to execfile(), but wrapped in safeties to | |||
|
130 | properly handle interactive rendering.""" | |||
|
131 | ||||
|
132 | import matplotlib | |||
|
133 | import matplotlib.pylab as pylab | |||
|
134 | ||||
|
135 | #print '*** Matplotlib runner ***' # dbg | |||
|
136 | # turn off rendering until end of script | |||
|
137 | is_interactive = matplotlib.rcParams['interactive'] | |||
|
138 | matplotlib.interactive(False) | |||
|
139 | safe_execfile(fname,*where,**kw) | |||
|
140 | matplotlib.interactive(is_interactive) | |||
|
141 | # make rendering call now, if the user tried to do it | |||
|
142 | if pylab.draw_if_interactive.called: | |||
|
143 | pylab.draw() | |||
|
144 | pylab.draw_if_interactive.called = False | |||
|
145 | ||||
|
146 | return mpl_execfile |
@@ -27,53 +27,30 b' Notes' | |||||
27 | import logging |
|
27 | import logging | |
28 | import os |
|
28 | import os | |
29 | import sys |
|
29 | import sys | |
30 | import warnings |
|
|||
31 |
|
30 | |||
32 | from IPython.core.application import Application, BaseAppArgParseConfigLoader |
|
|||
33 | from IPython.core import release |
|
31 | from IPython.core import release | |
|
32 | from IPython.core.application import Application, BaseAppArgParseConfigLoader | |||
|
33 | from IPython.core.error import UsageError | |||
34 | from IPython.core.iplib import InteractiveShell |
|
34 | from IPython.core.iplib import InteractiveShell | |
|
35 | from IPython.core.pylabtools import pylab_activate | |||
35 | from IPython.config.loader import ( |
|
36 | from IPython.config.loader import ( | |
36 | NoConfigDefault, |
|
37 | NoConfigDefault, | |
37 | Config, |
|
38 | Config, | |
38 | PyFileConfigLoader |
|
39 | PyFileConfigLoader | |
39 | ) |
|
40 | ) | |
40 |
|
||||
41 | from IPython.lib import inputhook |
|
41 | from IPython.lib import inputhook | |
42 |
|
||||
43 | from IPython.utils.genutils import filefind, get_ipython_dir |
|
42 | from IPython.utils.genutils import filefind, get_ipython_dir | |
44 |
|
43 | |||
45 | #----------------------------------------------------------------------------- |
|
44 | #----------------------------------------------------------------------------- | |
46 | # Utilities and helpers |
|
45 | # Utilities and helpers | |
47 | #----------------------------------------------------------------------------- |
|
46 | #----------------------------------------------------------------------------- | |
48 |
|
47 | |||
49 |
|
||||
50 | ipython_desc = """ |
|
48 | ipython_desc = """ | |
51 | A Python shell with automatic history (input and output), dynamic object |
|
49 | A Python shell with automatic history (input and output), dynamic object | |
52 | introspection, easier configuration, command completion, access to the system |
|
50 | introspection, easier configuration, command completion, access to the system | |
53 | shell and more. |
|
51 | shell and more. | |
54 | """ |
|
52 | """ | |
55 |
|
53 | |||
56 | def pylab_warning(): |
|
|||
57 | msg = """ |
|
|||
58 |
|
||||
59 | IPython's -pylab mode has been disabled until matplotlib supports this version |
|
|||
60 | of IPython. This version of IPython has greatly improved GUI integration that |
|
|||
61 | matplotlib will soon be able to take advantage of. This will eventually |
|
|||
62 | result in greater stability and a richer API for matplotlib under IPython. |
|
|||
63 | However during this transition, you will either need to use an older version |
|
|||
64 | of IPython, or do the following to use matplotlib interactively:: |
|
|||
65 |
|
||||
66 | import matplotlib |
|
|||
67 | matplotlib.interactive(True) |
|
|||
68 | matplotlib.use('wxagg') # adjust for your backend |
|
|||
69 | %gui -a wx # adjust for your GUI |
|
|||
70 | from matplotlib import pyplot as plt |
|
|||
71 |
|
||||
72 | See the %gui magic for information on the new interface. |
|
|||
73 | """ |
|
|||
74 | warnings.warn(msg, category=DeprecationWarning, stacklevel=1) |
|
|||
75 |
|
||||
76 |
|
||||
77 | #----------------------------------------------------------------------------- |
|
54 | #----------------------------------------------------------------------------- | |
78 | # Main classes and functions |
|
55 | # Main classes and functions | |
79 | #----------------------------------------------------------------------------- |
|
56 | #----------------------------------------------------------------------------- | |
@@ -267,23 +244,21 b' cl_args = (' | |||||
267 | action='store_true', dest='Global.force_interact', default=NoConfigDefault, |
|
244 | action='store_true', dest='Global.force_interact', default=NoConfigDefault, | |
268 | help="If running code from the command line, become interactive afterwards.") |
|
245 | help="If running code from the command line, become interactive afterwards.") | |
269 | ), |
|
246 | ), | |
270 | (('--wthread',), dict( |
|
247 | (('--wthread','-wthread'), dict( | |
271 | action='store_true', dest='Global.wthread', default=NoConfigDefault, |
|
248 | action='store_true', dest='Global.wthread', default=NoConfigDefault, | |
272 | help="Enable wxPython event loop integration.") |
|
249 | help="Enable wxPython event loop integration.") | |
273 | ), |
|
250 | ), | |
274 | (('--q4thread','--qthread'), dict( |
|
251 | (('--q4thread','--qthread','-q4thread','-qthread'), dict( | |
275 | action='store_true', dest='Global.q4thread', default=NoConfigDefault, |
|
252 | action='store_true', dest='Global.q4thread', default=NoConfigDefault, | |
276 | help="Enable Qt4 event loop integration. Qt3 is no longer supported.") |
|
253 | help="Enable Qt4 event loop integration. Qt3 is no longer supported.") | |
277 | ), |
|
254 | ), | |
278 | (('--gthread',), dict( |
|
255 | (('--gthread','-gthread'), dict( | |
279 | action='store_true', dest='Global.gthread', default=NoConfigDefault, |
|
256 | action='store_true', dest='Global.gthread', default=NoConfigDefault, | |
280 | help="Enable GTK event loop integration.") |
|
257 | help="Enable GTK event loop integration.") | |
281 | ), |
|
258 | ), | |
282 | # # These are only here to get the proper deprecation warnings |
|
|||
283 | (('--pylab',), dict( |
|
259 | (('--pylab',), dict( | |
284 | action='store_true', dest='Global.pylab', default=NoConfigDefault, |
|
260 | action='store_true', dest='Global.pylab', default=NoConfigDefault, | |
285 | help="Disabled. Pylab has been disabled until matplotlib " |
|
261 | help="Pre-load matplotlib and numpy for interactive use.") | |
286 | "supports this version of IPython.") |
|
|||
287 | ) |
|
262 | ) | |
288 | ) |
|
263 | ) | |
289 |
|
264 | |||
@@ -341,6 +316,9 b' class IPythonApp(Application):' | |||||
341 | Global.q4thread = False |
|
316 | Global.q4thread = False | |
342 | Global.gthread = False |
|
317 | Global.gthread = False | |
343 |
|
318 | |||
|
319 | # Pylab off by default | |||
|
320 | Global.pylab = False | |||
|
321 | ||||
344 | def create_command_line_config(self): |
|
322 | def create_command_line_config(self): | |
345 | """Create and return a command line config loader.""" |
|
323 | """Create and return a command line config loader.""" | |
346 | return IPythonAppCLConfigLoader( |
|
324 | return IPythonAppCLConfigLoader( | |
@@ -348,14 +326,6 b' class IPythonApp(Application):' | |||||
348 | version=release.version |
|
326 | version=release.version | |
349 | ) |
|
327 | ) | |
350 |
|
328 | |||
351 | def post_load_command_line_config(self): |
|
|||
352 | """Do actions after loading cl config.""" |
|
|||
353 | clc = self.command_line_config |
|
|||
354 |
|
||||
355 | # Display the deprecation warnings about threaded shells |
|
|||
356 | if hasattr(clc.Global, 'pylab'): |
|
|||
357 | pylab_warning() |
|
|||
358 | del clc.Global['pylab'] |
|
|||
359 |
|
329 | |||
360 | def load_file_config(self): |
|
330 | def load_file_config(self): | |
361 | if hasattr(self.command_line_config.Global, 'quick'): |
|
331 | if hasattr(self.command_line_config.Global, 'quick'): | |
@@ -433,29 +403,43 b' class IPythonApp(Application):' | |||||
433 | if self.log_level <= logging.INFO: print |
|
403 | if self.log_level <= logging.INFO: print | |
434 |
|
404 | |||
435 | # Now a variety of things that happen after the banner is printed. |
|
405 | # Now a variety of things that happen after the banner is printed. | |
436 | self._enable_gui() |
|
406 | self._enable_gui_pylab() | |
437 | self._load_extensions() |
|
407 | self._load_extensions() | |
438 | self._run_exec_lines() |
|
408 | self._run_exec_lines() | |
439 | self._run_exec_files() |
|
409 | self._run_exec_files() | |
440 | self._run_cmd_line_code() |
|
410 | self._run_cmd_line_code() | |
|
411 | self._configure_xmode() | |||
|
412 | ||||
|
413 | def _enable_gui_pylab(self): | |||
|
414 | """Enable GUI event loop integration, taking pylab into account.""" | |||
|
415 | Global = self.master_config.Global | |||
|
416 | ||||
|
417 | # Select which gui to use | |||
|
418 | if Global.wthread: | |||
|
419 | gui = inputhook.GUI_WX | |||
|
420 | elif Global.q4thread: | |||
|
421 | gui = inputhook.GUI_QT | |||
|
422 | elif Global.gthread: | |||
|
423 | gui = inputhook.GUI_GTK | |||
|
424 | else: | |||
|
425 | gui = None | |||
|
426 | ||||
|
427 | if Global.pylab: | |||
|
428 | activate = self.shell.enable_pylab | |||
|
429 | else: | |||
|
430 | # Enable only GUI integration, no pylab | |||
|
431 | activate = inputhook.enable_gui | |||
|
432 | ||||
|
433 | if gui or Global.pylab: | |||
|
434 | try: | |||
|
435 | m = "Enabling GUI event loop integration, toolkit=%s, pylab=%s"\ | |||
|
436 | % (gui, Global.pylab) | |||
|
437 | self.log.info(m) | |||
|
438 | activate(gui) | |||
|
439 | except: | |||
|
440 | self.log.warn("Error in enabling GUI event loop integration:") | |||
|
441 | self.shell.showtraceback() | |||
441 |
|
442 | |||
442 | def _enable_gui(self): |
|
|||
443 | """Enable GUI event loop integration.""" |
|
|||
444 | config = self.master_config |
|
|||
445 | try: |
|
|||
446 | # Enable GUI integration |
|
|||
447 | if config.Global.wthread: |
|
|||
448 | self.log.info("Enabling wx GUI event loop integration") |
|
|||
449 | inputhook.enable_wx(app=True) |
|
|||
450 | elif config.Global.q4thread: |
|
|||
451 | self.log.info("Enabling Qt4 GUI event loop integration") |
|
|||
452 | inputhook.enable_qt4(app=True) |
|
|||
453 | elif config.Global.gthread: |
|
|||
454 | self.log.info("Enabling GTK GUI event loop integration") |
|
|||
455 | inputhook.enable_gtk(app=True) |
|
|||
456 | except: |
|
|||
457 | self.log.warn("Error in enabling GUI event loop integration:") |
|
|||
458 | self.shell.showtraceback() |
|
|||
459 |
|
443 | |||
460 | def _load_extensions(self): |
|
444 | def _load_extensions(self): | |
461 | """Load all IPython extensions in Global.extensions. |
|
445 | """Load all IPython extensions in Global.extensions. | |
@@ -540,12 +524,18 b' class IPythonApp(Application):' | |||||
540 | self.log.warn("Error in executing file in user namespace: %s" % fname) |
|
524 | self.log.warn("Error in executing file in user namespace: %s" % fname) | |
541 | self.shell.showtraceback() |
|
525 | self.shell.showtraceback() | |
542 |
|
526 | |||
|
527 | def _configure_xmode(self): | |||
|
528 | # XXX - shouldn't this be read from the config? I'm still a little | |||
|
529 | # lost with all the details of handling the new config guys... | |||
|
530 | self.shell.InteractiveTB.set_mode(mode=self.shell.xmode) | |||
|
531 | ||||
543 | def start_app(self): |
|
532 | def start_app(self): | |
544 | if self.master_config.Global.interact: |
|
533 | if self.master_config.Global.interact: | |
545 | self.log.debug("Starting IPython's mainloop...") |
|
534 | self.log.debug("Starting IPython's mainloop...") | |
546 | self.shell.mainloop() |
|
535 | self.shell.mainloop() | |
547 |
|
536 | |||
548 |
|
537 | |||
|
538 | ||||
549 | def load_default_config(ipython_dir=None): |
|
539 | def load_default_config(ipython_dir=None): | |
550 | """Load the default config file from the default ipython_dir. |
|
540 | """Load the default config file from the default ipython_dir. | |
551 |
|
541 |
@@ -31,34 +31,37 b' import sys' | |||||
31 | import tempfile |
|
31 | import tempfile | |
32 | from contextlib import nested |
|
32 | from contextlib import nested | |
33 |
|
33 | |||
34 | from IPython.core import ultratb |
|
|||
35 | from IPython.core import debugger, oinspect |
|
34 | from IPython.core import debugger, oinspect | |
36 | from IPython.core import shadowns |
|
|||
37 | from IPython.core import history as ipcorehist |
|
35 | from IPython.core import history as ipcorehist | |
38 | from IPython.core import prefilter |
|
36 | from IPython.core import prefilter | |
|
37 | from IPython.core import shadowns | |||
|
38 | from IPython.core import ultratb | |||
39 | from IPython.core.alias import AliasManager |
|
39 | from IPython.core.alias import AliasManager | |
40 | from IPython.core.builtin_trap import BuiltinTrap |
|
40 | from IPython.core.builtin_trap import BuiltinTrap | |
|
41 | from IPython.core.component import Component | |||
41 | from IPython.core.display_trap import DisplayTrap |
|
42 | from IPython.core.display_trap import DisplayTrap | |
|
43 | from IPython.core.error import TryNext, UsageError | |||
42 | from IPython.core.fakemodule import FakeModule, init_fakemod_dict |
|
44 | from IPython.core.fakemodule import FakeModule, init_fakemod_dict | |
43 | from IPython.core.logger import Logger |
|
45 | from IPython.core.logger import Logger | |
44 | from IPython.core.magic import Magic |
|
46 | from IPython.core.magic import Magic | |
45 | from IPython.core.prompts import CachedOutput |
|
|||
46 | from IPython.core.prefilter import PrefilterManager |
|
47 | from IPython.core.prefilter import PrefilterManager | |
47 |
from IPython.core. |
|
48 | from IPython.core.prompts import CachedOutput | |
|
49 | from IPython.core.pylabtools import pylab_activate | |||
48 | from IPython.core.usage import interactive_usage, default_banner |
|
50 | from IPython.core.usage import interactive_usage, default_banner | |
49 | from IPython.core.error import TryNext, UsageError |
|
|||
50 |
|
||||
51 | from IPython.utils import pickleshare |
|
|||
52 | from IPython.external.Itpl import ItplNS |
|
51 | from IPython.external.Itpl import ItplNS | |
|
52 | from IPython.lib.inputhook import enable_gui | |||
53 | from IPython.lib.backgroundjobs import BackgroundJobManager |
|
53 | from IPython.lib.backgroundjobs import BackgroundJobManager | |
54 | from IPython.utils.ipstruct import Struct |
|
|||
55 | from IPython.utils import PyColorize |
|
54 | from IPython.utils import PyColorize | |
56 |
from IPython.utils |
|
55 | from IPython.utils import pickleshare | |
57 | from IPython.utils.genutils import get_ipython_dir |
|
56 | from IPython.utils.genutils import get_ipython_dir | |
|
57 | from IPython.utils.ipstruct import Struct | |||
58 | from IPython.utils.platutils import toggle_set_term_title, set_term_title |
|
58 | from IPython.utils.platutils import toggle_set_term_title, set_term_title | |
59 | from IPython.utils.strdispatch import StrDispatch |
|
59 | from IPython.utils.strdispatch import StrDispatch | |
60 | from IPython.utils.syspathcontext import prepended_to_syspath |
|
60 | from IPython.utils.syspathcontext import prepended_to_syspath | |
61 |
|
61 | |||
|
62 | # XXX - need to clean up this import * line | |||
|
63 | from IPython.utils.genutils import * | |||
|
64 | ||||
62 | # from IPython.utils import growl |
|
65 | # from IPython.utils import growl | |
63 | # growl.start("IPython") |
|
66 | # growl.start("IPython") | |
64 |
|
67 | |||
@@ -70,7 +73,6 b' from IPython.utils.traitlets import (' | |||||
70 | # Globals |
|
73 | # Globals | |
71 | #----------------------------------------------------------------------------- |
|
74 | #----------------------------------------------------------------------------- | |
72 |
|
75 | |||
73 |
|
||||
74 | # store the builtin raw_input globally, and use this always, in case user code |
|
76 | # store the builtin raw_input globally, and use this always, in case user code | |
75 | # overwrites it (like wx.py.PyShell does) |
|
77 | # overwrites it (like wx.py.PyShell does) | |
76 | raw_input_original = raw_input |
|
78 | raw_input_original = raw_input | |
@@ -78,12 +80,10 b' raw_input_original = raw_input' | |||||
78 | # compiled regexps for autoindent management |
|
80 | # compiled regexps for autoindent management | |
79 | dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass') |
|
81 | dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass') | |
80 |
|
82 | |||
81 |
|
||||
82 | #----------------------------------------------------------------------------- |
|
83 | #----------------------------------------------------------------------------- | |
83 | # Utilities |
|
84 | # Utilities | |
84 | #----------------------------------------------------------------------------- |
|
85 | #----------------------------------------------------------------------------- | |
85 |
|
86 | |||
86 |
|
||||
87 | ini_spaces_re = re.compile(r'^(\s+)') |
|
87 | ini_spaces_re = re.compile(r'^(\s+)') | |
88 |
|
88 | |||
89 |
|
89 | |||
@@ -2445,6 +2445,18 b' class InteractiveShell(Component, Magic):' | |||||
2445 | return ask_yes_no(prompt,default) |
|
2445 | return ask_yes_no(prompt,default) | |
2446 |
|
2446 | |||
2447 | #------------------------------------------------------------------------- |
|
2447 | #------------------------------------------------------------------------- | |
|
2448 | # Things related to GUI support and pylab | |||
|
2449 | #------------------------------------------------------------------------- | |||
|
2450 | ||||
|
2451 | def enable_pylab(self, gui=None): | |||
|
2452 | """ | |||
|
2453 | """ | |||
|
2454 | gui = pylab_activate(self.user_ns, gui) | |||
|
2455 | enable_gui(gui) | |||
|
2456 | self.magic_run = self._pylab_magic_run | |||
|
2457 | ||||
|
2458 | ||||
|
2459 | #------------------------------------------------------------------------- | |||
2448 | # Things related to IPython exiting |
|
2460 | # Things related to IPython exiting | |
2449 | #------------------------------------------------------------------------- |
|
2461 | #------------------------------------------------------------------------- | |
2450 |
|
2462 |
@@ -44,21 +44,26 b' except ImportError:' | |||||
44 |
|
44 | |||
45 | # Homebrewed |
|
45 | # Homebrewed | |
46 | import IPython |
|
46 | import IPython | |
47 | from IPython.utils import wildcard |
|
47 | import IPython.utils.generics | |
|
48 | ||||
48 | from IPython.core import debugger, oinspect |
|
49 | from IPython.core import debugger, oinspect | |
49 | from IPython.core.error import TryNext |
|
50 | from IPython.core.error import TryNext | |
|
51 | from IPython.core.error import UsageError | |||
50 | from IPython.core.fakemodule import FakeModule |
|
52 | from IPython.core.fakemodule import FakeModule | |
|
53 | from IPython.core.macro import Macro | |||
|
54 | from IPython.core.page import page | |||
51 | from IPython.core.prefilter import ESC_MAGIC |
|
55 | from IPython.core.prefilter import ESC_MAGIC | |
|
56 | from IPython.core.pylabtools import mpl_runner | |||
|
57 | from IPython.lib.inputhook import enable_gui | |||
52 | from IPython.external.Itpl import Itpl, itpl, printpl,itplns |
|
58 | from IPython.external.Itpl import Itpl, itpl, printpl,itplns | |
|
59 | from IPython.testing import decorators as testdec | |||
|
60 | from IPython.utils import platutils | |||
|
61 | from IPython.utils import wildcard | |||
53 | from IPython.utils.PyColorize import Parser |
|
62 | from IPython.utils.PyColorize import Parser | |
54 | from IPython.utils.ipstruct import Struct |
|
63 | from IPython.utils.ipstruct import Struct | |
55 | from IPython.core.macro import Macro |
|
64 | ||
|
65 | # XXX - We need to switch to explicit imports here with genutils | |||
56 | from IPython.utils.genutils import * |
|
66 | from IPython.utils.genutils import * | |
57 | from IPython.core.page import page |
|
|||
58 | from IPython.utils import platutils |
|
|||
59 | import IPython.utils.generics |
|
|||
60 | from IPython.core.error import UsageError |
|
|||
61 | from IPython.testing import decorators as testdec |
|
|||
62 |
|
67 | |||
63 | #*************************************************************************** |
|
68 | #*************************************************************************** | |
64 | # Utility functions |
|
69 | # Utility functions | |
@@ -82,130 +87,6 b' def compress_dhist(dh):' | |||||
82 | return newhead + tail |
|
87 | return newhead + tail | |
83 |
|
88 | |||
84 |
|
89 | |||
85 | def pylab_activate(user_ns, gui=None, import_all=True): |
|
|||
86 | """Activate pylab mode in the user's namespace. |
|
|||
87 |
|
||||
88 | Loads and initializes numpy, matplotlib and friends for interactive use. |
|
|||
89 |
|
||||
90 | Parameters |
|
|||
91 | ---------- |
|
|||
92 | user_ns : dict |
|
|||
93 | Namespace where the imports will occur. |
|
|||
94 |
|
||||
95 | gui : optional, string |
|
|||
96 | A valid gui name following the conventions of the %gui magic. |
|
|||
97 |
|
||||
98 | import_all : optional, boolean |
|
|||
99 | If true, an 'import *' is done from numpy and pylab. |
|
|||
100 |
|
||||
101 | Returns |
|
|||
102 | ------- |
|
|||
103 | The actual gui used (if not given as input, it was obtained from matplotlib |
|
|||
104 | itself, and will be needed next to configure IPython's gui integration. |
|
|||
105 | """ |
|
|||
106 |
|
||||
107 | # Initialize matplotlib to interactive mode always |
|
|||
108 | import matplotlib |
|
|||
109 |
|
||||
110 | # If user specifies a GUI, that dictates the backend, otherwise we read the |
|
|||
111 | # user's mpl default from the mpl rc structure |
|
|||
112 | g2b = {'tk': 'TkAgg', |
|
|||
113 | 'gtk': 'GTKAgg', |
|
|||
114 | 'wx': 'WXAgg', |
|
|||
115 | 'qt': 'Qt4Agg', # qt3 not supported |
|
|||
116 | 'qt4': 'Qt4Agg' } |
|
|||
117 |
|
||||
118 | if gui: |
|
|||
119 | # select backend based on requested gui |
|
|||
120 | backend = g2b[gui] |
|
|||
121 | else: |
|
|||
122 | backend = matplotlib.rcParams['backend'] |
|
|||
123 | # In this case, we need to find what the appropriate gui selection call |
|
|||
124 | # should be for IPython, so we can activate inputhook accordingly |
|
|||
125 | b2g = dict(zip(g2b.values(),g2b.keys())) |
|
|||
126 | gui = b2g[backend] |
|
|||
127 |
|
||||
128 | # We must set the desired backend before importing pylab |
|
|||
129 | matplotlib.use(backend) |
|
|||
130 |
|
||||
131 | # This must be imported last in the matplotlib series, after |
|
|||
132 | # backend/interactivity choices have been made |
|
|||
133 | import matplotlib.pylab as pylab |
|
|||
134 |
|
||||
135 | # XXX For now leave this commented out, but depending on discussions with |
|
|||
136 | # mpl-dev, we may be able to allow interactive switching... |
|
|||
137 | #import matplotlib.pyplot |
|
|||
138 | #matplotlib.pyplot.switch_backend(backend) |
|
|||
139 |
|
||||
140 | pylab.show._needmain = False |
|
|||
141 | # We need to detect at runtime whether show() is called by the user. |
|
|||
142 | # For this, we wrap it into a decorator which adds a 'called' flag. |
|
|||
143 | pylab.draw_if_interactive = flag_calls(pylab.draw_if_interactive) |
|
|||
144 |
|
||||
145 | # Import numpy as np/pyplot as plt are conventions we're trying to |
|
|||
146 | # somewhat standardize on. Making them available to users by default |
|
|||
147 | # will greatly help this. |
|
|||
148 | exec ("import numpy\n" |
|
|||
149 | "import numpy as np\n" |
|
|||
150 | "import matplotlib\n" |
|
|||
151 | "from matplotlib import pylab, mlab, pyplot as plt\n" |
|
|||
152 | ) in user_ns |
|
|||
153 |
|
||||
154 | if import_all: |
|
|||
155 | exec("from matplotlib.pylab import *\n" |
|
|||
156 | "from numpy import *\n") in user_ns |
|
|||
157 |
|
||||
158 | matplotlib.interactive(True) |
|
|||
159 |
|
||||
160 | print """ |
|
|||
161 | Welcome to pylab, a matplotlib-based Python environment. |
|
|||
162 | Backend in use: %s |
|
|||
163 | For more information, type 'help(pylab)'.""" % backend |
|
|||
164 |
|
||||
165 | return gui |
|
|||
166 |
|
||||
167 | # We need a little factory function here to create the closure where |
|
|||
168 | # safe_execfile can live. |
|
|||
169 | def mpl_runner(safe_execfile): |
|
|||
170 | """Factory to return a matplotlib-enabled runner for %run. |
|
|||
171 |
|
||||
172 | Parameters |
|
|||
173 | ---------- |
|
|||
174 | safe_execfile : function |
|
|||
175 | This must be a function with the same interface as the |
|
|||
176 | :meth:`safe_execfile` method of IPython. |
|
|||
177 |
|
||||
178 | Returns |
|
|||
179 | ------- |
|
|||
180 | A function suitable for use as the ``runner`` argument of the %run magic |
|
|||
181 | function. |
|
|||
182 | """ |
|
|||
183 |
|
||||
184 | def mpl_execfile(fname,*where,**kw): |
|
|||
185 | """matplotlib-aware wrapper around safe_execfile. |
|
|||
186 |
|
||||
187 | Its interface is identical to that of the :func:`execfile` builtin. |
|
|||
188 |
|
||||
189 | This is ultimately a call to execfile(), but wrapped in safeties to |
|
|||
190 | properly handle interactive rendering.""" |
|
|||
191 |
|
||||
192 | import matplotlib |
|
|||
193 | import matplotlib.pylab as pylab |
|
|||
194 |
|
||||
195 | #print '*** Matplotlib runner ***' # dbg |
|
|||
196 | # turn off rendering until end of script |
|
|||
197 | is_interactive = matplotlib.rcParams['interactive'] |
|
|||
198 | matplotlib.interactive(False) |
|
|||
199 | safe_execfile(fname,*where,**kw) |
|
|||
200 | matplotlib.interactive(is_interactive) |
|
|||
201 | # make rendering call now, if the user tried to do it |
|
|||
202 | if pylab.draw_if_interactive.called: |
|
|||
203 | pylab.draw() |
|
|||
204 | pylab.draw_if_interactive.called = False |
|
|||
205 |
|
||||
206 | return mpl_execfile |
|
|||
207 |
|
||||
208 |
|
||||
209 | #*************************************************************************** |
|
90 | #*************************************************************************** | |
210 | # Main class implementing Magic functionality |
|
91 | # Main class implementing Magic functionality | |
211 |
|
92 | |||
@@ -3568,7 +3449,7 b' Defaulting color scheme to \'NoColor\'"""' | |||||
3568 | oc.prompt_out.pad_left = False |
|
3449 | oc.prompt_out.pad_left = False | |
3569 |
|
3450 | |||
3570 | shell.pprint = False |
|
3451 | shell.pprint = False | |
3571 |
|
3452 | |||
3572 | shell.magic_xmode('Plain') |
|
3453 | shell.magic_xmode('Plain') | |
3573 |
|
3454 | |||
3574 | else: |
|
3455 | else: | |
@@ -3624,26 +3505,9 b' Defaulting color scheme to \'NoColor\'"""' | |||||
3624 |
|
3505 | |||
3625 | This is highly recommended for most users. |
|
3506 | This is highly recommended for most users. | |
3626 | """ |
|
3507 | """ | |
3627 | from IPython.lib import inputhook |
|
|||
3628 |
|
||||
3629 | opts, arg = self.parse_options(parameter_s,'a') |
|
3508 | opts, arg = self.parse_options(parameter_s,'a') | |
3630 |
if |
|
3509 | if arg=='': arg = None | |
3631 | inputhook.clear_inputhook() |
|
3510 | return enable_gui(arg, 'a' in opts) | |
3632 | return |
|
|||
3633 |
|
||||
3634 | guis = {'tk': inputhook.enable_tk, |
|
|||
3635 | 'gtk':inputhook.enable_gtk, |
|
|||
3636 | 'wx': inputhook.enable_wx, |
|
|||
3637 | 'qt': inputhook.enable_qt4, # qt3 not supported |
|
|||
3638 | 'qt4': inputhook.enable_qt4 } |
|
|||
3639 | try: |
|
|||
3640 | gui = guis[arg] |
|
|||
3641 | except KeyError: |
|
|||
3642 | e="Invalid GUI request %r, valid ones are:%s" % (arg, guis.keys()) |
|
|||
3643 | raise UsageError(e) |
|
|||
3644 |
|
||||
3645 | #print 'Switching IPython gui support to:', arg, 'a' in opts # dbg |
|
|||
3646 | return gui('a' in opts) |
|
|||
3647 |
|
3511 | |||
3648 | def magic_load_ext(self, module_str): |
|
3512 | def magic_load_ext(self, module_str): | |
3649 | """Load an IPython extension by its module name.""" |
|
3513 | """Load an IPython extension by its module name.""" | |
@@ -3757,9 +3621,6 b' Defaulting color scheme to \'NoColor\'"""' | |||||
3757 | Backend in use: Qt4Agg |
|
3621 | Backend in use: Qt4Agg | |
3758 | For more information, type 'help(pylab)'. |
|
3622 | For more information, type 'help(pylab)'. | |
3759 | """ |
|
3623 | """ | |
3760 |
|
3624 | self.shell.enable_pylab(s) | ||
3761 | gui = pylab_activate(self.shell.user_ns, s) |
|
|||
3762 | self.shell.magic_gui('-a %s' % gui) |
|
|||
3763 | self.shell.magic_run = self._pylab_magic_run |
|
|||
3764 |
|
3625 | |||
3765 | # end Magic |
|
3626 | # end Magic |
@@ -1,5 +1,5 b'' | |||||
1 | #!/usr/bin/env python |
|
1 | #!/usr/bin/env python | |
2 |
# |
|
2 | # coding: utf-8 | |
3 | """ |
|
3 | """ | |
4 | Inputhook management for GUI event loop integration. |
|
4 | Inputhook management for GUI event loop integration. | |
5 | """ |
|
5 | """ | |
@@ -24,6 +24,7 b' import sys' | |||||
24 |
|
24 | |||
25 | # Constants for identifying the GUI toolkits. |
|
25 | # Constants for identifying the GUI toolkits. | |
26 | GUI_WX = 'wx' |
|
26 | GUI_WX = 'wx' | |
|
27 | GUI_QT = 'qt' | |||
27 | GUI_QT4 = 'qt4' |
|
28 | GUI_QT4 = 'qt4' | |
28 | GUI_GTK = 'gtk' |
|
29 | GUI_GTK = 'gtk' | |
29 | GUI_TK = 'tk' |
|
30 | GUI_TK = 'tk' | |
@@ -326,8 +327,17 b' class InputHookManager(object):' | |||||
326 | self._installed = True |
|
327 | self._installed = True | |
327 | return original |
|
328 | return original | |
328 |
|
329 | |||
329 | def clear_inputhook(self): |
|
330 | def clear_inputhook(self, app=None): | |
330 |
"""Set PyOS_InputHook to NULL and return the previous one. |
|
331 | """Set PyOS_InputHook to NULL and return the previous one. | |
|
332 | ||||
|
333 | Parameters | |||
|
334 | ---------- | |||
|
335 | app : optional, ignored | |||
|
336 | This parameter is allowed only so that clear_inputhook() can be | |||
|
337 | called with a similar interface as all the ``enable_*`` methods. But | |||
|
338 | the actual value of the parameter is ignored. This uniform interface | |||
|
339 | makes it easier to have user-level entry points in the main IPython | |||
|
340 | app like :meth:`enable_gui`.""" | |||
331 | pyos_inputhook_ptr = self.get_pyos_inputhook() |
|
341 | pyos_inputhook_ptr = self.get_pyos_inputhook() | |
332 | original = self.get_pyos_inputhook_as_func() |
|
342 | original = self.get_pyos_inputhook_as_func() | |
333 | pyos_inputhook_ptr.value = ctypes.c_void_p(None).value |
|
343 | pyos_inputhook_ptr.value = ctypes.c_void_p(None).value | |
@@ -523,3 +533,39 b' set_inputhook = inputhook_manager.set_inputhook' | |||||
523 | current_gui = inputhook_manager.current_gui |
|
533 | current_gui = inputhook_manager.current_gui | |
524 | clear_app_refs = inputhook_manager.clear_app_refs |
|
534 | clear_app_refs = inputhook_manager.clear_app_refs | |
525 | spin = inputhook_manager.spin |
|
535 | spin = inputhook_manager.spin | |
|
536 | ||||
|
537 | ||||
|
538 | # Convenience function to switch amongst them | |||
|
539 | def enable_gui(gui=None, app=True): | |||
|
540 | """Switch amongst GUI input hooks by name. | |||
|
541 | ||||
|
542 | This is just a utility wrapper around the methods of the InputHookManager | |||
|
543 | object. | |||
|
544 | ||||
|
545 | Parameters | |||
|
546 | ---------- | |||
|
547 | gui : optional, string or None | |||
|
548 | If None, clears input hook, otherwise it must be one of the recognized | |||
|
549 | GUI names (see ``GUI_*`` constants in module). | |||
|
550 | ||||
|
551 | app : optional, bool | |||
|
552 | If true, create an app object and return it. | |||
|
553 | ||||
|
554 | Returns | |||
|
555 | ------- | |||
|
556 | The output of the underlying gui switch routine, typically the actual | |||
|
557 | PyOS_InputHook wrapper object or the GUI toolkit app created, if there was | |||
|
558 | one. | |||
|
559 | """ | |||
|
560 | guis = {None: clear_inputhook, | |||
|
561 | GUI_TK: enable_tk, | |||
|
562 | GUI_GTK: enable_gtk, | |||
|
563 | GUI_WX: enable_wx, | |||
|
564 | GUI_QT: enable_qt4, # qt3 not supported | |||
|
565 | GUI_QT4: enable_qt4 } | |||
|
566 | try: | |||
|
567 | gui_hook = guis[gui] | |||
|
568 | except KeyError: | |||
|
569 | e="Invalid GUI request %r, valid ones are:%s" % (gui, guis.keys()) | |||
|
570 | raise ValueError(e) | |||
|
571 | return gui_hook(app) |
General Comments 0
You need to be logged in to leave comments.
Login now