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