##// END OF EJS Templates
move interact trait up one level to InteractiveShellApp
Min RK -
Show More
@@ -1,435 +1,437 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5 """
5 """
6
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 from __future__ import absolute_import
10 from __future__ import absolute_import
11 from __future__ import print_function
11 from __future__ import print_function
12
12
13 import glob
13 import glob
14 import os
14 import os
15 import sys
15 import sys
16
16
17 from traitlets.config.application import boolean_flag
17 from traitlets.config.application import boolean_flag
18 from traitlets.config.configurable import Configurable
18 from traitlets.config.configurable import Configurable
19 from traitlets.config.loader import Config
19 from traitlets.config.loader import Config
20 from IPython.core import pylabtools
20 from IPython.core import pylabtools
21 from IPython.utils import py3compat
21 from IPython.utils import py3compat
22 from IPython.utils.contexts import preserve_keys
22 from IPython.utils.contexts import preserve_keys
23 from IPython.utils.path import filefind
23 from IPython.utils.path import filefind
24 from traitlets import (
24 from traitlets import (
25 Unicode, Instance, List, Bool, CaselessStrEnum
25 Unicode, Instance, List, Bool, CaselessStrEnum
26 )
26 )
27 from IPython.lib.inputhook import guis
27 from IPython.lib.inputhook import guis
28
28
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30 # Aliases and Flags
30 # Aliases and Flags
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32
32
33 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
33 gui_keys = tuple(sorted([ key for key in guis if key is not None ]))
34
34
35 backend_keys = sorted(pylabtools.backends.keys())
35 backend_keys = sorted(pylabtools.backends.keys())
36 backend_keys.insert(0, 'auto')
36 backend_keys.insert(0, 'auto')
37
37
38 shell_flags = {}
38 shell_flags = {}
39
39
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
41 addflag('autoindent', 'InteractiveShell.autoindent',
41 addflag('autoindent', 'InteractiveShell.autoindent',
42 'Turn on autoindenting.', 'Turn off autoindenting.'
42 'Turn on autoindenting.', 'Turn off autoindenting.'
43 )
43 )
44 addflag('automagic', 'InteractiveShell.automagic',
44 addflag('automagic', 'InteractiveShell.automagic',
45 """Turn on the auto calling of magic commands. Type %%magic at the
45 """Turn on the auto calling of magic commands. Type %%magic at the
46 IPython prompt for more information.""",
46 IPython prompt for more information.""",
47 'Turn off the auto calling of magic commands.'
47 'Turn off the auto calling of magic commands.'
48 )
48 )
49 addflag('pdb', 'InteractiveShell.pdb',
49 addflag('pdb', 'InteractiveShell.pdb',
50 "Enable auto calling the pdb debugger after every exception.",
50 "Enable auto calling the pdb debugger after every exception.",
51 "Disable auto calling the pdb debugger after every exception."
51 "Disable auto calling the pdb debugger after every exception."
52 )
52 )
53 # pydb flag doesn't do any config, as core.debugger switches on import,
53 # pydb flag doesn't do any config, as core.debugger switches on import,
54 # which is before parsing. This just allows the flag to be passed.
54 # which is before parsing. This just allows the flag to be passed.
55 shell_flags.update(dict(
55 shell_flags.update(dict(
56 pydb = ({},
56 pydb = ({},
57 """Use the third party 'pydb' package as debugger, instead of pdb.
57 """Use the third party 'pydb' package as debugger, instead of pdb.
58 Requires that pydb is installed."""
58 Requires that pydb is installed."""
59 )
59 )
60 ))
60 ))
61 addflag('pprint', 'PlainTextFormatter.pprint',
61 addflag('pprint', 'PlainTextFormatter.pprint',
62 "Enable auto pretty printing of results.",
62 "Enable auto pretty printing of results.",
63 "Disable auto pretty printing of results."
63 "Disable auto pretty printing of results."
64 )
64 )
65 addflag('color-info', 'InteractiveShell.color_info',
65 addflag('color-info', 'InteractiveShell.color_info',
66 """IPython can display information about objects via a set of functions,
66 """IPython can display information about objects via a set of functions,
67 and optionally can use colors for this, syntax highlighting
67 and optionally can use colors for this, syntax highlighting
68 source code and various other elements. This is on by default, but can cause
68 source code and various other elements. This is on by default, but can cause
69 problems with some pagers. If you see such problems, you can disable the
69 problems with some pagers. If you see such problems, you can disable the
70 colours.""",
70 colours.""",
71 "Disable using colors for info related things."
71 "Disable using colors for info related things."
72 )
72 )
73 addflag('deep-reload', 'InteractiveShell.deep_reload',
73 addflag('deep-reload', 'InteractiveShell.deep_reload',
74 """ **Deprecated** and will be removed in IPython 5.0.
74 """ **Deprecated** and will be removed in IPython 5.0.
75
75
76 Enable deep (recursive) reloading by default. IPython can use the
76 Enable deep (recursive) reloading by default. IPython can use the
77 deep_reload module which reloads changes in modules recursively (it
77 deep_reload module which reloads changes in modules recursively (it
78 replaces the reload() function, so you don't need to change anything to
78 replaces the reload() function, so you don't need to change anything to
79 use it). deep_reload() forces a full reload of modules whose code may
79 use it). deep_reload() forces a full reload of modules whose code may
80 have changed, which the default reload() function does not. When
80 have changed, which the default reload() function does not. When
81 deep_reload is off, IPython will use the normal reload(), but
81 deep_reload is off, IPython will use the normal reload(), but
82 deep_reload will still be available as dreload(). This feature is off
82 deep_reload will still be available as dreload(). This feature is off
83 by default [which means that you have both normal reload() and
83 by default [which means that you have both normal reload() and
84 dreload()].""",
84 dreload()].""",
85 "Disable deep (recursive) reloading by default."
85 "Disable deep (recursive) reloading by default."
86 )
86 )
87 nosep_config = Config()
87 nosep_config = Config()
88 nosep_config.InteractiveShell.separate_in = ''
88 nosep_config.InteractiveShell.separate_in = ''
89 nosep_config.InteractiveShell.separate_out = ''
89 nosep_config.InteractiveShell.separate_out = ''
90 nosep_config.InteractiveShell.separate_out2 = ''
90 nosep_config.InteractiveShell.separate_out2 = ''
91
91
92 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
92 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
93 shell_flags['pylab'] = (
93 shell_flags['pylab'] = (
94 {'InteractiveShellApp' : {'pylab' : 'auto'}},
94 {'InteractiveShellApp' : {'pylab' : 'auto'}},
95 """Pre-load matplotlib and numpy for interactive use with
95 """Pre-load matplotlib and numpy for interactive use with
96 the default matplotlib backend."""
96 the default matplotlib backend."""
97 )
97 )
98 shell_flags['matplotlib'] = (
98 shell_flags['matplotlib'] = (
99 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
99 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
100 """Configure matplotlib for interactive use with
100 """Configure matplotlib for interactive use with
101 the default matplotlib backend."""
101 the default matplotlib backend."""
102 )
102 )
103
103
104 # it's possible we don't want short aliases for *all* of these:
104 # it's possible we don't want short aliases for *all* of these:
105 shell_aliases = dict(
105 shell_aliases = dict(
106 autocall='InteractiveShell.autocall',
106 autocall='InteractiveShell.autocall',
107 colors='InteractiveShell.colors',
107 colors='InteractiveShell.colors',
108 logfile='InteractiveShell.logfile',
108 logfile='InteractiveShell.logfile',
109 logappend='InteractiveShell.logappend',
109 logappend='InteractiveShell.logappend',
110 c='InteractiveShellApp.code_to_run',
110 c='InteractiveShellApp.code_to_run',
111 m='InteractiveShellApp.module_to_run',
111 m='InteractiveShellApp.module_to_run',
112 ext='InteractiveShellApp.extra_extension',
112 ext='InteractiveShellApp.extra_extension',
113 gui='InteractiveShellApp.gui',
113 gui='InteractiveShellApp.gui',
114 pylab='InteractiveShellApp.pylab',
114 pylab='InteractiveShellApp.pylab',
115 matplotlib='InteractiveShellApp.matplotlib',
115 matplotlib='InteractiveShellApp.matplotlib',
116 )
116 )
117 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
117 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
118
118
119 #-----------------------------------------------------------------------------
119 #-----------------------------------------------------------------------------
120 # Main classes and functions
120 # Main classes and functions
121 #-----------------------------------------------------------------------------
121 #-----------------------------------------------------------------------------
122
122
123 class InteractiveShellApp(Configurable):
123 class InteractiveShellApp(Configurable):
124 """A Mixin for applications that start InteractiveShell instances.
124 """A Mixin for applications that start InteractiveShell instances.
125
125
126 Provides configurables for loading extensions and executing files
126 Provides configurables for loading extensions and executing files
127 as part of configuring a Shell environment.
127 as part of configuring a Shell environment.
128
128
129 The following methods should be called by the :meth:`initialize` method
129 The following methods should be called by the :meth:`initialize` method
130 of the subclass:
130 of the subclass:
131
131
132 - :meth:`init_path`
132 - :meth:`init_path`
133 - :meth:`init_shell` (to be implemented by the subclass)
133 - :meth:`init_shell` (to be implemented by the subclass)
134 - :meth:`init_gui_pylab`
134 - :meth:`init_gui_pylab`
135 - :meth:`init_extensions`
135 - :meth:`init_extensions`
136 - :meth:`init_code`
136 - :meth:`init_code`
137 """
137 """
138 extensions = List(Unicode(), config=True,
138 extensions = List(Unicode(), config=True,
139 help="A list of dotted module names of IPython extensions to load."
139 help="A list of dotted module names of IPython extensions to load."
140 )
140 )
141 extra_extension = Unicode('', config=True,
141 extra_extension = Unicode('', config=True,
142 help="dotted module name of an IPython extension to load."
142 help="dotted module name of an IPython extension to load."
143 )
143 )
144
144
145 reraise_ipython_extension_failures = Bool(
145 reraise_ipython_extension_failures = Bool(
146 False,
146 False,
147 config=True,
147 config=True,
148 help="Reraise exceptions encountered loading IPython extensions?",
148 help="Reraise exceptions encountered loading IPython extensions?",
149 )
149 )
150
150
151 # Extensions that are always loaded (not configurable)
151 # Extensions that are always loaded (not configurable)
152 default_extensions = List(Unicode(), [u'storemagic'], config=False)
152 default_extensions = List(Unicode(), [u'storemagic'], config=False)
153
153
154 hide_initial_ns = Bool(True, config=True,
154 hide_initial_ns = Bool(True, config=True,
155 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
155 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
156 be hidden from tools like %who?"""
156 be hidden from tools like %who?"""
157 )
157 )
158
158
159 exec_files = List(Unicode(), config=True,
159 exec_files = List(Unicode(), config=True,
160 help="""List of files to run at IPython startup."""
160 help="""List of files to run at IPython startup."""
161 )
161 )
162 exec_PYTHONSTARTUP = Bool(True, config=True,
162 exec_PYTHONSTARTUP = Bool(True, config=True,
163 help="""Run the file referenced by the PYTHONSTARTUP environment
163 help="""Run the file referenced by the PYTHONSTARTUP environment
164 variable at IPython startup."""
164 variable at IPython startup."""
165 )
165 )
166 file_to_run = Unicode('', config=True,
166 file_to_run = Unicode('', config=True,
167 help="""A file to be run""")
167 help="""A file to be run""")
168
168
169 exec_lines = List(Unicode(), config=True,
169 exec_lines = List(Unicode(), config=True,
170 help="""lines of code to run at IPython startup."""
170 help="""lines of code to run at IPython startup."""
171 )
171 )
172 code_to_run = Unicode('', config=True,
172 code_to_run = Unicode('', config=True,
173 help="Execute the given command string."
173 help="Execute the given command string."
174 )
174 )
175 module_to_run = Unicode('', config=True,
175 module_to_run = Unicode('', config=True,
176 help="Run the module as a script."
176 help="Run the module as a script."
177 )
177 )
178 gui = CaselessStrEnum(gui_keys, config=True, allow_none=True,
178 gui = CaselessStrEnum(gui_keys, config=True, allow_none=True,
179 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
179 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
180 )
180 )
181 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
181 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
182 config=True,
182 config=True,
183 help="""Configure matplotlib for interactive use with
183 help="""Configure matplotlib for interactive use with
184 the default matplotlib backend."""
184 the default matplotlib backend."""
185 )
185 )
186 pylab = CaselessStrEnum(backend_keys, allow_none=True,
186 pylab = CaselessStrEnum(backend_keys, allow_none=True,
187 config=True,
187 config=True,
188 help="""Pre-load matplotlib and numpy for interactive use,
188 help="""Pre-load matplotlib and numpy for interactive use,
189 selecting a particular matplotlib backend and loop integration.
189 selecting a particular matplotlib backend and loop integration.
190 """
190 """
191 )
191 )
192 pylab_import_all = Bool(True, config=True,
192 pylab_import_all = Bool(True, config=True,
193 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
193 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
194 and an ``import *`` is done from numpy and pylab, when using pylab mode.
194 and an ``import *`` is done from numpy and pylab, when using pylab mode.
195
195
196 When False, pylab mode should not import any names into the user namespace.
196 When False, pylab mode should not import any names into the user namespace.
197 """
197 """
198 )
198 )
199 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
199 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
200 allow_none=True)
200 allow_none=True)
201 # whether interact-loop should start
202 interact = Bool(True)
201
203
202 user_ns = Instance(dict, args=None, allow_none=True)
204 user_ns = Instance(dict, args=None, allow_none=True)
203 def _user_ns_changed(self, name, old, new):
205 def _user_ns_changed(self, name, old, new):
204 if self.shell is not None:
206 if self.shell is not None:
205 self.shell.user_ns = new
207 self.shell.user_ns = new
206 self.shell.init_user_ns()
208 self.shell.init_user_ns()
207
209
208 def init_path(self):
210 def init_path(self):
209 """Add current working directory, '', to sys.path"""
211 """Add current working directory, '', to sys.path"""
210 if sys.path[0] != '':
212 if sys.path[0] != '':
211 sys.path.insert(0, '')
213 sys.path.insert(0, '')
212
214
213 def init_shell(self):
215 def init_shell(self):
214 raise NotImplementedError("Override in subclasses")
216 raise NotImplementedError("Override in subclasses")
215
217
216 def init_gui_pylab(self):
218 def init_gui_pylab(self):
217 """Enable GUI event loop integration, taking pylab into account."""
219 """Enable GUI event loop integration, taking pylab into account."""
218 enable = False
220 enable = False
219 shell = self.shell
221 shell = self.shell
220 if self.pylab:
222 if self.pylab:
221 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
223 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
222 key = self.pylab
224 key = self.pylab
223 elif self.matplotlib:
225 elif self.matplotlib:
224 enable = shell.enable_matplotlib
226 enable = shell.enable_matplotlib
225 key = self.matplotlib
227 key = self.matplotlib
226 elif self.gui:
228 elif self.gui:
227 enable = shell.enable_gui
229 enable = shell.enable_gui
228 key = self.gui
230 key = self.gui
229
231
230 if not enable:
232 if not enable:
231 return
233 return
232
234
233 try:
235 try:
234 r = enable(key)
236 r = enable(key)
235 except ImportError:
237 except ImportError:
236 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
238 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
237 self.shell.showtraceback()
239 self.shell.showtraceback()
238 return
240 return
239 except Exception:
241 except Exception:
240 self.log.warning("GUI event loop or pylab initialization failed")
242 self.log.warning("GUI event loop or pylab initialization failed")
241 self.shell.showtraceback()
243 self.shell.showtraceback()
242 return
244 return
243
245
244 if isinstance(r, tuple):
246 if isinstance(r, tuple):
245 gui, backend = r[:2]
247 gui, backend = r[:2]
246 self.log.info("Enabling GUI event loop integration, "
248 self.log.info("Enabling GUI event loop integration, "
247 "eventloop=%s, matplotlib=%s", gui, backend)
249 "eventloop=%s, matplotlib=%s", gui, backend)
248 if key == "auto":
250 if key == "auto":
249 print("Using matplotlib backend: %s" % backend)
251 print("Using matplotlib backend: %s" % backend)
250 else:
252 else:
251 gui = r
253 gui = r
252 self.log.info("Enabling GUI event loop integration, "
254 self.log.info("Enabling GUI event loop integration, "
253 "eventloop=%s", gui)
255 "eventloop=%s", gui)
254
256
255 def init_extensions(self):
257 def init_extensions(self):
256 """Load all IPython extensions in IPythonApp.extensions.
258 """Load all IPython extensions in IPythonApp.extensions.
257
259
258 This uses the :meth:`ExtensionManager.load_extensions` to load all
260 This uses the :meth:`ExtensionManager.load_extensions` to load all
259 the extensions listed in ``self.extensions``.
261 the extensions listed in ``self.extensions``.
260 """
262 """
261 try:
263 try:
262 self.log.debug("Loading IPython extensions...")
264 self.log.debug("Loading IPython extensions...")
263 extensions = self.default_extensions + self.extensions
265 extensions = self.default_extensions + self.extensions
264 if self.extra_extension:
266 if self.extra_extension:
265 extensions.append(self.extra_extension)
267 extensions.append(self.extra_extension)
266 for ext in extensions:
268 for ext in extensions:
267 try:
269 try:
268 self.log.info("Loading IPython extension: %s" % ext)
270 self.log.info("Loading IPython extension: %s" % ext)
269 self.shell.extension_manager.load_extension(ext)
271 self.shell.extension_manager.load_extension(ext)
270 except:
272 except:
271 if self.reraise_ipython_extension_failures:
273 if self.reraise_ipython_extension_failures:
272 raise
274 raise
273 msg = ("Error in loading extension: {ext}\n"
275 msg = ("Error in loading extension: {ext}\n"
274 "Check your config files in {location}".format(
276 "Check your config files in {location}".format(
275 ext=ext,
277 ext=ext,
276 location=self.profile_dir.location
278 location=self.profile_dir.location
277 ))
279 ))
278 self.log.warning(msg, exc_info=True)
280 self.log.warning(msg, exc_info=True)
279 except:
281 except:
280 if self.reraise_ipython_extension_failures:
282 if self.reraise_ipython_extension_failures:
281 raise
283 raise
282 self.log.warning("Unknown error in loading extensions:", exc_info=True)
284 self.log.warning("Unknown error in loading extensions:", exc_info=True)
283
285
284 def init_code(self):
286 def init_code(self):
285 """run the pre-flight code, specified via exec_lines"""
287 """run the pre-flight code, specified via exec_lines"""
286 self._run_startup_files()
288 self._run_startup_files()
287 self._run_exec_lines()
289 self._run_exec_lines()
288 self._run_exec_files()
290 self._run_exec_files()
289
291
290 # Hide variables defined here from %who etc.
292 # Hide variables defined here from %who etc.
291 if self.hide_initial_ns:
293 if self.hide_initial_ns:
292 self.shell.user_ns_hidden.update(self.shell.user_ns)
294 self.shell.user_ns_hidden.update(self.shell.user_ns)
293
295
294 # command-line execution (ipython -i script.py, ipython -m module)
296 # command-line execution (ipython -i script.py, ipython -m module)
295 # should *not* be excluded from %whos
297 # should *not* be excluded from %whos
296 self._run_cmd_line_code()
298 self._run_cmd_line_code()
297 self._run_module()
299 self._run_module()
298
300
299 # flush output, so itwon't be attached to the first cell
301 # flush output, so itwon't be attached to the first cell
300 sys.stdout.flush()
302 sys.stdout.flush()
301 sys.stderr.flush()
303 sys.stderr.flush()
302
304
303 def _run_exec_lines(self):
305 def _run_exec_lines(self):
304 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
306 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
305 if not self.exec_lines:
307 if not self.exec_lines:
306 return
308 return
307 try:
309 try:
308 self.log.debug("Running code from IPythonApp.exec_lines...")
310 self.log.debug("Running code from IPythonApp.exec_lines...")
309 for line in self.exec_lines:
311 for line in self.exec_lines:
310 try:
312 try:
311 self.log.info("Running code in user namespace: %s" %
313 self.log.info("Running code in user namespace: %s" %
312 line)
314 line)
313 self.shell.run_cell(line, store_history=False)
315 self.shell.run_cell(line, store_history=False)
314 except:
316 except:
315 self.log.warning("Error in executing line in user "
317 self.log.warning("Error in executing line in user "
316 "namespace: %s" % line)
318 "namespace: %s" % line)
317 self.shell.showtraceback()
319 self.shell.showtraceback()
318 except:
320 except:
319 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
321 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
320 self.shell.showtraceback()
322 self.shell.showtraceback()
321
323
322 def _exec_file(self, fname, shell_futures=False):
324 def _exec_file(self, fname, shell_futures=False):
323 try:
325 try:
324 full_filename = filefind(fname, [u'.', self.ipython_dir])
326 full_filename = filefind(fname, [u'.', self.ipython_dir])
325 except IOError as e:
327 except IOError as e:
326 self.log.warning("File not found: %r"%fname)
328 self.log.warning("File not found: %r"%fname)
327 return
329 return
328 # Make sure that the running script gets a proper sys.argv as if it
330 # Make sure that the running script gets a proper sys.argv as if it
329 # were run from a system shell.
331 # were run from a system shell.
330 save_argv = sys.argv
332 save_argv = sys.argv
331 sys.argv = [full_filename] + self.extra_args[1:]
333 sys.argv = [full_filename] + self.extra_args[1:]
332 # protect sys.argv from potential unicode strings on Python 2:
334 # protect sys.argv from potential unicode strings on Python 2:
333 if not py3compat.PY3:
335 if not py3compat.PY3:
334 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
336 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
335 try:
337 try:
336 if os.path.isfile(full_filename):
338 if os.path.isfile(full_filename):
337 self.log.info("Running file in user namespace: %s" %
339 self.log.info("Running file in user namespace: %s" %
338 full_filename)
340 full_filename)
339 # Ensure that __file__ is always defined to match Python
341 # Ensure that __file__ is always defined to match Python
340 # behavior.
342 # behavior.
341 with preserve_keys(self.shell.user_ns, '__file__'):
343 with preserve_keys(self.shell.user_ns, '__file__'):
342 self.shell.user_ns['__file__'] = fname
344 self.shell.user_ns['__file__'] = fname
343 if full_filename.endswith('.ipy'):
345 if full_filename.endswith('.ipy'):
344 self.shell.safe_execfile_ipy(full_filename,
346 self.shell.safe_execfile_ipy(full_filename,
345 shell_futures=shell_futures)
347 shell_futures=shell_futures)
346 else:
348 else:
347 # default to python, even without extension
349 # default to python, even without extension
348 self.shell.safe_execfile(full_filename,
350 self.shell.safe_execfile(full_filename,
349 self.shell.user_ns,
351 self.shell.user_ns,
350 shell_futures=shell_futures,
352 shell_futures=shell_futures,
351 raise_exceptions=True)
353 raise_exceptions=True)
352 finally:
354 finally:
353 sys.argv = save_argv
355 sys.argv = save_argv
354
356
355 def _run_startup_files(self):
357 def _run_startup_files(self):
356 """Run files from profile startup directory"""
358 """Run files from profile startup directory"""
357 startup_dir = self.profile_dir.startup_dir
359 startup_dir = self.profile_dir.startup_dir
358 startup_files = []
360 startup_files = []
359
361
360 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
362 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
361 not (self.file_to_run or self.code_to_run or self.module_to_run):
363 not (self.file_to_run or self.code_to_run or self.module_to_run):
362 python_startup = os.environ['PYTHONSTARTUP']
364 python_startup = os.environ['PYTHONSTARTUP']
363 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
365 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
364 try:
366 try:
365 self._exec_file(python_startup)
367 self._exec_file(python_startup)
366 except:
368 except:
367 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
369 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
368 self.shell.showtraceback()
370 self.shell.showtraceback()
369 finally:
371 finally:
370 # Many PYTHONSTARTUP files set up the readline completions,
372 # Many PYTHONSTARTUP files set up the readline completions,
371 # but this is often at odds with IPython's own completions.
373 # but this is often at odds with IPython's own completions.
372 # Do not allow PYTHONSTARTUP to set up readline.
374 # Do not allow PYTHONSTARTUP to set up readline.
373 if self.shell.has_readline:
375 if self.shell.has_readline:
374 self.shell.set_readline_completer()
376 self.shell.set_readline_completer()
375
377
376 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
378 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
377 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
379 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
378 if not startup_files:
380 if not startup_files:
379 return
381 return
380
382
381 self.log.debug("Running startup files from %s...", startup_dir)
383 self.log.debug("Running startup files from %s...", startup_dir)
382 try:
384 try:
383 for fname in sorted(startup_files):
385 for fname in sorted(startup_files):
384 self._exec_file(fname)
386 self._exec_file(fname)
385 except:
387 except:
386 self.log.warning("Unknown error in handling startup files:")
388 self.log.warning("Unknown error in handling startup files:")
387 self.shell.showtraceback()
389 self.shell.showtraceback()
388
390
389 def _run_exec_files(self):
391 def _run_exec_files(self):
390 """Run files from IPythonApp.exec_files"""
392 """Run files from IPythonApp.exec_files"""
391 if not self.exec_files:
393 if not self.exec_files:
392 return
394 return
393
395
394 self.log.debug("Running files in IPythonApp.exec_files...")
396 self.log.debug("Running files in IPythonApp.exec_files...")
395 try:
397 try:
396 for fname in self.exec_files:
398 for fname in self.exec_files:
397 self._exec_file(fname)
399 self._exec_file(fname)
398 except:
400 except:
399 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
401 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
400 self.shell.showtraceback()
402 self.shell.showtraceback()
401
403
402 def _run_cmd_line_code(self):
404 def _run_cmd_line_code(self):
403 """Run code or file specified at the command-line"""
405 """Run code or file specified at the command-line"""
404 if self.code_to_run:
406 if self.code_to_run:
405 line = self.code_to_run
407 line = self.code_to_run
406 try:
408 try:
407 self.log.info("Running code given at command line (c=): %s" %
409 self.log.info("Running code given at command line (c=): %s" %
408 line)
410 line)
409 self.shell.run_cell(line, store_history=False)
411 self.shell.run_cell(line, store_history=False)
410 except:
412 except:
411 self.log.warning("Error in executing line in user namespace: %s" %
413 self.log.warning("Error in executing line in user namespace: %s" %
412 line)
414 line)
413 self.shell.showtraceback()
415 self.shell.showtraceback()
414
416
415 # Like Python itself, ignore the second if the first of these is present
417 # Like Python itself, ignore the second if the first of these is present
416 elif self.file_to_run:
418 elif self.file_to_run:
417 fname = self.file_to_run
419 fname = self.file_to_run
418 try:
420 try:
419 self._exec_file(fname, shell_futures=True)
421 self._exec_file(fname, shell_futures=True)
420 except:
422 except:
421 self.shell.showtraceback(tb_offset=4)
423 self.shell.showtraceback(tb_offset=4)
422 self.exit(1)
424 self.exit(1)
423
425
424 def _run_module(self):
426 def _run_module(self):
425 """Run module specified at the command-line."""
427 """Run module specified at the command-line."""
426 if self.module_to_run:
428 if self.module_to_run:
427 # Make sure that the module gets a proper sys.argv as if it were
429 # Make sure that the module gets a proper sys.argv as if it were
428 # run using `python -m`.
430 # run using `python -m`.
429 save_argv = sys.argv
431 save_argv = sys.argv
430 sys.argv = [sys.executable] + self.extra_args
432 sys.argv = [sys.executable] + self.extra_args
431 try:
433 try:
432 self.shell.safe_run_module(self.module_to_run,
434 self.shell.safe_run_module(self.module_to_run,
433 self.shell.user_ns)
435 self.shell.user_ns)
434 finally:
436 finally:
435 sys.argv = save_argv
437 sys.argv = save_argv
@@ -1,369 +1,368 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 """
3 """
4 The :class:`~IPython.core.application.Application` object for the command
4 The :class:`~IPython.core.application.Application` object for the command
5 line :command:`ipython` program.
5 line :command:`ipython` program.
6 """
6 """
7
7
8 # Copyright (c) IPython Development Team.
8 # Copyright (c) IPython Development Team.
9 # Distributed under the terms of the Modified BSD License.
9 # Distributed under the terms of the Modified BSD License.
10
10
11 from __future__ import absolute_import
11 from __future__ import absolute_import
12 from __future__ import print_function
12 from __future__ import print_function
13
13
14 import logging
14 import logging
15 import os
15 import os
16 import sys
16 import sys
17
17
18 from traitlets.config.loader import Config
18 from traitlets.config.loader import Config
19 from traitlets.config.application import boolean_flag, catch_config_error, Application
19 from traitlets.config.application import boolean_flag, catch_config_error, Application
20 from IPython.core import release
20 from IPython.core import release
21 from IPython.core import usage
21 from IPython.core import usage
22 from IPython.core.completer import IPCompleter
22 from IPython.core.completer import IPCompleter
23 from IPython.core.crashhandler import CrashHandler
23 from IPython.core.crashhandler import CrashHandler
24 from IPython.core.formatters import PlainTextFormatter
24 from IPython.core.formatters import PlainTextFormatter
25 from IPython.core.history import HistoryManager
25 from IPython.core.history import HistoryManager
26 from IPython.core.prompts import PromptManager
26 from IPython.core.prompts import PromptManager
27 from IPython.core.application import (
27 from IPython.core.application import (
28 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
28 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
29 )
29 )
30 from IPython.core.magics import ScriptMagics
30 from IPython.core.magics import ScriptMagics
31 from IPython.core.shellapp import (
31 from IPython.core.shellapp import (
32 InteractiveShellApp, shell_flags, shell_aliases
32 InteractiveShellApp, shell_flags, shell_aliases
33 )
33 )
34 from IPython.extensions.storemagic import StoreMagics
34 from IPython.extensions.storemagic import StoreMagics
35 from IPython.terminal.interactiveshell import TerminalInteractiveShell
35 from IPython.terminal.interactiveshell import TerminalInteractiveShell
36 from IPython.utils import warn
36 from IPython.utils import warn
37 from IPython.paths import get_ipython_dir
37 from IPython.paths import get_ipython_dir
38 from traitlets import (
38 from traitlets import (
39 Bool, List, Dict,
39 Bool, List, Dict,
40 )
40 )
41
41
42 #-----------------------------------------------------------------------------
42 #-----------------------------------------------------------------------------
43 # Globals, utilities and helpers
43 # Globals, utilities and helpers
44 #-----------------------------------------------------------------------------
44 #-----------------------------------------------------------------------------
45
45
46 _examples = """
46 _examples = """
47 ipython --matplotlib # enable matplotlib integration
47 ipython --matplotlib # enable matplotlib integration
48 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
48 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
49
49
50 ipython --log-level=DEBUG # set logging to DEBUG
50 ipython --log-level=DEBUG # set logging to DEBUG
51 ipython --profile=foo # start with profile foo
51 ipython --profile=foo # start with profile foo
52
52
53 ipython profile create foo # create profile foo w/ default config files
53 ipython profile create foo # create profile foo w/ default config files
54 ipython help profile # show the help for the profile subcmd
54 ipython help profile # show the help for the profile subcmd
55
55
56 ipython locate # print the path to the IPython directory
56 ipython locate # print the path to the IPython directory
57 ipython locate profile foo # print the path to the directory for profile `foo`
57 ipython locate profile foo # print the path to the directory for profile `foo`
58 """
58 """
59
59
60 #-----------------------------------------------------------------------------
60 #-----------------------------------------------------------------------------
61 # Crash handler for this application
61 # Crash handler for this application
62 #-----------------------------------------------------------------------------
62 #-----------------------------------------------------------------------------
63
63
64 class IPAppCrashHandler(CrashHandler):
64 class IPAppCrashHandler(CrashHandler):
65 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
65 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
66
66
67 def __init__(self, app):
67 def __init__(self, app):
68 contact_name = release.author
68 contact_name = release.author
69 contact_email = release.author_email
69 contact_email = release.author_email
70 bug_tracker = 'https://github.com/ipython/ipython/issues'
70 bug_tracker = 'https://github.com/ipython/ipython/issues'
71 super(IPAppCrashHandler,self).__init__(
71 super(IPAppCrashHandler,self).__init__(
72 app, contact_name, contact_email, bug_tracker
72 app, contact_name, contact_email, bug_tracker
73 )
73 )
74
74
75 def make_report(self,traceback):
75 def make_report(self,traceback):
76 """Return a string containing a crash report."""
76 """Return a string containing a crash report."""
77
77
78 sec_sep = self.section_sep
78 sec_sep = self.section_sep
79 # Start with parent report
79 # Start with parent report
80 report = [super(IPAppCrashHandler, self).make_report(traceback)]
80 report = [super(IPAppCrashHandler, self).make_report(traceback)]
81 # Add interactive-specific info we may have
81 # Add interactive-specific info we may have
82 rpt_add = report.append
82 rpt_add = report.append
83 try:
83 try:
84 rpt_add(sec_sep+"History of session input:")
84 rpt_add(sec_sep+"History of session input:")
85 for line in self.app.shell.user_ns['_ih']:
85 for line in self.app.shell.user_ns['_ih']:
86 rpt_add(line)
86 rpt_add(line)
87 rpt_add('\n*** Last line of input (may not be in above history):\n')
87 rpt_add('\n*** Last line of input (may not be in above history):\n')
88 rpt_add(self.app.shell._last_input_line+'\n')
88 rpt_add(self.app.shell._last_input_line+'\n')
89 except:
89 except:
90 pass
90 pass
91
91
92 return ''.join(report)
92 return ''.join(report)
93
93
94 #-----------------------------------------------------------------------------
94 #-----------------------------------------------------------------------------
95 # Aliases and Flags
95 # Aliases and Flags
96 #-----------------------------------------------------------------------------
96 #-----------------------------------------------------------------------------
97 flags = dict(base_flags)
97 flags = dict(base_flags)
98 flags.update(shell_flags)
98 flags.update(shell_flags)
99 frontend_flags = {}
99 frontend_flags = {}
100 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
100 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
101 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
101 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
102 'Turn on auto editing of files with syntax errors.',
102 'Turn on auto editing of files with syntax errors.',
103 'Turn off auto editing of files with syntax errors.'
103 'Turn off auto editing of files with syntax errors.'
104 )
104 )
105 addflag('banner', 'TerminalIPythonApp.display_banner',
105 addflag('banner', 'TerminalIPythonApp.display_banner',
106 "Display a banner upon starting IPython.",
106 "Display a banner upon starting IPython.",
107 "Don't display a banner upon starting IPython."
107 "Don't display a banner upon starting IPython."
108 )
108 )
109 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
109 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
110 """Set to confirm when you try to exit IPython with an EOF (Control-D
110 """Set to confirm when you try to exit IPython with an EOF (Control-D
111 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
111 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
112 you can force a direct exit without any confirmation.""",
112 you can force a direct exit without any confirmation.""",
113 "Don't prompt the user when exiting."
113 "Don't prompt the user when exiting."
114 )
114 )
115 addflag('term-title', 'TerminalInteractiveShell.term_title',
115 addflag('term-title', 'TerminalInteractiveShell.term_title',
116 "Enable auto setting the terminal title.",
116 "Enable auto setting the terminal title.",
117 "Disable auto setting the terminal title."
117 "Disable auto setting the terminal title."
118 )
118 )
119 classic_config = Config()
119 classic_config = Config()
120 classic_config.InteractiveShell.cache_size = 0
120 classic_config.InteractiveShell.cache_size = 0
121 classic_config.PlainTextFormatter.pprint = False
121 classic_config.PlainTextFormatter.pprint = False
122 classic_config.PromptManager.in_template = '>>> '
122 classic_config.PromptManager.in_template = '>>> '
123 classic_config.PromptManager.in2_template = '... '
123 classic_config.PromptManager.in2_template = '... '
124 classic_config.PromptManager.out_template = ''
124 classic_config.PromptManager.out_template = ''
125 classic_config.InteractiveShell.separate_in = ''
125 classic_config.InteractiveShell.separate_in = ''
126 classic_config.InteractiveShell.separate_out = ''
126 classic_config.InteractiveShell.separate_out = ''
127 classic_config.InteractiveShell.separate_out2 = ''
127 classic_config.InteractiveShell.separate_out2 = ''
128 classic_config.InteractiveShell.colors = 'NoColor'
128 classic_config.InteractiveShell.colors = 'NoColor'
129 classic_config.InteractiveShell.xmode = 'Plain'
129 classic_config.InteractiveShell.xmode = 'Plain'
130
130
131 frontend_flags['classic']=(
131 frontend_flags['classic']=(
132 classic_config,
132 classic_config,
133 "Gives IPython a similar feel to the classic Python prompt."
133 "Gives IPython a similar feel to the classic Python prompt."
134 )
134 )
135 # # log doesn't make so much sense this way anymore
135 # # log doesn't make so much sense this way anymore
136 # paa('--log','-l',
136 # paa('--log','-l',
137 # action='store_true', dest='InteractiveShell.logstart',
137 # action='store_true', dest='InteractiveShell.logstart',
138 # help="Start logging to the default log file (./ipython_log.py).")
138 # help="Start logging to the default log file (./ipython_log.py).")
139 #
139 #
140 # # quick is harder to implement
140 # # quick is harder to implement
141 frontend_flags['quick']=(
141 frontend_flags['quick']=(
142 {'TerminalIPythonApp' : {'quick' : True}},
142 {'TerminalIPythonApp' : {'quick' : True}},
143 "Enable quick startup with no config files."
143 "Enable quick startup with no config files."
144 )
144 )
145
145
146 frontend_flags['i'] = (
146 frontend_flags['i'] = (
147 {'TerminalIPythonApp' : {'force_interact' : True}},
147 {'TerminalIPythonApp' : {'force_interact' : True}},
148 """If running code from the command line, become interactive afterwards.
148 """If running code from the command line, become interactive afterwards.
149 It is often useful to follow this with `--` to treat remaining flags as
149 It is often useful to follow this with `--` to treat remaining flags as
150 script arguments.
150 script arguments.
151 """
151 """
152 )
152 )
153 flags.update(frontend_flags)
153 flags.update(frontend_flags)
154
154
155 aliases = dict(base_aliases)
155 aliases = dict(base_aliases)
156 aliases.update(shell_aliases)
156 aliases.update(shell_aliases)
157
157
158 #-----------------------------------------------------------------------------
158 #-----------------------------------------------------------------------------
159 # Main classes and functions
159 # Main classes and functions
160 #-----------------------------------------------------------------------------
160 #-----------------------------------------------------------------------------
161
161
162
162
163 class LocateIPythonApp(BaseIPythonApplication):
163 class LocateIPythonApp(BaseIPythonApplication):
164 description = """print the path to the IPython dir"""
164 description = """print the path to the IPython dir"""
165 subcommands = Dict(dict(
165 subcommands = Dict(dict(
166 profile=('IPython.core.profileapp.ProfileLocate',
166 profile=('IPython.core.profileapp.ProfileLocate',
167 "print the path to an IPython profile directory",
167 "print the path to an IPython profile directory",
168 ),
168 ),
169 ))
169 ))
170 def start(self):
170 def start(self):
171 if self.subapp is not None:
171 if self.subapp is not None:
172 return self.subapp.start()
172 return self.subapp.start()
173 else:
173 else:
174 print(self.ipython_dir)
174 print(self.ipython_dir)
175
175
176
176
177 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
177 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
178 name = u'ipython'
178 name = u'ipython'
179 description = usage.cl_usage
179 description = usage.cl_usage
180 crash_handler_class = IPAppCrashHandler
180 crash_handler_class = IPAppCrashHandler
181 examples = _examples
181 examples = _examples
182
182
183 flags = Dict(flags)
183 flags = Dict(flags)
184 aliases = Dict(aliases)
184 aliases = Dict(aliases)
185 classes = List()
185 classes = List()
186 def _classes_default(self):
186 def _classes_default(self):
187 """This has to be in a method, for TerminalIPythonApp to be available."""
187 """This has to be in a method, for TerminalIPythonApp to be available."""
188 return [
188 return [
189 InteractiveShellApp, # ShellApp comes before TerminalApp, because
189 InteractiveShellApp, # ShellApp comes before TerminalApp, because
190 self.__class__, # it will also affect subclasses (e.g. QtConsole)
190 self.__class__, # it will also affect subclasses (e.g. QtConsole)
191 TerminalInteractiveShell,
191 TerminalInteractiveShell,
192 PromptManager,
192 PromptManager,
193 HistoryManager,
193 HistoryManager,
194 ProfileDir,
194 ProfileDir,
195 PlainTextFormatter,
195 PlainTextFormatter,
196 IPCompleter,
196 IPCompleter,
197 ScriptMagics,
197 ScriptMagics,
198 StoreMagics,
198 StoreMagics,
199 ]
199 ]
200
200
201 deprecated_subcommands = dict(
201 deprecated_subcommands = dict(
202 qtconsole=('qtconsole.qtconsoleapp.JupyterQtConsoleApp',
202 qtconsole=('qtconsole.qtconsoleapp.JupyterQtConsoleApp',
203 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter Qt Console."""
203 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter Qt Console."""
204 ),
204 ),
205 notebook=('notebook.notebookapp.NotebookApp',
205 notebook=('notebook.notebookapp.NotebookApp',
206 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter HTML Notebook Server."""
206 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter HTML Notebook Server."""
207 ),
207 ),
208 console=('jupyter_console.app.ZMQTerminalIPythonApp',
208 console=('jupyter_console.app.ZMQTerminalIPythonApp',
209 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter terminal-based Console."""
209 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter terminal-based Console."""
210 ),
210 ),
211 nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
211 nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
212 "DEPRECATED, Will be removed in IPython 6.0 : Convert notebooks to/from other formats."
212 "DEPRECATED, Will be removed in IPython 6.0 : Convert notebooks to/from other formats."
213 ),
213 ),
214 trust=('nbformat.sign.TrustNotebookApp',
214 trust=('nbformat.sign.TrustNotebookApp',
215 "DEPRECATED, Will be removed in IPython 6.0 : Sign notebooks to trust their potentially unsafe contents at load."
215 "DEPRECATED, Will be removed in IPython 6.0 : Sign notebooks to trust their potentially unsafe contents at load."
216 ),
216 ),
217 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
217 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
218 "DEPRECATED, Will be removed in IPython 6.0 : Manage Jupyter kernel specifications."
218 "DEPRECATED, Will be removed in IPython 6.0 : Manage Jupyter kernel specifications."
219 ),
219 ),
220 )
220 )
221 subcommands = dict(
221 subcommands = dict(
222 profile = ("IPython.core.profileapp.ProfileApp",
222 profile = ("IPython.core.profileapp.ProfileApp",
223 "Create and manage IPython profiles."
223 "Create and manage IPython profiles."
224 ),
224 ),
225 kernel = ("ipykernel.kernelapp.IPKernelApp",
225 kernel = ("ipykernel.kernelapp.IPKernelApp",
226 "Start a kernel without an attached frontend."
226 "Start a kernel without an attached frontend."
227 ),
227 ),
228 locate=('IPython.terminal.ipapp.LocateIPythonApp',
228 locate=('IPython.terminal.ipapp.LocateIPythonApp',
229 LocateIPythonApp.description
229 LocateIPythonApp.description
230 ),
230 ),
231 history=('IPython.core.historyapp.HistoryApp',
231 history=('IPython.core.historyapp.HistoryApp',
232 "Manage the IPython history database."
232 "Manage the IPython history database."
233 ),
233 ),
234 )
234 )
235 deprecated_subcommands['install-nbextension'] = (
235 deprecated_subcommands['install-nbextension'] = (
236 "notebook.nbextensions.InstallNBExtensionApp",
236 "notebook.nbextensions.InstallNBExtensionApp",
237 "DEPRECATED, Will be removed in IPython 6.0 : Install Jupyter notebook extension files"
237 "DEPRECATED, Will be removed in IPython 6.0 : Install Jupyter notebook extension files"
238 )
238 )
239 subcommands.update(deprecated_subcommands)
239 subcommands.update(deprecated_subcommands)
240
240
241 # *do* autocreate requested profile, but don't create the config file.
241 # *do* autocreate requested profile, but don't create the config file.
242 auto_create=Bool(True)
242 auto_create=Bool(True)
243 # configurables
243 # configurables
244 quick = Bool(False, config=True,
244 quick = Bool(False, config=True,
245 help="""Start IPython quickly by skipping the loading of config files."""
245 help="""Start IPython quickly by skipping the loading of config files."""
246 )
246 )
247 def _quick_changed(self, name, old, new):
247 def _quick_changed(self, name, old, new):
248 if new:
248 if new:
249 self.load_config_file = lambda *a, **kw: None
249 self.load_config_file = lambda *a, **kw: None
250
250
251 display_banner = Bool(True, config=True,
251 display_banner = Bool(True, config=True,
252 help="Whether to display a banner upon starting IPython."
252 help="Whether to display a banner upon starting IPython."
253 )
253 )
254
254
255 # if there is code of files to run from the cmd line, don't interact
255 # if there is code of files to run from the cmd line, don't interact
256 # unless the --i flag (App.force_interact) is true.
256 # unless the --i flag (App.force_interact) is true.
257 force_interact = Bool(False, config=True,
257 force_interact = Bool(False, config=True,
258 help="""If a command or file is given via the command-line,
258 help="""If a command or file is given via the command-line,
259 e.g. 'ipython foo.py', start an interactive shell after executing the
259 e.g. 'ipython foo.py', start an interactive shell after executing the
260 file or command."""
260 file or command."""
261 )
261 )
262 def _force_interact_changed(self, name, old, new):
262 def _force_interact_changed(self, name, old, new):
263 if new:
263 if new:
264 self.interact = True
264 self.interact = True
265
265
266 def _file_to_run_changed(self, name, old, new):
266 def _file_to_run_changed(self, name, old, new):
267 if new:
267 if new:
268 self.something_to_run = True
268 self.something_to_run = True
269 if new and not self.force_interact:
269 if new and not self.force_interact:
270 self.interact = False
270 self.interact = False
271 _code_to_run_changed = _file_to_run_changed
271 _code_to_run_changed = _file_to_run_changed
272 _module_to_run_changed = _file_to_run_changed
272 _module_to_run_changed = _file_to_run_changed
273
273
274 # internal, not-configurable
274 # internal, not-configurable
275 interact=Bool(True)
276 something_to_run=Bool(False)
275 something_to_run=Bool(False)
277
276
278 def parse_command_line(self, argv=None):
277 def parse_command_line(self, argv=None):
279 """override to allow old '-pylab' flag with deprecation warning"""
278 """override to allow old '-pylab' flag with deprecation warning"""
280
279
281 argv = sys.argv[1:] if argv is None else argv
280 argv = sys.argv[1:] if argv is None else argv
282
281
283 if '-pylab' in argv:
282 if '-pylab' in argv:
284 # deprecated `-pylab` given,
283 # deprecated `-pylab` given,
285 # warn and transform into current syntax
284 # warn and transform into current syntax
286 argv = argv[:] # copy, don't clobber
285 argv = argv[:] # copy, don't clobber
287 idx = argv.index('-pylab')
286 idx = argv.index('-pylab')
288 warn.warn("`-pylab` flag has been deprecated.\n"
287 warn.warn("`-pylab` flag has been deprecated.\n"
289 " Use `--matplotlib <backend>` and import pylab manually.")
288 " Use `--matplotlib <backend>` and import pylab manually.")
290 argv[idx] = '--pylab'
289 argv[idx] = '--pylab'
291
290
292 return super(TerminalIPythonApp, self).parse_command_line(argv)
291 return super(TerminalIPythonApp, self).parse_command_line(argv)
293
292
294 @catch_config_error
293 @catch_config_error
295 def initialize(self, argv=None):
294 def initialize(self, argv=None):
296 """Do actions after construct, but before starting the app."""
295 """Do actions after construct, but before starting the app."""
297 super(TerminalIPythonApp, self).initialize(argv)
296 super(TerminalIPythonApp, self).initialize(argv)
298 if self.subapp is not None:
297 if self.subapp is not None:
299 # don't bother initializing further, starting subapp
298 # don't bother initializing further, starting subapp
300 return
299 return
301 # print self.extra_args
300 # print self.extra_args
302 if self.extra_args and not self.something_to_run:
301 if self.extra_args and not self.something_to_run:
303 self.file_to_run = self.extra_args[0]
302 self.file_to_run = self.extra_args[0]
304 self.init_path()
303 self.init_path()
305 # create the shell
304 # create the shell
306 self.init_shell()
305 self.init_shell()
307 # and draw the banner
306 # and draw the banner
308 self.init_banner()
307 self.init_banner()
309 # Now a variety of things that happen after the banner is printed.
308 # Now a variety of things that happen after the banner is printed.
310 self.init_gui_pylab()
309 self.init_gui_pylab()
311 self.init_extensions()
310 self.init_extensions()
312 self.init_code()
311 self.init_code()
313
312
314 def init_shell(self):
313 def init_shell(self):
315 """initialize the InteractiveShell instance"""
314 """initialize the InteractiveShell instance"""
316 # Create an InteractiveShell instance.
315 # Create an InteractiveShell instance.
317 # shell.display_banner should always be False for the terminal
316 # shell.display_banner should always be False for the terminal
318 # based app, because we call shell.show_banner() by hand below
317 # based app, because we call shell.show_banner() by hand below
319 # so the banner shows *before* all extension loading stuff.
318 # so the banner shows *before* all extension loading stuff.
320 self.shell = TerminalInteractiveShell.instance(parent=self,
319 self.shell = TerminalInteractiveShell.instance(parent=self,
321 display_banner=False, profile_dir=self.profile_dir,
320 display_banner=False, profile_dir=self.profile_dir,
322 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
321 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
323 self.shell.configurables.append(self)
322 self.shell.configurables.append(self)
324
323
325 def init_banner(self):
324 def init_banner(self):
326 """optionally display the banner"""
325 """optionally display the banner"""
327 if self.display_banner and self.interact:
326 if self.display_banner and self.interact:
328 self.shell.show_banner()
327 self.shell.show_banner()
329 # Make sure there is a space below the banner.
328 # Make sure there is a space below the banner.
330 if self.log_level <= logging.INFO: print()
329 if self.log_level <= logging.INFO: print()
331
330
332 def _pylab_changed(self, name, old, new):
331 def _pylab_changed(self, name, old, new):
333 """Replace --pylab='inline' with --pylab='auto'"""
332 """Replace --pylab='inline' with --pylab='auto'"""
334 if new == 'inline':
333 if new == 'inline':
335 warn.warn("'inline' not available as pylab backend, "
334 warn.warn("'inline' not available as pylab backend, "
336 "using 'auto' instead.")
335 "using 'auto' instead.")
337 self.pylab = 'auto'
336 self.pylab = 'auto'
338
337
339 def start(self):
338 def start(self):
340 if self.subapp is not None:
339 if self.subapp is not None:
341 return self.subapp.start()
340 return self.subapp.start()
342 # perform any prexec steps:
341 # perform any prexec steps:
343 if self.interact:
342 if self.interact:
344 self.log.debug("Starting IPython's mainloop...")
343 self.log.debug("Starting IPython's mainloop...")
345 self.shell.mainloop()
344 self.shell.mainloop()
346 else:
345 else:
347 self.log.debug("IPython not interactive...")
346 self.log.debug("IPython not interactive...")
348
347
349 def load_default_config(ipython_dir=None):
348 def load_default_config(ipython_dir=None):
350 """Load the default config file from the default ipython_dir.
349 """Load the default config file from the default ipython_dir.
351
350
352 This is useful for embedded shells.
351 This is useful for embedded shells.
353 """
352 """
354 if ipython_dir is None:
353 if ipython_dir is None:
355 ipython_dir = get_ipython_dir()
354 ipython_dir = get_ipython_dir()
356
355
357 profile_dir = os.path.join(ipython_dir, 'profile_default')
356 profile_dir = os.path.join(ipython_dir, 'profile_default')
358
357
359 config = Config()
358 config = Config()
360 for cf in Application._load_config_files("ipython_config", path=profile_dir):
359 for cf in Application._load_config_files("ipython_config", path=profile_dir):
361 config.update(cf)
360 config.update(cf)
362
361
363 return config
362 return config
364
363
365 launch_new_instance = TerminalIPythonApp.launch_instance
364 launch_new_instance = TerminalIPythonApp.launch_instance
366
365
367
366
368 if __name__ == '__main__':
367 if __name__ == '__main__':
369 launch_new_instance()
368 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now