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