##// END OF EJS Templates
Make the TerminalInteractiveShell class configurable....
Matthias Bussonnier -
Show More
@@ -1,370 +1,377 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
11
12 import logging
12 import logging
13 import os
13 import os
14 import sys
14 import sys
15 import warnings
15 import warnings
16
16
17 from traitlets.config.loader import Config
17 from traitlets.config.loader import Config
18 from traitlets.config.application import boolean_flag, catch_config_error, Application
18 from traitlets.config.application import boolean_flag, catch_config_error, Application
19 from IPython.core import release
19 from IPython.core import release
20 from IPython.core import usage
20 from IPython.core import usage
21 from IPython.core.completer import IPCompleter
21 from IPython.core.completer import IPCompleter
22 from IPython.core.crashhandler import CrashHandler
22 from IPython.core.crashhandler import CrashHandler
23 from IPython.core.formatters import PlainTextFormatter
23 from IPython.core.formatters import PlainTextFormatter
24 from IPython.core.history import HistoryManager
24 from IPython.core.history import HistoryManager
25 from IPython.core.application import (
25 from IPython.core.application import (
26 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
26 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
27 )
27 )
28 from IPython.core.magics import ScriptMagics
28 from IPython.core.magics import ScriptMagics
29 from IPython.core.shellapp import (
29 from IPython.core.shellapp import (
30 InteractiveShellApp, shell_flags, shell_aliases
30 InteractiveShellApp, shell_flags, shell_aliases
31 )
31 )
32 from IPython.extensions.storemagic import StoreMagics
32 from IPython.extensions.storemagic import StoreMagics
33 from .interactiveshell import TerminalInteractiveShell
33 from .interactiveshell import TerminalInteractiveShell
34 from IPython.paths import get_ipython_dir
34 from IPython.paths import get_ipython_dir
35 from traitlets import (
35 from traitlets import (
36 Bool, List, Dict, default, observe,
36 Bool, List, Dict, default, observe, Type
37 )
37 )
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Globals, utilities and helpers
40 # Globals, utilities and helpers
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42
42
43 _examples = """
43 _examples = """
44 ipython --matplotlib # enable matplotlib integration
44 ipython --matplotlib # enable matplotlib integration
45 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
45 ipython --matplotlib=qt # enable matplotlib integration with qt4 backend
46
46
47 ipython --log-level=DEBUG # set logging to DEBUG
47 ipython --log-level=DEBUG # set logging to DEBUG
48 ipython --profile=foo # start with profile foo
48 ipython --profile=foo # start with profile foo
49
49
50 ipython profile create foo # create profile foo w/ default config files
50 ipython profile create foo # create profile foo w/ default config files
51 ipython help profile # show the help for the profile subcmd
51 ipython help profile # show the help for the profile subcmd
52
52
53 ipython locate # print the path to the IPython directory
53 ipython locate # print the path to the IPython directory
54 ipython locate profile foo # print the path to the directory for profile `foo`
54 ipython locate profile foo # print the path to the directory for profile `foo`
55 """
55 """
56
56
57 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
58 # Crash handler for this application
58 # Crash handler for this application
59 #-----------------------------------------------------------------------------
59 #-----------------------------------------------------------------------------
60
60
61 class IPAppCrashHandler(CrashHandler):
61 class IPAppCrashHandler(CrashHandler):
62 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
62 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
63
63
64 def __init__(self, app):
64 def __init__(self, app):
65 contact_name = release.author
65 contact_name = release.author
66 contact_email = release.author_email
66 contact_email = release.author_email
67 bug_tracker = 'https://github.com/ipython/ipython/issues'
67 bug_tracker = 'https://github.com/ipython/ipython/issues'
68 super(IPAppCrashHandler,self).__init__(
68 super(IPAppCrashHandler,self).__init__(
69 app, contact_name, contact_email, bug_tracker
69 app, contact_name, contact_email, bug_tracker
70 )
70 )
71
71
72 def make_report(self,traceback):
72 def make_report(self,traceback):
73 """Return a string containing a crash report."""
73 """Return a string containing a crash report."""
74
74
75 sec_sep = self.section_sep
75 sec_sep = self.section_sep
76 # Start with parent report
76 # Start with parent report
77 report = [super(IPAppCrashHandler, self).make_report(traceback)]
77 report = [super(IPAppCrashHandler, self).make_report(traceback)]
78 # Add interactive-specific info we may have
78 # Add interactive-specific info we may have
79 rpt_add = report.append
79 rpt_add = report.append
80 try:
80 try:
81 rpt_add(sec_sep+"History of session input:")
81 rpt_add(sec_sep+"History of session input:")
82 for line in self.app.shell.user_ns['_ih']:
82 for line in self.app.shell.user_ns['_ih']:
83 rpt_add(line)
83 rpt_add(line)
84 rpt_add('\n*** Last line of input (may not be in above history):\n')
84 rpt_add('\n*** Last line of input (may not be in above history):\n')
85 rpt_add(self.app.shell._last_input_line+'\n')
85 rpt_add(self.app.shell._last_input_line+'\n')
86 except:
86 except:
87 pass
87 pass
88
88
89 return ''.join(report)
89 return ''.join(report)
90
90
91 #-----------------------------------------------------------------------------
91 #-----------------------------------------------------------------------------
92 # Aliases and Flags
92 # Aliases and Flags
93 #-----------------------------------------------------------------------------
93 #-----------------------------------------------------------------------------
94 flags = dict(base_flags)
94 flags = dict(base_flags)
95 flags.update(shell_flags)
95 flags.update(shell_flags)
96 frontend_flags = {}
96 frontend_flags = {}
97 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
97 addflag = lambda *args: frontend_flags.update(boolean_flag(*args))
98 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
98 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
99 'Turn on auto editing of files with syntax errors.',
99 'Turn on auto editing of files with syntax errors.',
100 'Turn off auto editing of files with syntax errors.'
100 'Turn off auto editing of files with syntax errors.'
101 )
101 )
102 addflag('simple-prompt', 'TerminalInteractiveShell.simple_prompt',
102 addflag('simple-prompt', 'TerminalInteractiveShell.simple_prompt',
103 "Force simple minimal prompt using `raw_input`",
103 "Force simple minimal prompt using `raw_input`",
104 "Use a rich interactive prompt with prompt_toolkit",
104 "Use a rich interactive prompt with prompt_toolkit",
105 )
105 )
106
106
107 addflag('banner', 'TerminalIPythonApp.display_banner',
107 addflag('banner', 'TerminalIPythonApp.display_banner',
108 "Display a banner upon starting IPython.",
108 "Display a banner upon starting IPython.",
109 "Don't display a banner upon starting IPython."
109 "Don't display a banner upon starting IPython."
110 )
110 )
111 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
111 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
112 """Set to confirm when you try to exit IPython with an EOF (Control-D
112 """Set to confirm when you try to exit IPython with an EOF (Control-D
113 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
113 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
114 you can force a direct exit without any confirmation.""",
114 you can force a direct exit without any confirmation.""",
115 "Don't prompt the user when exiting."
115 "Don't prompt the user when exiting."
116 )
116 )
117 addflag('term-title', 'TerminalInteractiveShell.term_title',
117 addflag('term-title', 'TerminalInteractiveShell.term_title',
118 "Enable auto setting the terminal title.",
118 "Enable auto setting the terminal title.",
119 "Disable auto setting the terminal title."
119 "Disable auto setting the terminal title."
120 )
120 )
121 classic_config = Config()
121 classic_config = Config()
122 classic_config.InteractiveShell.cache_size = 0
122 classic_config.InteractiveShell.cache_size = 0
123 classic_config.PlainTextFormatter.pprint = False
123 classic_config.PlainTextFormatter.pprint = False
124 classic_config.TerminalInteractiveShell.prompts_class='IPython.terminal.prompts.ClassicPrompts'
124 classic_config.TerminalInteractiveShell.prompts_class='IPython.terminal.prompts.ClassicPrompts'
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
187 interactive_shell_class = Type(
188 klass=object, # use default_value otherwise which only allow subclasses.
189 default_value=TerminalInteractiveShell,
190 help="Class to use to instantiate the TerminalInteractiveShell object. Useful for custom Frontends"
191 ).tag(config=True)
192
186 @default('classes')
193 @default('classes')
187 def _classes_default(self):
194 def _classes_default(self):
188 """This has to be in a method, for TerminalIPythonApp to be available."""
195 """This has to be in a method, for TerminalIPythonApp to be available."""
189 return [
196 return [
190 InteractiveShellApp, # ShellApp comes before TerminalApp, because
197 InteractiveShellApp, # ShellApp comes before TerminalApp, because
191 self.__class__, # it will also affect subclasses (e.g. QtConsole)
198 self.__class__, # it will also affect subclasses (e.g. QtConsole)
192 TerminalInteractiveShell,
199 TerminalInteractiveShell,
193 HistoryManager,
200 HistoryManager,
194 ProfileDir,
201 ProfileDir,
195 PlainTextFormatter,
202 PlainTextFormatter,
196 IPCompleter,
203 IPCompleter,
197 ScriptMagics,
204 ScriptMagics,
198 StoreMagics,
205 StoreMagics,
199 ]
206 ]
200
207
201 deprecated_subcommands = dict(
208 deprecated_subcommands = dict(
202 qtconsole=('qtconsole.qtconsoleapp.JupyterQtConsoleApp',
209 qtconsole=('qtconsole.qtconsoleapp.JupyterQtConsoleApp',
203 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter Qt Console."""
210 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter Qt Console."""
204 ),
211 ),
205 notebook=('notebook.notebookapp.NotebookApp',
212 notebook=('notebook.notebookapp.NotebookApp',
206 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter HTML Notebook Server."""
213 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter HTML Notebook Server."""
207 ),
214 ),
208 console=('jupyter_console.app.ZMQTerminalIPythonApp',
215 console=('jupyter_console.app.ZMQTerminalIPythonApp',
209 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter terminal-based Console."""
216 """DEPRECATED, Will be removed in IPython 6.0 : Launch the Jupyter terminal-based Console."""
210 ),
217 ),
211 nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
218 nbconvert=('nbconvert.nbconvertapp.NbConvertApp',
212 "DEPRECATED, Will be removed in IPython 6.0 : Convert notebooks to/from other formats."
219 "DEPRECATED, Will be removed in IPython 6.0 : Convert notebooks to/from other formats."
213 ),
220 ),
214 trust=('nbformat.sign.TrustNotebookApp',
221 trust=('nbformat.sign.TrustNotebookApp',
215 "DEPRECATED, Will be removed in IPython 6.0 : Sign notebooks to trust their potentially unsafe contents at load."
222 "DEPRECATED, Will be removed in IPython 6.0 : Sign notebooks to trust their potentially unsafe contents at load."
216 ),
223 ),
217 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
224 kernelspec=('jupyter_client.kernelspecapp.KernelSpecApp',
218 "DEPRECATED, Will be removed in IPython 6.0 : Manage Jupyter kernel specifications."
225 "DEPRECATED, Will be removed in IPython 6.0 : Manage Jupyter kernel specifications."
219 ),
226 ),
220 )
227 )
221 subcommands = dict(
228 subcommands = dict(
222 profile = ("IPython.core.profileapp.ProfileApp",
229 profile = ("IPython.core.profileapp.ProfileApp",
223 "Create and manage IPython profiles."
230 "Create and manage IPython profiles."
224 ),
231 ),
225 kernel = ("ipykernel.kernelapp.IPKernelApp",
232 kernel = ("ipykernel.kernelapp.IPKernelApp",
226 "Start a kernel without an attached frontend."
233 "Start a kernel without an attached frontend."
227 ),
234 ),
228 locate=('IPython.terminal.ipapp.LocateIPythonApp',
235 locate=('IPython.terminal.ipapp.LocateIPythonApp',
229 LocateIPythonApp.description
236 LocateIPythonApp.description
230 ),
237 ),
231 history=('IPython.core.historyapp.HistoryApp',
238 history=('IPython.core.historyapp.HistoryApp',
232 "Manage the IPython history database."
239 "Manage the IPython history database."
233 ),
240 ),
234 )
241 )
235 deprecated_subcommands['install-nbextension'] = (
242 deprecated_subcommands['install-nbextension'] = (
236 "notebook.nbextensions.InstallNBExtensionApp",
243 "notebook.nbextensions.InstallNBExtensionApp",
237 "DEPRECATED, Will be removed in IPython 6.0 : Install Jupyter notebook extension files"
244 "DEPRECATED, Will be removed in IPython 6.0 : Install Jupyter notebook extension files"
238 )
245 )
239 subcommands.update(deprecated_subcommands)
246 subcommands.update(deprecated_subcommands)
240
247
241 # *do* autocreate requested profile, but don't create the config file.
248 # *do* autocreate requested profile, but don't create the config file.
242 auto_create=Bool(True)
249 auto_create=Bool(True)
243 # configurables
250 # configurables
244 quick = Bool(False,
251 quick = Bool(False,
245 help="""Start IPython quickly by skipping the loading of config files."""
252 help="""Start IPython quickly by skipping the loading of config files."""
246 ).tag(config=True)
253 ).tag(config=True)
247 @observe('quick')
254 @observe('quick')
248 def _quick_changed(self, change):
255 def _quick_changed(self, change):
249 if change['new']:
256 if change['new']:
250 self.load_config_file = lambda *a, **kw: None
257 self.load_config_file = lambda *a, **kw: None
251
258
252 display_banner = Bool(True,
259 display_banner = Bool(True,
253 help="Whether to display a banner upon starting IPython."
260 help="Whether to display a banner upon starting IPython."
254 ).tag(config=True)
261 ).tag(config=True)
255
262
256 # if there is code of files to run from the cmd line, don't interact
263 # if there is code of files to run from the cmd line, don't interact
257 # unless the --i flag (App.force_interact) is true.
264 # unless the --i flag (App.force_interact) is true.
258 force_interact = Bool(False,
265 force_interact = Bool(False,
259 help="""If a command or file is given via the command-line,
266 help="""If a command or file is given via the command-line,
260 e.g. 'ipython foo.py', start an interactive shell after executing the
267 e.g. 'ipython foo.py', start an interactive shell after executing the
261 file or command."""
268 file or command."""
262 ).tag(config=True)
269 ).tag(config=True)
263 @observe('force_interact')
270 @observe('force_interact')
264 def _force_interact_changed(self, change):
271 def _force_interact_changed(self, change):
265 if change['new']:
272 if change['new']:
266 self.interact = True
273 self.interact = True
267
274
268 @observe('file_to_run', 'code_to_run', 'module_to_run')
275 @observe('file_to_run', 'code_to_run', 'module_to_run')
269 def _file_to_run_changed(self, change):
276 def _file_to_run_changed(self, change):
270 new = change['new']
277 new = change['new']
271 if new:
278 if new:
272 self.something_to_run = True
279 self.something_to_run = True
273 if new and not self.force_interact:
280 if new and not self.force_interact:
274 self.interact = False
281 self.interact = False
275
282
276 # internal, not-configurable
283 # internal, not-configurable
277 something_to_run=Bool(False)
284 something_to_run=Bool(False)
278
285
279 def parse_command_line(self, argv=None):
286 def parse_command_line(self, argv=None):
280 """override to allow old '-pylab' flag with deprecation warning"""
287 """override to allow old '-pylab' flag with deprecation warning"""
281
288
282 argv = sys.argv[1:] if argv is None else argv
289 argv = sys.argv[1:] if argv is None else argv
283
290
284 if '-pylab' in argv:
291 if '-pylab' in argv:
285 # deprecated `-pylab` given,
292 # deprecated `-pylab` given,
286 # warn and transform into current syntax
293 # warn and transform into current syntax
287 argv = argv[:] # copy, don't clobber
294 argv = argv[:] # copy, don't clobber
288 idx = argv.index('-pylab')
295 idx = argv.index('-pylab')
289 warnings.warn("`-pylab` flag has been deprecated.\n"
296 warnings.warn("`-pylab` flag has been deprecated.\n"
290 " Use `--matplotlib <backend>` and import pylab manually.")
297 " Use `--matplotlib <backend>` and import pylab manually.")
291 argv[idx] = '--pylab'
298 argv[idx] = '--pylab'
292
299
293 return super(TerminalIPythonApp, self).parse_command_line(argv)
300 return super(TerminalIPythonApp, self).parse_command_line(argv)
294
301
295 @catch_config_error
302 @catch_config_error
296 def initialize(self, argv=None):
303 def initialize(self, argv=None):
297 """Do actions after construct, but before starting the app."""
304 """Do actions after construct, but before starting the app."""
298 super(TerminalIPythonApp, self).initialize(argv)
305 super(TerminalIPythonApp, self).initialize(argv)
299 if self.subapp is not None:
306 if self.subapp is not None:
300 # don't bother initializing further, starting subapp
307 # don't bother initializing further, starting subapp
301 return
308 return
302 # print self.extra_args
309 # print self.extra_args
303 if self.extra_args and not self.something_to_run:
310 if self.extra_args and not self.something_to_run:
304 self.file_to_run = self.extra_args[0]
311 self.file_to_run = self.extra_args[0]
305 self.init_path()
312 self.init_path()
306 # create the shell
313 # create the shell
307 self.init_shell()
314 self.init_shell()
308 # and draw the banner
315 # and draw the banner
309 self.init_banner()
316 self.init_banner()
310 # Now a variety of things that happen after the banner is printed.
317 # Now a variety of things that happen after the banner is printed.
311 self.init_gui_pylab()
318 self.init_gui_pylab()
312 self.init_extensions()
319 self.init_extensions()
313 self.init_code()
320 self.init_code()
314
321
315 def init_shell(self):
322 def init_shell(self):
316 """initialize the InteractiveShell instance"""
323 """initialize the InteractiveShell instance"""
317 # Create an InteractiveShell instance.
324 # Create an InteractiveShell instance.
318 # shell.display_banner should always be False for the terminal
325 # shell.display_banner should always be False for the terminal
319 # based app, because we call shell.show_banner() by hand below
326 # based app, because we call shell.show_banner() by hand below
320 # so the banner shows *before* all extension loading stuff.
327 # so the banner shows *before* all extension loading stuff.
321 self.shell = TerminalInteractiveShell.instance(parent=self,
328 self.shell = self.interactive_shell_class.instance(parent=self,
322 profile_dir=self.profile_dir,
329 profile_dir=self.profile_dir,
323 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
330 ipython_dir=self.ipython_dir, user_ns=self.user_ns)
324 self.shell.configurables.append(self)
331 self.shell.configurables.append(self)
325
332
326 def init_banner(self):
333 def init_banner(self):
327 """optionally display the banner"""
334 """optionally display the banner"""
328 if self.display_banner and self.interact:
335 if self.display_banner and self.interact:
329 self.shell.show_banner()
336 self.shell.show_banner()
330 # Make sure there is a space below the banner.
337 # Make sure there is a space below the banner.
331 if self.log_level <= logging.INFO: print()
338 if self.log_level <= logging.INFO: print()
332
339
333 def _pylab_changed(self, name, old, new):
340 def _pylab_changed(self, name, old, new):
334 """Replace --pylab='inline' with --pylab='auto'"""
341 """Replace --pylab='inline' with --pylab='auto'"""
335 if new == 'inline':
342 if new == 'inline':
336 warnings.warn("'inline' not available as pylab backend, "
343 warnings.warn("'inline' not available as pylab backend, "
337 "using 'auto' instead.")
344 "using 'auto' instead.")
338 self.pylab = 'auto'
345 self.pylab = 'auto'
339
346
340 def start(self):
347 def start(self):
341 if self.subapp is not None:
348 if self.subapp is not None:
342 return self.subapp.start()
349 return self.subapp.start()
343 # perform any prexec steps:
350 # perform any prexec steps:
344 if self.interact:
351 if self.interact:
345 self.log.debug("Starting IPython's mainloop...")
352 self.log.debug("Starting IPython's mainloop...")
346 self.shell.mainloop()
353 self.shell.mainloop()
347 else:
354 else:
348 self.log.debug("IPython not interactive...")
355 self.log.debug("IPython not interactive...")
349
356
350 def load_default_config(ipython_dir=None):
357 def load_default_config(ipython_dir=None):
351 """Load the default config file from the default ipython_dir.
358 """Load the default config file from the default ipython_dir.
352
359
353 This is useful for embedded shells.
360 This is useful for embedded shells.
354 """
361 """
355 if ipython_dir is None:
362 if ipython_dir is None:
356 ipython_dir = get_ipython_dir()
363 ipython_dir = get_ipython_dir()
357
364
358 profile_dir = os.path.join(ipython_dir, 'profile_default')
365 profile_dir = os.path.join(ipython_dir, 'profile_default')
359
366
360 config = Config()
367 config = Config()
361 for cf in Application._load_config_files("ipython_config", path=profile_dir):
368 for cf in Application._load_config_files("ipython_config", path=profile_dir):
362 config.update(cf)
369 config.update(cf)
363
370
364 return config
371 return config
365
372
366 launch_new_instance = TerminalIPythonApp.launch_instance
373 launch_new_instance = TerminalIPythonApp.launch_instance
367
374
368
375
369 if __name__ == '__main__':
376 if __name__ == '__main__':
370 launch_new_instance()
377 launch_new_instance()
@@ -1,176 +1,185 b''
1 =====================
1 =====================
2 Development version
2 Development version
3 =====================
3 =====================
4
4
5 This document describes in-flight development work.
5 This document describes in-flight development work.
6
6
7 .. warning::
7 .. warning::
8
8
9 Please do not edit this file by hand (doing so will likely cause merge
9 Please do not edit this file by hand (doing so will likely cause merge
10 conflicts for other Pull Requests). Instead, create a new file in the
10 conflicts for other Pull Requests). Instead, create a new file in the
11 `docs/source/whatsnew/pr` folder
11 `docs/source/whatsnew/pr` folder
12
12
13 IPython 6.0
13 IPython 6.0
14 ===========
14 ===========
15
15
16 Released .... ...., 2017
16 Released .... ...., 2017
17
17
18 IPython 6 feature a major improvement in the completion machinery which is now
18 IPython 6 feature a major improvement in the completion machinery which is now
19 capable of completing non-executed code. It is also the first version of IPython
19 capable of completing non-executed code. It is also the first version of IPython
20 to stop compatibility with Python 2, which is still supported on the bugfix only
20 to stop compatibility with Python 2, which is still supported on the bugfix only
21 5.x branch. Read below to have a non-exhaustive list of new features.
21 5.x branch. Read below to have a non-exhaustive list of new features.
22
22
23 Make sure you have pip > 9.0 before upgrading.
23 Make sure you have pip > 9.0 before upgrading.
24 You should be able to update by using:
24 You should be able to update by using:
25
25
26 .. code::
26 .. code::
27
27
28 pip install ipython --upgrade
28 pip install ipython --upgrade
29
29
30 New completion API and Interface
30 New completion API and Interface
31 --------------------------------
31 --------------------------------
32
32
33 The completer Completion API has seen an overhaul, and the new completer have
33 The completer Completion API has seen an overhaul, and the new completer have
34 plenty of improvement both from the end users of terminal IPython or for
34 plenty of improvement both from the end users of terminal IPython or for
35 consumers of the API.
35 consumers of the API.
36
36
37 This new API is capable of pulling completions from :any:`jedi`, thus allowing
37 This new API is capable of pulling completions from :any:`jedi`, thus allowing
38 type inference on non-executed code. If :any:`jedi` is installed completion like
38 type inference on non-executed code. If :any:`jedi` is installed completion like
39 the following are now becoming possible without code evaluation:
39 the following are now becoming possible without code evaluation:
40
40
41 >>> data = ['Number of users', 123_456]
41 >>> data = ['Number of users', 123_456]
42 ... data[0].<tab>
42 ... data[0].<tab>
43
43
44 That is to say, IPython is now capable of inferring that `data[0]` is a string,
44 That is to say, IPython is now capable of inferring that `data[0]` is a string,
45 and will suggest completions like `.capitalize`. The completion power of IPython
45 and will suggest completions like `.capitalize`. The completion power of IPython
46 will increase with new Jedi releases, and a number of bugs and more completions
46 will increase with new Jedi releases, and a number of bugs and more completions
47 are already available on development version of :any:`jedi` if you are curious.
47 are already available on development version of :any:`jedi` if you are curious.
48
48
49 With the help of prompt toolkit, types of completions can be shown in the
49 With the help of prompt toolkit, types of completions can be shown in the
50 completer interface:
50 completer interface:
51
51
52 .. image:: ../_images/jedi_type_inference_60.png
52 .. image:: ../_images/jedi_type_inference_60.png
53 :alt: Jedi showing ability to do type inference
53 :alt: Jedi showing ability to do type inference
54 :align: center
54 :align: center
55 :width: 400px
55 :width: 400px
56 :target: ../_images/jedi_type_inference_60.png
56 :target: ../_images/jedi_type_inference_60.png
57
57
58 The appearance of the completer is controlled by the
58 The appearance of the completer is controlled by the
59 ``c.TerminalInteractiveShell.display_completions`` option that will show the
59 ``c.TerminalInteractiveShell.display_completions`` option that will show the
60 type differently depending on the value among ``'column'``, ``'multicolumn'``
60 type differently depending on the value among ``'column'``, ``'multicolumn'``
61 and ``'readlinelike'``
61 and ``'readlinelike'``
62
62
63 The use of Jedi also full fill a number of request and fix a number of bugs
63 The use of Jedi also full fill a number of request and fix a number of bugs
64 like case insensitive completion, completion after division operator: See
64 like case insensitive completion, completion after division operator: See
65 :ghpull:`10182`.
65 :ghpull:`10182`.
66
66
67 Extra patches and updates will be needed to the :mod:`ipykernel` package for
67 Extra patches and updates will be needed to the :mod:`ipykernel` package for
68 this feature to be available to other clients like jupyter Notebook, Lab,
68 this feature to be available to other clients like jupyter Notebook, Lab,
69 Nteract, Hydrogen...
69 Nteract, Hydrogen...
70
70
71 The use of Jedi can is barely noticeable on recent enough machines, but can be
71 The use of Jedi can is barely noticeable on recent enough machines, but can be
72 feel on older ones, in cases were Jedi behavior need to be adjusted, the amount
72 feel on older ones, in cases were Jedi behavior need to be adjusted, the amount
73 of time given to Jedi to compute type inference can be adjusted with
73 of time given to Jedi to compute type inference can be adjusted with
74 ``c.IPCompleter.jedi_compute_type_timeout``, with object whose type were not
74 ``c.IPCompleter.jedi_compute_type_timeout``, with object whose type were not
75 inferred will be shown as ``<unknown>``. Jedi can also be completely deactivated
75 inferred will be shown as ``<unknown>``. Jedi can also be completely deactivated
76 by using the ``c.Completer.use_jedi=False`` option.
76 by using the ``c.Completer.use_jedi=False`` option.
77
77
78
78
79 The old ``Completer.complete()`` API is waiting deprecation and should be
79 The old ``Completer.complete()`` API is waiting deprecation and should be
80 replaced replaced by ``Completer.completions()`` in a near future. Feedback on
80 replaced replaced by ``Completer.completions()`` in a near future. Feedback on
81 the current state of the API and suggestions welcome.
81 the current state of the API and suggestions welcome.
82
82
83 Python 3 only codebase
83 Python 3 only codebase
84 ----------------------
84 ----------------------
85
85
86 One of the large challenges in IPython 6.0 has been the adoption of a pure
86 One of the large challenges in IPython 6.0 has been the adoption of a pure
87 Python 3 code base, which lead us to great length to upstream patches in pip,
87 Python 3 code base, which lead us to great length to upstream patches in pip,
88 pypi and warehouse to make sure Python 2 system still upgrade to the latest
88 pypi and warehouse to make sure Python 2 system still upgrade to the latest
89 compatible Python version compatible.
89 compatible Python version compatible.
90
90
91 We remind our Python 2 users that IPython 5 is still compatible with Python 2.7,
91 We remind our Python 2 users that IPython 5 is still compatible with Python 2.7,
92 still maintained and get regular releases. Using pip 9+, upgrading IPython will
92 still maintained and get regular releases. Using pip 9+, upgrading IPython will
93 automatically upgrade to the latest version compatible with your system.
93 automatically upgrade to the latest version compatible with your system.
94
94
95 .. warning::
95 .. warning::
96
96
97 If you are on a system using an older verison of pip on Python 2, pip may
97 If you are on a system using an older verison of pip on Python 2, pip may
98 still install IPython 6.0 on your system, and IPython will refuse to start.
98 still install IPython 6.0 on your system, and IPython will refuse to start.
99 You can fix this by ugrading pip, and reinstalling ipython, or forcing pip to
99 You can fix this by ugrading pip, and reinstalling ipython, or forcing pip to
100 install an earlier version: ``pip install 'ipython<6'``
100 install an earlier version: ``pip install 'ipython<6'``
101
101
102 The ability to use only Python 3 on the code base of IPython has bring a number
102 The ability to use only Python 3 on the code base of IPython has bring a number
103 of advantage. Most of the newly written code make use of `optional function type
103 of advantage. Most of the newly written code make use of `optional function type
104 anotation <https://www.python.org/dev/peps/pep-0484/>`_ leading to clearer code
104 anotation <https://www.python.org/dev/peps/pep-0484/>`_ leading to clearer code
105 and better documentation.
105 and better documentation.
106
106
107 The total size of the repository has also for a first time between releases
107 The total size of the repository has also for a first time between releases
108 (excluding the big split for 4.0) decreased by about 1500 lines, potentially
108 (excluding the big split for 4.0) decreased by about 1500 lines, potentially
109 quite a bit more codewide as some documents like this one are append only and
109 quite a bit more codewide as some documents like this one are append only and
110 are about 300 lines long.
110 are about 300 lines long.
111
111
112 The removal as of Python2/Python3 shim layer has made the code quite clearer and
112 The removal as of Python2/Python3 shim layer has made the code quite clearer and
113 more idiomatic in a number of location, and much friendlier to work with and
113 more idiomatic in a number of location, and much friendlier to work with and
114 understand. We hope to further embrace Python 3 capability in the next release
114 understand. We hope to further embrace Python 3 capability in the next release
115 cycle and introduce more of the Python 3 only idioms (yield from, kwarg only,
115 cycle and introduce more of the Python 3 only idioms (yield from, kwarg only,
116 general unpacking) in the code base of IPython, and see if we can take advantage
116 general unpacking) in the code base of IPython, and see if we can take advantage
117 of these as well to improve user experience with better error messages and
117 of these as well to improve user experience with better error messages and
118 hints.
118 hints.
119
119
120
120
121 Configurable TerminalInteractiveShell
122 -------------------------------------
123
124 IPython gained a new ``c.TerminalIPythonApp.interactive_shell_class`` option
125 that allow to customize the class used to start the terminal frontend. This
126 should allow user to use custom interfaces, like reviving the former readline
127 interface which is now a separate package not maintained by the core team.
128
129
121 Miscs improvements
130 Miscs improvements
122 ------------------
131 ------------------
123
132
124
133
125 - The :cellmagic:`capture` magic can now capture the result of a cell (from an
134 - The :cellmagic:`capture` magic can now capture the result of a cell (from an
126 expression on the last line), as well as printed and displayed output.
135 expression on the last line), as well as printed and displayed output.
127 :ghpull:`9851`.
136 :ghpull:`9851`.
128
137
129 - Pressing Ctrl-Z in the terminal debugger now suspends IPython, as it already
138 - Pressing Ctrl-Z in the terminal debugger now suspends IPython, as it already
130 does in the main terminal prompt.
139 does in the main terminal prompt.
131
140
132 - autoreload can now reload ``Enum``. See :ghissue:`10232` and :ghpull:`10316`
141 - autoreload can now reload ``Enum``. See :ghissue:`10232` and :ghpull:`10316`
133
142
134 - IPython.display has gained a :any:`GeoJSON <IPython.display.GeoJSON>` object.
143 - IPython.display has gained a :any:`GeoJSON <IPython.display.GeoJSON>` object.
135 :ghpull:`10288` and :ghpull:`10253`
144 :ghpull:`10288` and :ghpull:`10253`
136
145
137 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
146 .. DO NOT EDIT THIS LINE BEFORE RELEASE. FEATURE INSERTION POINT.
138
147
139
148
140 Functions Deprecated in 6.x Development cycle
149 Functions Deprecated in 6.x Development cycle
141 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142
151
143 - Loading extensions from ``ipython_extension_dir`` print a warning that this
152 - Loading extensions from ``ipython_extension_dir`` print a warning that this
144 location is pending deprecation. This should only affect users still having
153 location is pending deprecation. This should only affect users still having
145 extensions installed with ``%install_ext`` which has been deprecated since
154 extensions installed with ``%install_ext`` which has been deprecated since
146 IPython 4.0, and removed in 5.0. Extensions still present in
155 IPython 4.0, and removed in 5.0. Extensions still present in
147 ``ipython_extension_dir`` may shadow more recently installed versions using
156 ``ipython_extension_dir`` may shadow more recently installed versions using
148 pip. It is thus recommended to clean ``ipython_extension_dir`` of any
157 pip. It is thus recommended to clean ``ipython_extension_dir`` of any
149 extension now available as a package.
158 extension now available as a package.
150
159
151
160
152 - ``IPython.utils.warn`` was deprecated in IPython 4.0, and has now been removed.
161 - ``IPython.utils.warn`` was deprecated in IPython 4.0, and has now been removed.
153 instead of ``IPython.utils.warn`` inbuilt :any:`warnings` module is used.
162 instead of ``IPython.utils.warn`` inbuilt :any:`warnings` module is used.
154
163
155
164
156 - The function `IPython.core.oinspect.py:call_tip` is unused, was marked as
165 - The function `IPython.core.oinspect.py:call_tip` is unused, was marked as
157 Deprecated (raising a Deprecation Warning) and marked for later removal
166 Deprecated (raising a Deprecation Warning) and marked for later removal
158 :ghpull:`10104`
167 :ghpull:`10104`
159
168
160 Backwards incompatible changes
169 Backwards incompatible changes
161 ------------------------------
170 ------------------------------
162
171
163 Functions Removed in 6.x Development cycle
172 Functions Removed in 6.x Development cycle
164 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165
174
166 The following functions have been removed in the
175 The following functions have been removed in the
167 development cycle marked for Milestone 6.0.
176 development cycle marked for Milestone 6.0.
168
177
169 - ``IPython/utils/process.py`` - ``is_cmd_found``
178 - ``IPython/utils/process.py`` - ``is_cmd_found``
170 - ``IPython/utils/process.py`` - ``pycmd2argv``
179 - ``IPython/utils/process.py`` - ``pycmd2argv``
171
180
172 - The `--deep-reload` flag and the corresponding options to inject `dreload` or
181 - The `--deep-reload` flag and the corresponding options to inject `dreload` or
173 `reload` into the interactive namespace have been removed. You have to
182 `reload` into the interactive namespace have been removed. You have to
174 explicitly import `reload` from `IPython.lib.deepreload` to use it.
183 explicitly import `reload` from `IPython.lib.deepreload` to use it.
175
184
176 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
185 .. DO NOT EDIT THIS LINE BEFORE RELEASE. INCOMPAT INSERTION POINT.
General Comments 0
You need to be logged in to leave comments. Login now