##// END OF EJS Templates
add `--matplotlib` flag to terminal IPython...
MinRK -
Show More
@@ -1,371 +1,397 b''
1 1 # encoding: utf-8
2 2 """
3 3 A mixin for :class:`~IPython.core.application.Application` classes that
4 4 launch InteractiveShell instances, load extensions, etc.
5 5
6 6 Authors
7 7 -------
8 8
9 9 * Min Ragan-Kelley
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 from __future__ import absolute_import
24 24
25 25 import glob
26 26 import os
27 27 import sys
28 28
29 29 from IPython.config.application import boolean_flag
30 30 from IPython.config.configurable import Configurable
31 31 from IPython.config.loader import Config
32 32 from IPython.core import pylabtools
33 33 from IPython.utils import py3compat
34 34 from IPython.utils.contexts import preserve_keys
35 35 from IPython.utils.path import filefind
36 36 from IPython.utils.traitlets import (
37 37 Unicode, Instance, List, Bool, CaselessStrEnum
38 38 )
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Aliases and Flags
42 42 #-----------------------------------------------------------------------------
43 43
44 44 shell_flags = {}
45 45
46 46 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
47 47 addflag('autoindent', 'InteractiveShell.autoindent',
48 48 'Turn on autoindenting.', 'Turn off autoindenting.'
49 49 )
50 50 addflag('automagic', 'InteractiveShell.automagic',
51 51 """Turn on the auto calling of magic commands. Type %%magic at the
52 52 IPython prompt for more information.""",
53 53 'Turn off the auto calling of magic commands.'
54 54 )
55 55 addflag('pdb', 'InteractiveShell.pdb',
56 56 "Enable auto calling the pdb debugger after every exception.",
57 57 "Disable auto calling the pdb debugger after every exception."
58 58 )
59 59 # pydb flag doesn't do any config, as core.debugger switches on import,
60 60 # which is before parsing. This just allows the flag to be passed.
61 61 shell_flags.update(dict(
62 62 pydb = ({},
63 63 """Use the third party 'pydb' package as debugger, instead of pdb.
64 64 Requires that pydb is installed."""
65 65 )
66 66 ))
67 67 addflag('pprint', 'PlainTextFormatter.pprint',
68 68 "Enable auto pretty printing of results.",
69 69 "Disable auto auto pretty printing of results."
70 70 )
71 71 addflag('color-info', 'InteractiveShell.color_info',
72 72 """IPython can display information about objects via a set of func-
73 73 tions, and optionally can use colors for this, syntax highlighting
74 74 source code and various other elements. However, because this
75 75 information is passed through a pager (like 'less') and many pagers get
76 76 confused with color codes, this option is off by default. You can test
77 77 it and turn it on permanently in your ipython_config.py file if it
78 78 works for you. Test it and turn it on permanently if it works with
79 79 your system. The magic function %%color_info allows you to toggle this
80 80 interactively for testing.""",
81 81 "Disable using colors for info related things."
82 82 )
83 83 addflag('deep-reload', 'InteractiveShell.deep_reload',
84 84 """Enable deep (recursive) reloading by default. IPython can use the
85 85 deep_reload module which reloads changes in modules recursively (it
86 86 replaces the reload() function, so you don't need to change anything to
87 87 use it). deep_reload() forces a full reload of modules whose code may
88 88 have changed, which the default reload() function does not. When
89 89 deep_reload is off, IPython will use the normal reload(), but
90 90 deep_reload will still be available as dreload(). This feature is off
91 91 by default [which means that you have both normal reload() and
92 92 dreload()].""",
93 93 "Disable deep (recursive) reloading by default."
94 94 )
95 95 nosep_config = Config()
96 96 nosep_config.InteractiveShell.separate_in = ''
97 97 nosep_config.InteractiveShell.separate_out = ''
98 98 nosep_config.InteractiveShell.separate_out2 = ''
99 99
100 100 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
101 101 shell_flags['pylab'] = (
102 102 {'InteractiveShellApp' : {'pylab' : 'auto'}},
103 103 """Pre-load matplotlib and numpy for interactive use with
104 104 the default matplotlib backend."""
105 105 )
106 shell_flags['matplotlib'] = (
107 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
108 """Configure matplotlib for interactive use with
109 the default matplotlib backend."""
110 )
106 111
107 112 # it's possible we don't want short aliases for *all* of these:
108 113 shell_aliases = dict(
109 114 autocall='InteractiveShell.autocall',
110 115 colors='InteractiveShell.colors',
111 116 logfile='InteractiveShell.logfile',
112 117 logappend='InteractiveShell.logappend',
113 118 c='InteractiveShellApp.code_to_run',
114 119 m='InteractiveShellApp.module_to_run',
115 120 ext='InteractiveShellApp.extra_extension',
116 121 gui='InteractiveShellApp.gui',
117 122 pylab='InteractiveShellApp.pylab',
123 matplotlib='InteractiveShellApp.matplotlib',
118 124 )
119 125 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
120 126
121 127 #-----------------------------------------------------------------------------
122 128 # Main classes and functions
123 129 #-----------------------------------------------------------------------------
124 130
125 131 class InteractiveShellApp(Configurable):
126 132 """A Mixin for applications that start InteractiveShell instances.
127 133
128 134 Provides configurables for loading extensions and executing files
129 135 as part of configuring a Shell environment.
130 136
131 137 The following methods should be called by the :meth:`initialize` method
132 138 of the subclass:
133 139
134 140 - :meth:`init_path`
135 141 - :meth:`init_shell` (to be implemented by the subclass)
136 142 - :meth:`init_gui_pylab`
137 143 - :meth:`init_extensions`
138 144 - :meth:`init_code`
139 145 """
140 146 extensions = List(Unicode, config=True,
141 147 help="A list of dotted module names of IPython extensions to load."
142 148 )
143 149 extra_extension = Unicode('', config=True,
144 150 help="dotted module name of an IPython extension to load."
145 151 )
146 152 def _extra_extension_changed(self, name, old, new):
147 153 if new:
148 154 # add to self.extensions
149 155 self.extensions.append(new)
150 156
151 157 # Extensions that are always loaded (not configurable)
152 158 default_extensions = List(Unicode, [u'storemagic'], config=False)
153 159
154 160 exec_files = List(Unicode, config=True,
155 161 help="""List of files to run at IPython startup."""
156 162 )
157 163 file_to_run = Unicode('', config=True,
158 164 help="""A file to be run""")
159 165
160 166 exec_lines = List(Unicode, config=True,
161 167 help="""lines of code to run at IPython startup."""
162 168 )
163 169 code_to_run = Unicode('', config=True,
164 170 help="Execute the given command string."
165 171 )
166 172 module_to_run = Unicode('', config=True,
167 173 help="Run the module as a script."
168 174 )
169 175 gui = CaselessStrEnum(('qt', 'wx', 'gtk', 'glut', 'pyglet', 'osx'), config=True,
170 176 help="Enable GUI event loop integration ('qt', 'wx', 'gtk', 'glut', 'pyglet', 'osx')."
171 177 )
178 matplotlib = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'inline', 'auto'],
179 config=True,
180 help="""Configure matplotlib for interactive use with
181 the default matplotlib backend."""
182 )
172 183 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'inline', 'auto'],
173 184 config=True,
174 185 help="""Pre-load matplotlib and numpy for interactive use,
175 186 selecting a particular matplotlib backend and loop integration.
176 187 """
177 188 )
178 189 pylab_import_all = Bool(True, config=True,
179 190 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
180 191 and an 'import *' is done from numpy and pylab, when using pylab mode.
181 192
182 193 When False, pylab mode should not import any names into the user namespace.
183 194 """
184 195 )
185 196 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
186 197
187 198 def init_path(self):
188 199 """Add current working directory, '', to sys.path"""
189 200 if sys.path[0] != '':
190 201 sys.path.insert(0, '')
191 202
192 203 def init_shell(self):
193 204 raise NotImplementedError("Override in subclasses")
194 205
195 206 def init_gui_pylab(self):
196 207 """Enable GUI event loop integration, taking pylab into account."""
197 if self.gui or self.pylab:
198 shell = self.shell
199 try:
200 if self.pylab:
201 gui, backend = pylabtools.find_gui_and_backend(self.pylab)
202 self.log.info("Enabling GUI event loop integration, "
203 "toolkit=%s, pylab=%s" % (gui, self.pylab))
204 if self.pylab == "auto":
205 print ("using matplotlib backend: %s" % backend)
206 shell.enable_pylab(self.pylab, import_all=self.pylab_import_all)
207 else:
208 self.log.info("Enabling GUI event loop integration, "
209 "toolkit=%s" % self.gui)
210 shell.enable_gui(self.gui)
211 except ImportError:
212 self.log.warn("pylab mode doesn't work as matplotlib could not be found." + \
213 "\nIs it installed on the system?")
214 self.shell.showtraceback()
215 except Exception:
216 self.log.warn("GUI event loop or pylab initialization failed")
217 self.shell.showtraceback()
208 enable = False
209 shell = self.shell
210 if self.pylab:
211 enable = shell.enable_pylab
212 key = self.pylab
213 elif self.matplotlib:
214 enable = shell.enable_matplotlib
215 key = self.matplotlib
216 elif self.gui:
217 enable = shell.enable_gui
218 key = self.gui
219
220 if not enable:
221 return
222
223 try:
224 r = enable(key)
225 except ImportError:
226 self.log.warn("Eventloop or matplotlib integration failed. Is matplotlib installed?")
227 self.shell.showtraceback()
228 return
229 except Exception:
230 self.log.warn("GUI event loop or pylab initialization failed")
231 self.shell.showtraceback()
232 return
233
234 if isinstance(r, tuple):
235 gui, backend = r[:2]
236 self.log.info("Enabling GUI event loop integration, "
237 "eventloop=%s, matplotlib=%s", gui, backend)
238 if key == "auto":
239 print ("using matplotlib backend: %s" % backend)
240 else:
241 gui = r
242 self.log.info("Enabling GUI event loop integration, "
243 "eventloop=%s", gui)
218 244
219 245 def init_extensions(self):
220 246 """Load all IPython extensions in IPythonApp.extensions.
221 247
222 248 This uses the :meth:`ExtensionManager.load_extensions` to load all
223 249 the extensions listed in ``self.extensions``.
224 250 """
225 251 try:
226 252 self.log.debug("Loading IPython extensions...")
227 253 extensions = self.default_extensions + self.extensions
228 254 for ext in extensions:
229 255 try:
230 256 self.log.info("Loading IPython extension: %s" % ext)
231 257 self.shell.extension_manager.load_extension(ext)
232 258 except:
233 259 self.log.warn("Error in loading extension: %s" % ext +
234 260 "\nCheck your config files in %s" % self.profile_dir.location
235 261 )
236 262 self.shell.showtraceback()
237 263 except:
238 264 self.log.warn("Unknown error in loading extensions:")
239 265 self.shell.showtraceback()
240 266
241 267 def init_code(self):
242 268 """run the pre-flight code, specified via exec_lines"""
243 269 self._run_startup_files()
244 270 self._run_exec_lines()
245 271 self._run_exec_files()
246 272 self._run_cmd_line_code()
247 273 self._run_module()
248 274
249 275 # flush output, so itwon't be attached to the first cell
250 276 sys.stdout.flush()
251 277 sys.stderr.flush()
252 278
253 279 # Hide variables defined here from %who etc.
254 280 self.shell.user_ns_hidden.update(self.shell.user_ns)
255 281
256 282 def _run_exec_lines(self):
257 283 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
258 284 if not self.exec_lines:
259 285 return
260 286 try:
261 287 self.log.debug("Running code from IPythonApp.exec_lines...")
262 288 for line in self.exec_lines:
263 289 try:
264 290 self.log.info("Running code in user namespace: %s" %
265 291 line)
266 292 self.shell.run_cell(line, store_history=False)
267 293 except:
268 294 self.log.warn("Error in executing line in user "
269 295 "namespace: %s" % line)
270 296 self.shell.showtraceback()
271 297 except:
272 298 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
273 299 self.shell.showtraceback()
274 300
275 301 def _exec_file(self, fname):
276 302 try:
277 303 full_filename = filefind(fname, [u'.', self.ipython_dir])
278 304 except IOError as e:
279 305 self.log.warn("File not found: %r"%fname)
280 306 return
281 307 # Make sure that the running script gets a proper sys.argv as if it
282 308 # were run from a system shell.
283 309 save_argv = sys.argv
284 310 sys.argv = [full_filename] + self.extra_args[1:]
285 311 # protect sys.argv from potential unicode strings on Python 2:
286 312 if not py3compat.PY3:
287 313 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
288 314 try:
289 315 if os.path.isfile(full_filename):
290 316 self.log.info("Running file in user namespace: %s" %
291 317 full_filename)
292 318 # Ensure that __file__ is always defined to match Python
293 319 # behavior.
294 320 with preserve_keys(self.shell.user_ns, '__file__'):
295 321 self.shell.user_ns['__file__'] = fname
296 322 if full_filename.endswith('.ipy'):
297 323 self.shell.safe_execfile_ipy(full_filename)
298 324 else:
299 325 # default to python, even without extension
300 326 self.shell.safe_execfile(full_filename,
301 327 self.shell.user_ns)
302 328 finally:
303 329 sys.argv = save_argv
304 330
305 331 def _run_startup_files(self):
306 332 """Run files from profile startup directory"""
307 333 startup_dir = self.profile_dir.startup_dir
308 334 startup_files = []
309 335 if os.environ.get('PYTHONSTARTUP', False):
310 336 startup_files.append(os.environ['PYTHONSTARTUP'])
311 337 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
312 338 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
313 339 if not startup_files:
314 340 return
315 341
316 342 self.log.debug("Running startup files from %s...", startup_dir)
317 343 try:
318 344 for fname in sorted(startup_files):
319 345 self._exec_file(fname)
320 346 except:
321 347 self.log.warn("Unknown error in handling startup files:")
322 348 self.shell.showtraceback()
323 349
324 350 def _run_exec_files(self):
325 351 """Run files from IPythonApp.exec_files"""
326 352 if not self.exec_files:
327 353 return
328 354
329 355 self.log.debug("Running files in IPythonApp.exec_files...")
330 356 try:
331 357 for fname in self.exec_files:
332 358 self._exec_file(fname)
333 359 except:
334 360 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
335 361 self.shell.showtraceback()
336 362
337 363 def _run_cmd_line_code(self):
338 364 """Run code or file specified at the command-line"""
339 365 if self.code_to_run:
340 366 line = self.code_to_run
341 367 try:
342 368 self.log.info("Running code given at command line (c=): %s" %
343 369 line)
344 370 self.shell.run_cell(line, store_history=False)
345 371 except:
346 372 self.log.warn("Error in executing line in user namespace: %s" %
347 373 line)
348 374 self.shell.showtraceback()
349 375
350 376 # Like Python itself, ignore the second if the first of these is present
351 377 elif self.file_to_run:
352 378 fname = self.file_to_run
353 379 try:
354 380 self._exec_file(fname)
355 381 except:
356 382 self.log.warn("Error in executing file in user namespace: %s" %
357 383 fname)
358 384 self.shell.showtraceback()
359 385
360 386 def _run_module(self):
361 387 """Run module specified at the command-line."""
362 388 if self.module_to_run:
363 389 # Make sure that the module gets a proper sys.argv as if it were
364 390 # run using `python -m`.
365 391 save_argv = sys.argv
366 392 sys.argv = [sys.executable] + self.extra_args
367 393 try:
368 394 self.shell.safe_run_module(self.module_to_run,
369 395 self.shell.user_ns)
370 396 finally:
371 397 sys.argv = save_argv
General Comments 0
You need to be logged in to leave comments. Login now