##// END OF EJS Templates
Actually warn that `ipython <subcommand>` is deprecated....
Matthias Bussonnier -
Show More
@@ -1,397 +1,407 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for IPython.
4 4
5 5 All top-level applications should use the classes in this module for
6 6 handling configuration and creating configurables.
7 7
8 8 The job of an :class:`Application` is to create the master configuration
9 9 object and then create the configurable objects, passing the config to them.
10 10 """
11 11
12 12 # Copyright (c) IPython Development Team.
13 13 # Distributed under the terms of the Modified BSD License.
14 14
15 15 import atexit
16 16 import glob
17 17 import logging
18 18 import os
19 19 import shutil
20 20 import sys
21 21
22 22 from traitlets.config.application import Application, catch_config_error
23 23 from traitlets.config.loader import ConfigFileNotFound, PyFileConfigLoader
24 24 from IPython.core import release, crashhandler
25 25 from IPython.core.profiledir import ProfileDir, ProfileDirError
26 26 from IPython.paths import get_ipython_dir, get_ipython_package_dir
27 27 from IPython.utils.path import ensure_dir_exists
28 28 from IPython.utils import py3compat
29 29 from traitlets import List, Unicode, Type, Bool, Dict, Set, Instance, Undefined
30 30
31 31 if os.name == 'nt':
32 32 programdata = os.environ.get('PROGRAMDATA', None)
33 33 if programdata:
34 34 SYSTEM_CONFIG_DIRS = [os.path.join(programdata, 'ipython')]
35 35 else: # PROGRAMDATA is not defined by default on XP.
36 36 SYSTEM_CONFIG_DIRS = []
37 37 else:
38 38 SYSTEM_CONFIG_DIRS = [
39 39 "/usr/local/etc/ipython",
40 40 "/etc/ipython",
41 41 ]
42 42
43 43
44 44 # aliases and flags
45 45
46 46 base_aliases = {
47 47 'profile-dir' : 'ProfileDir.location',
48 48 'profile' : 'BaseIPythonApplication.profile',
49 49 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
50 50 'log-level' : 'Application.log_level',
51 51 'config' : 'BaseIPythonApplication.extra_config_file',
52 52 }
53 53
54 54 base_flags = dict(
55 55 debug = ({'Application' : {'log_level' : logging.DEBUG}},
56 56 "set log level to logging.DEBUG (maximize logging output)"),
57 57 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
58 58 "set log level to logging.CRITICAL (minimize logging output)"),
59 59 init = ({'BaseIPythonApplication' : {
60 60 'copy_config_files' : True,
61 61 'auto_create' : True}
62 62 }, """Initialize profile with default config files. This is equivalent
63 63 to running `ipython profile create <profile>` prior to startup.
64 64 """)
65 65 )
66 66
67 67 class ProfileAwareConfigLoader(PyFileConfigLoader):
68 68 """A Python file config loader that is aware of IPython profiles."""
69 69 def load_subconfig(self, fname, path=None, profile=None):
70 70 if profile is not None:
71 71 try:
72 72 profile_dir = ProfileDir.find_profile_dir_by_name(
73 73 get_ipython_dir(),
74 74 profile,
75 75 )
76 76 except ProfileDirError:
77 77 return
78 78 path = profile_dir.location
79 79 return super(ProfileAwareConfigLoader, self).load_subconfig(fname, path=path)
80 80
81 81 class BaseIPythonApplication(Application):
82 82
83 83 name = Unicode(u'ipython')
84 84 description = Unicode(u'IPython: an enhanced interactive Python shell.')
85 85 version = Unicode(release.version)
86 86
87 87 aliases = Dict(base_aliases)
88 88 flags = Dict(base_flags)
89 89 classes = List([ProfileDir])
90 90
91 91 # enable `load_subconfig('cfg.py', profile='name')`
92 92 python_config_loader_class = ProfileAwareConfigLoader
93 93
94 94 # Track whether the config_file has changed,
95 95 # because some logic happens only if we aren't using the default.
96 96 config_file_specified = Set()
97 97
98 98 config_file_name = Unicode()
99 99 def _config_file_name_default(self):
100 100 return self.name.replace('-','_') + u'_config.py'
101 101 def _config_file_name_changed(self, name, old, new):
102 102 if new != old:
103 103 self.config_file_specified.add(new)
104 104
105 105 # The directory that contains IPython's builtin profiles.
106 106 builtin_profile_dir = Unicode(
107 107 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
108 108 )
109 109
110 110 config_file_paths = List(Unicode())
111 111 def _config_file_paths_default(self):
112 112 return [py3compat.getcwd()]
113 113
114 114 extra_config_file = Unicode(config=True,
115 115 help="""Path to an extra config file to load.
116 116
117 117 If specified, load this config file in addition to any other IPython config.
118 118 """)
119 119 def _extra_config_file_changed(self, name, old, new):
120 120 try:
121 121 self.config_files.remove(old)
122 122 except ValueError:
123 123 pass
124 124 self.config_file_specified.add(new)
125 125 self.config_files.append(new)
126 126
127 127 profile = Unicode(u'default', config=True,
128 128 help="""The IPython profile to use."""
129 129 )
130 130
131 131 def _profile_changed(self, name, old, new):
132 132 self.builtin_profile_dir = os.path.join(
133 133 get_ipython_package_dir(), u'config', u'profile', new
134 134 )
135 135
136 136 ipython_dir = Unicode(config=True,
137 137 help="""
138 138 The name of the IPython directory. This directory is used for logging
139 139 configuration (through profiles), history storage, etc. The default
140 140 is usually $HOME/.ipython. This option can also be specified through
141 141 the environment variable IPYTHONDIR.
142 142 """
143 143 )
144 144 def _ipython_dir_default(self):
145 145 d = get_ipython_dir()
146 146 self._ipython_dir_changed('ipython_dir', d, d)
147 147 return d
148 148
149 149 _in_init_profile_dir = False
150 150 profile_dir = Instance(ProfileDir, allow_none=True)
151 151 def _profile_dir_default(self):
152 152 # avoid recursion
153 153 if self._in_init_profile_dir:
154 154 return
155 155 # profile_dir requested early, force initialization
156 156 self.init_profile_dir()
157 157 return self.profile_dir
158 158
159 159 overwrite = Bool(False, config=True,
160 160 help="""Whether to overwrite existing config files when copying""")
161 161 auto_create = Bool(False, config=True,
162 162 help="""Whether to create profile dir if it doesn't exist""")
163 163
164 164 config_files = List(Unicode())
165 165 def _config_files_default(self):
166 166 return [self.config_file_name]
167 167
168 168 copy_config_files = Bool(False, config=True,
169 169 help="""Whether to install the default config files into the profile dir.
170 170 If a new profile is being created, and IPython contains config files for that
171 171 profile, then they will be staged into the new directory. Otherwise,
172 172 default config files will be automatically generated.
173 173 """)
174 174
175 175 verbose_crash = Bool(False, config=True,
176 176 help="""Create a massive crash report when IPython encounters what may be an
177 177 internal error. The default is to append a short message to the
178 178 usual traceback""")
179 179
180 180 # The class to use as the crash handler.
181 181 crash_handler_class = Type(crashhandler.CrashHandler)
182 182
183 183 @catch_config_error
184 184 def __init__(self, **kwargs):
185 185 super(BaseIPythonApplication, self).__init__(**kwargs)
186 186 # ensure current working directory exists
187 187 try:
188 directory = py3compat.getcwd()
188 py3compat.getcwd()
189 189 except:
190 190 # exit if cwd doesn't exist
191 191 self.log.error("Current working directory doesn't exist.")
192 192 self.exit(1)
193 193
194 194 #-------------------------------------------------------------------------
195 195 # Various stages of Application creation
196 196 #-------------------------------------------------------------------------
197 197
198 def initialize_subcommand(self, subc, argv=None):
199 if subc in self.deprecated_subcommands:
200 import time
201 self.log.warning("Subcommand `ipython {sub}` is deprecated and will be removed "
202 "in future versions.".format(sub=subc))
203 self.log.warning("You likely want to use `jupyter {sub}`... continue "
204 "in 5 sec".format(sub=subc))
205 time.sleep(5)
206 return super(BaseIPythonApplication, self).initialize_subcommand(subc, argv)
207
198 208 def init_crash_handler(self):
199 209 """Create a crash handler, typically setting sys.excepthook to it."""
200 210 self.crash_handler = self.crash_handler_class(self)
201 211 sys.excepthook = self.excepthook
202 212 def unset_crashhandler():
203 213 sys.excepthook = sys.__excepthook__
204 214 atexit.register(unset_crashhandler)
205 215
206 216 def excepthook(self, etype, evalue, tb):
207 217 """this is sys.excepthook after init_crashhandler
208 218
209 219 set self.verbose_crash=True to use our full crashhandler, instead of
210 220 a regular traceback with a short message (crash_handler_lite)
211 221 """
212 222
213 223 if self.verbose_crash:
214 224 return self.crash_handler(etype, evalue, tb)
215 225 else:
216 226 return crashhandler.crash_handler_lite(etype, evalue, tb)
217 227
218 228 def _ipython_dir_changed(self, name, old, new):
219 229 if old is not Undefined:
220 230 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
221 231 sys.getfilesystemencoding()
222 232 )
223 233 if str_old in sys.path:
224 234 sys.path.remove(str_old)
225 235 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
226 236 sys.getfilesystemencoding()
227 237 )
228 238 sys.path.append(str_path)
229 239 ensure_dir_exists(new)
230 240 readme = os.path.join(new, 'README')
231 241 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
232 242 if not os.path.exists(readme) and os.path.exists(readme_src):
233 243 shutil.copy(readme_src, readme)
234 244 for d in ('extensions', 'nbextensions'):
235 245 path = os.path.join(new, d)
236 246 try:
237 247 ensure_dir_exists(path)
238 248 except OSError as e:
239 249 # this will not be EEXIST
240 250 self.log.error("couldn't create path %s: %s", path, e)
241 251 self.log.debug("IPYTHONDIR set to: %s" % new)
242 252
243 253 def load_config_file(self, suppress_errors=True):
244 254 """Load the config file.
245 255
246 256 By default, errors in loading config are handled, and a warning
247 257 printed on screen. For testing, the suppress_errors option is set
248 258 to False, so errors will make tests fail.
249 259 """
250 260 self.log.debug("Searching path %s for config files", self.config_file_paths)
251 261 base_config = 'ipython_config.py'
252 262 self.log.debug("Attempting to load config file: %s" %
253 263 base_config)
254 264 try:
255 265 Application.load_config_file(
256 266 self,
257 267 base_config,
258 268 path=self.config_file_paths
259 269 )
260 270 except ConfigFileNotFound:
261 271 # ignore errors loading parent
262 272 self.log.debug("Config file %s not found", base_config)
263 273 pass
264 274
265 275 for config_file_name in self.config_files:
266 276 if not config_file_name or config_file_name == base_config:
267 277 continue
268 278 self.log.debug("Attempting to load config file: %s" %
269 279 self.config_file_name)
270 280 try:
271 281 Application.load_config_file(
272 282 self,
273 283 config_file_name,
274 284 path=self.config_file_paths
275 285 )
276 286 except ConfigFileNotFound:
277 287 # Only warn if the default config file was NOT being used.
278 288 if config_file_name in self.config_file_specified:
279 289 msg = self.log.warn
280 290 else:
281 291 msg = self.log.debug
282 292 msg("Config file not found, skipping: %s", config_file_name)
283 293 except Exception:
284 294 # For testing purposes.
285 295 if not suppress_errors:
286 296 raise
287 297 self.log.warn("Error loading config file: %s" %
288 298 self.config_file_name, exc_info=True)
289 299
290 300 def init_profile_dir(self):
291 301 """initialize the profile dir"""
292 302 self._in_init_profile_dir = True
293 303 if self.profile_dir is not None:
294 304 # already ran
295 305 return
296 306 if 'ProfileDir.location' not in self.config:
297 307 # location not specified, find by profile name
298 308 try:
299 309 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
300 310 except ProfileDirError:
301 311 # not found, maybe create it (always create default profile)
302 312 if self.auto_create or self.profile == 'default':
303 313 try:
304 314 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
305 315 except ProfileDirError:
306 316 self.log.fatal("Could not create profile: %r"%self.profile)
307 317 self.exit(1)
308 318 else:
309 319 self.log.info("Created profile dir: %r"%p.location)
310 320 else:
311 321 self.log.fatal("Profile %r not found."%self.profile)
312 322 self.exit(1)
313 323 else:
314 324 self.log.debug("Using existing profile dir: %r"%p.location)
315 325 else:
316 326 location = self.config.ProfileDir.location
317 327 # location is fully specified
318 328 try:
319 329 p = ProfileDir.find_profile_dir(location, self.config)
320 330 except ProfileDirError:
321 331 # not found, maybe create it
322 332 if self.auto_create:
323 333 try:
324 334 p = ProfileDir.create_profile_dir(location, self.config)
325 335 except ProfileDirError:
326 336 self.log.fatal("Could not create profile directory: %r"%location)
327 337 self.exit(1)
328 338 else:
329 339 self.log.debug("Creating new profile dir: %r"%location)
330 340 else:
331 341 self.log.fatal("Profile directory %r not found."%location)
332 342 self.exit(1)
333 343 else:
334 344 self.log.info("Using existing profile dir: %r"%location)
335 345 # if profile_dir is specified explicitly, set profile name
336 346 dir_name = os.path.basename(p.location)
337 347 if dir_name.startswith('profile_'):
338 348 self.profile = dir_name[8:]
339 349
340 350 self.profile_dir = p
341 351 self.config_file_paths.append(p.location)
342 352 self._in_init_profile_dir = False
343 353
344 354 def init_config_files(self):
345 355 """[optionally] copy default config files into profile dir."""
346 356 self.config_file_paths.extend(SYSTEM_CONFIG_DIRS)
347 357 # copy config files
348 358 path = self.builtin_profile_dir
349 359 if self.copy_config_files:
350 360 src = self.profile
351 361
352 362 cfg = self.config_file_name
353 363 if path and os.path.exists(os.path.join(path, cfg)):
354 364 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
355 365 cfg, src, self.profile_dir.location, self.overwrite)
356 366 )
357 367 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
358 368 else:
359 369 self.stage_default_config_file()
360 370 else:
361 371 # Still stage *bundled* config files, but not generated ones
362 372 # This is necessary for `ipython profile=sympy` to load the profile
363 373 # on the first go
364 374 files = glob.glob(os.path.join(path, '*.py'))
365 375 for fullpath in files:
366 376 cfg = os.path.basename(fullpath)
367 377 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
368 378 # file was copied
369 379 self.log.warn("Staging bundled %s from %s into %r"%(
370 380 cfg, self.profile, self.profile_dir.location)
371 381 )
372 382
373 383
374 384 def stage_default_config_file(self):
375 385 """auto generate default config file, and stage it into the profile."""
376 386 s = self.generate_config_file()
377 387 fname = os.path.join(self.profile_dir.location, self.config_file_name)
378 388 if self.overwrite or not os.path.exists(fname):
379 389 self.log.warn("Generating default config file: %r"%(fname))
380 390 with open(fname, 'w') as f:
381 391 f.write(s)
382 392
383 393 @catch_config_error
384 394 def initialize(self, argv=None):
385 395 # don't hook up crash handler before parsing command-line
386 396 self.parse_command_line(argv)
387 397 self.init_crash_handler()
388 398 if self.subapp is not None:
389 399 # stop here if subapp is taking over
390 400 return
391 401 cl_config = self.config
392 402 self.init_profile_dir()
393 403 self.init_config_files()
394 404 self.load_config_file()
395 405 # enforce cl-opts override configfile opts:
396 406 self.update_config(cl_config)
397 407
@@ -1,377 +1,369 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.application.Application` object for the command
5 5 line :command:`ipython` program.
6 6 """
7 7
8 8 # Copyright (c) IPython Development Team.
9 9 # Distributed under the terms of the Modified BSD License.
10 10
11 11 from __future__ import absolute_import
12 12 from __future__ import print_function
13 13
14 14 import logging
15 15 import os
16 16 import sys
17 17
18 18 from traitlets.config.loader import Config
19 19 from traitlets.config.application import boolean_flag, catch_config_error, Application
20 20 from IPython.core import release
21 21 from IPython.core import usage
22 22 from IPython.core.completer import IPCompleter
23 23 from IPython.core.crashhandler import CrashHandler
24 24 from IPython.core.formatters import PlainTextFormatter
25 25 from IPython.core.history import HistoryManager
26 26 from IPython.core.prompts import PromptManager
27 27 from IPython.core.application import (
28 28 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
29 29 )
30 30 from IPython.core.magics import ScriptMagics
31 31 from IPython.core.shellapp import (
32 32 InteractiveShellApp, shell_flags, shell_aliases
33 33 )
34 34 from IPython.extensions.storemagic import StoreMagics
35 35 from IPython.terminal.interactiveshell import TerminalInteractiveShell
36 36 from IPython.utils import warn
37 37 from IPython.paths import get_ipython_dir
38 38 from traitlets import (
39 39 Bool, List, Dict,
40 40 )
41 41
42 42 #-----------------------------------------------------------------------------
43 43 # Globals, utilities and helpers
44 44 #-----------------------------------------------------------------------------
45 45
46 46 _examples = """
47 47 ipython --matplotlib # enable matplotlib integration
48 48 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
49 49
50 50 ipython --log-level=DEBUG # set logging to DEBUG
51 51 ipython --profile=foo # start with profile foo
52 52
53 ipython qtconsole # start the qtconsole GUI application
54 ipython help qtconsole # show the help for the qtconsole subcmd
55
56 ipython console # start the terminal-based console application
57 ipython help console # show the help for the console subcmd
58
59 ipython notebook # start the IPython notebook
60 ipython help notebook # show the help for the notebook subcmd
61
62 53 ipython profile create foo # create profile foo w/ default config files
63 54 ipython help profile # show the help for the profile subcmd
64 55
65 56 ipython locate # print the path to the IPython directory
66 57 ipython locate profile foo # print the path to the directory for profile `foo`
67
68 ipython nbconvert # convert notebooks to/from other formats
69 58 """
70 59
71 60 #-----------------------------------------------------------------------------
72 61 # Crash handler for this application
73 62 #-----------------------------------------------------------------------------
74 63
75 64 class IPAppCrashHandler(CrashHandler):
76 65 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
77 66
78 67 def __init__(self, app):
79 68 contact_name = release.author
80 69 contact_email = release.author_email
81 70 bug_tracker = 'https://github.com/ipython/ipython/issues'
82 71 super(IPAppCrashHandler,self).__init__(
83 72 app, contact_name, contact_email, bug_tracker
84 73 )
85 74
86 75 def make_report(self,traceback):
87 76 """Return a string containing a crash report."""
88 77
89 78 sec_sep = self.section_sep
90 79 # Start with parent report
91 80 report = [super(IPAppCrashHandler, self).make_report(traceback)]
92 81 # Add interactive-specific info we may have
93 82 rpt_add = report.append
94 83 try:
95 84 rpt_add(sec_sep+"History of session input:")
96 85 for line in self.app.shell.user_ns['_ih']:
97 86 rpt_add(line)
98 87 rpt_add('\n*** Last line of input (may not be in above history):\n')
99 88 rpt_add(self.app.shell._last_input_line+'\n')
100 89 except:
101 90 pass
102 91
103 92 return ''.join(report)
104 93
105 94 #-----------------------------------------------------------------------------
106 95 # Aliases and Flags
107 96 #-----------------------------------------------------------------------------
108 97 flags = dict(base_flags)
109 98 flags.update(shell_flags)
110 99 frontend_flags = {}
111 100 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
112 101 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
113 102 'Turn on auto editing of files with syntax errors.',
114 103 'Turn off auto editing of files with syntax errors.'
115 104 )
116 105 addflag('banner', 'TerminalIPythonApp.display_banner',
117 106 "Display a banner upon starting IPython.",
118 107 "Don't display a banner upon starting IPython."
119 108 )
120 109 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
121 110 """Set to confirm when you try to exit IPython with an EOF (Control-D
122 111 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
123 112 you can force a direct exit without any confirmation.""",
124 113 "Don't prompt the user when exiting."
125 114 )
126 115 addflag('term-title', 'TerminalInteractiveShell.term_title',
127 116 "Enable auto setting the terminal title.",
128 117 "Disable auto setting the terminal title."
129 118 )
130 119 classic_config = Config()
131 120 classic_config.InteractiveShell.cache_size = 0
132 121 classic_config.PlainTextFormatter.pprint = False
133 122 classic_config.PromptManager.in_template = '>>> '
134 123 classic_config.PromptManager.in2_template = '... '
135 124 classic_config.PromptManager.out_template = ''
136 125 classic_config.InteractiveShell.separate_in = ''
137 126 classic_config.InteractiveShell.separate_out = ''
138 127 classic_config.InteractiveShell.separate_out2 = ''
139 128 classic_config.InteractiveShell.colors = 'NoColor'
140 129 classic_config.InteractiveShell.xmode = 'Plain'
141 130
142 131 frontend_flags['classic']=(
143 132 classic_config,
144 133 "Gives IPython a similar feel to the classic Python prompt."
145 134 )
146 135 # # log doesn't make so much sense this way anymore
147 136 # paa('--log','-l',
148 137 # action='store_true', dest='InteractiveShell.logstart',
149 138 # help="Start logging to the default log file (./ipython_log.py).")
150 139 #
151 140 # # quick is harder to implement
152 141 frontend_flags['quick']=(
153 142 {'TerminalIPythonApp' : {'quick' : True}},
154 143 "Enable quick startup with no config files."
155 144 )
156 145
157 146 frontend_flags['i'] = (
158 147 {'TerminalIPythonApp' : {'force_interact' : True}},
159 148 """If running code from the command line, become interactive afterwards.
160 149 It is often useful to follow this with `--` to treat remaining flags as
161 150 script arguments.
162 151 """
163 152 )
164 153 flags.update(frontend_flags)
165 154
166 155 aliases = dict(base_aliases)
167 156 aliases.update(shell_aliases)
168 157
169 158 #-----------------------------------------------------------------------------
170 159 # Main classes and functions
171 160 #-----------------------------------------------------------------------------
172 161
173 162
174 163 class LocateIPythonApp(BaseIPythonApplication):
175 164 description = """print the path to the IPython dir"""
176 165 subcommands = Dict(dict(
177 166 profile=('IPython.core.profileapp.ProfileLocate',
178 167 "print the path to an IPython profile directory",
179 168 ),
180 169 ))
181 170 def start(self):
182 171 if self.subapp is not None:
183 172 return self.subapp.start()
184 173 else:
185 174 print(self.ipython_dir)
186 175
187 176
188 177 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
189 178 name = u'ipython'
190 179 description = usage.cl_usage
191 180 crash_handler_class = IPAppCrashHandler
192 181 examples = _examples
193 182
194 183 flags = Dict(flags)
195 184 aliases = Dict(aliases)
196 185 classes = List()
197 186 def _classes_default(self):
198 187 """This has to be in a method, for TerminalIPythonApp to be available."""
199 188 return [
200 189 InteractiveShellApp, # ShellApp comes before TerminalApp, because
201 190 self.__class__, # it will also affect subclasses (e.g. QtConsole)
202 191 TerminalInteractiveShell,
203 192 PromptManager,
204 193 HistoryManager,
205 194 ProfileDir,
206 195 PlainTextFormatter,
207 196 IPCompleter,
208 197 ScriptMagics,
209 198 StoreMagics,
210 199 ]
211 200
212 subcommands = dict(
201 deprecated_subcommands = dict(
213 202 qtconsole=('qtconsole.qtconsoleapp.JupyterQtConsoleApp',
214 203 """DEPRECATD: Launch the Jupyter Qt Console."""
215 204 ),
216 205 notebook=('notebook.notebookapp.NotebookApp',
217 206 """DEPRECATED: Launch the Jupyter HTML Notebook Server."""
218 207 ),
219 profile = ("IPython.core.profileapp.ProfileApp",
220 "Create and manage IPython profiles."
221 ),
222 kernel = ("ipykernel.kernelapp.IPKernelApp",
223 "Start a kernel without an attached frontend."
224 ),
225 208 console=('jupyter_console.app.ZMQTerminalIPythonApp',
226 209 """DEPRECATED: Launch the Jupyter terminal-based Console."""
227 210 ),
228 locate=('IPython.terminal.ipapp.LocateIPythonApp',
229 LocateIPythonApp.description
230 ),
231 history=('IPython.core.historyapp.HistoryApp',
232 "Manage the IPython history database."
233 ),
234 211 nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
235 212 "DEPRECATED: Convert notebooks to/from other formats."
236 213 ),
237 214 trust=('nbformat.sign.TrustNotebookApp',
238 215 "DEPRECATED: Sign notebooks to trust their potentially unsafe contents at load."
239 216 ),
240 217 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
241 218 "DEPRECATED: Manage Jupyter kernel specifications."
242 219 ),
243 220 )
244 subcommands['install-nbextension'] = (
221 subcommands = dict(
222 profile = ("IPython.core.profileapp.ProfileApp",
223 "Create and manage IPython profiles."
224 ),
225 kernel = ("ipykernel.kernelapp.IPKernelApp",
226 "Start a kernel without an attached frontend."
227 ),
228 locate=('IPython.terminal.ipapp.LocateIPythonApp',
229 LocateIPythonApp.description
230 ),
231 history=('IPython.core.historyapp.HistoryApp',
232 "Manage the IPython history database."
233 ),
234 )
235 deprecated_subcommands['install-nbextension'] = (
245 236 "notebook.nbextensions.InstallNBExtensionApp",
246 237 "DEPRECATED: Install Jupyter notebook extension files"
247 238 )
239 subcommands.update(deprecated_subcommands)
248 240
249 241 # *do* autocreate requested profile, but don't create the config file.
250 242 auto_create=Bool(True)
251 243 # configurables
252 244 quick = Bool(False, config=True,
253 245 help="""Start IPython quickly by skipping the loading of config files."""
254 246 )
255 247 def _quick_changed(self, name, old, new):
256 248 if new:
257 249 self.load_config_file = lambda *a, **kw: None
258 250
259 251 display_banner = Bool(True, config=True,
260 252 help="Whether to display a banner upon starting IPython."
261 253 )
262 254
263 255 # if there is code of files to run from the cmd line, don't interact
264 256 # unless the --i flag (App.force_interact) is true.
265 257 force_interact = Bool(False, config=True,
266 258 help="""If a command or file is given via the command-line,
267 259 e.g. 'ipython foo.py', start an interactive shell after executing the
268 260 file or command."""
269 261 )
270 262 def _force_interact_changed(self, name, old, new):
271 263 if new:
272 264 self.interact = True
273 265
274 266 def _file_to_run_changed(self, name, old, new):
275 267 if new:
276 268 self.something_to_run = True
277 269 if new and not self.force_interact:
278 270 self.interact = False
279 271 _code_to_run_changed = _file_to_run_changed
280 272 _module_to_run_changed = _file_to_run_changed
281 273
282 274 # internal, not-configurable
283 275 interact=Bool(True)
284 276 something_to_run=Bool(False)
285 277
286 278 def parse_command_line(self, argv=None):
287 279 """override to allow old '-pylab' flag with deprecation warning"""
288 280
289 281 argv = sys.argv[1:] if argv is None else argv
290 282
291 283 if '-pylab' in argv:
292 284 # deprecated `-pylab` given,
293 285 # warn and transform into current syntax
294 286 argv = argv[:] # copy, don't clobber
295 287 idx = argv.index('-pylab')
296 288 warn.warn("`-pylab` flag has been deprecated.\n"
297 289 " Use `--matplotlib <backend>` and import pylab manually.")
298 290 argv[idx] = '--pylab'
299 291
300 292 return super(TerminalIPythonApp, self).parse_command_line(argv)
301 293
302 294 @catch_config_error
303 295 def initialize(self, argv=None):
304 296 """Do actions after construct, but before starting the app."""
305 297 super(TerminalIPythonApp, self).initialize(argv)
306 298 if self.subapp is not None:
307 299 # don't bother initializing further, starting subapp
308 300 return
309 301 # print self.extra_args
310 302 if self.extra_args and not self.something_to_run:
311 303 self.file_to_run = self.extra_args[0]
312 304 self.init_path()
313 305 # create the shell
314 306 self.init_shell()
315 307 # and draw the banner
316 308 self.init_banner()
317 309 # Now a variety of things that happen after the banner is printed.
318 310 self.init_gui_pylab()
319 311 self.init_extensions()
320 312 self.init_code()
321 313
322 314 def init_shell(self):
323 315 """initialize the InteractiveShell instance"""
324 316 # Create an InteractiveShell instance.
325 317 # shell.display_banner should always be False for the terminal
326 318 # based app, because we call shell.show_banner() by hand below
327 319 # so the banner shows *before* all extension loading stuff.
328 320 self.shell = TerminalInteractiveShell.instance(parent=self,
329 321 display_banner=False, profile_dir=self.profile_dir,
330 322 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
331 323 self.shell.configurables.append(self)
332 324
333 325 def init_banner(self):
334 326 """optionally display the banner"""
335 327 if self.display_banner and self.interact:
336 328 self.shell.show_banner()
337 329 # Make sure there is a space below the banner.
338 330 if self.log_level <= logging.INFO: print()
339 331
340 332 def _pylab_changed(self, name, old, new):
341 333 """Replace --pylab='inline' with --pylab='auto'"""
342 334 if new == 'inline':
343 335 warn.warn("'inline' not available as pylab backend, "
344 336 "using 'auto' instead.")
345 337 self.pylab = 'auto'
346 338
347 339 def start(self):
348 340 if self.subapp is not None:
349 341 return self.subapp.start()
350 342 # perform any prexec steps:
351 343 if self.interact:
352 344 self.log.debug("Starting IPython's mainloop...")
353 345 self.shell.mainloop()
354 346 else:
355 347 self.log.debug("IPython not interactive...")
356 348
357 349 def load_default_config(ipython_dir=None):
358 350 """Load the default config file from the default ipython_dir.
359 351
360 352 This is useful for embedded shells.
361 353 """
362 354 if ipython_dir is None:
363 355 ipython_dir = get_ipython_dir()
364 356
365 357 profile_dir = os.path.join(ipython_dir, 'profile_default')
366 358
367 359 config = Config()
368 360 for cf in Application._load_config_files("ipython_config", path=profile_dir):
369 361 config.update(cf)
370 362
371 363 return config
372 364
373 365 launch_new_instance = TerminalIPythonApp.launch_instance
374 366
375 367
376 368 if __name__ == '__main__':
377 369 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now