##// END OF EJS Templates
Split generic part of terminal frontend/terminal/ipapp into core/shellapp...
MinRK -
Show More
@@ -0,0 +1,243 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 """
4 A mixin for :class:`~IPython.core.newapplication.Application` classes that
5 launch InteractiveShell instances, load extensions, etc.
6
7 Authors
8 -------
9
10 * Min Ragan-Kelley
11 """
12
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Imports
22 #-----------------------------------------------------------------------------
23
24 from __future__ import absolute_import
25
26 import os
27 import sys
28
29 from IPython.config.application import boolean_flag
30 from IPython.config.configurable import Configurable
31 from IPython.utils.path import filefind
32 from IPython.utils.traitlets import Unicode, Instance, List
33
34 #-----------------------------------------------------------------------------
35 # Aliases and Flags
36 #-----------------------------------------------------------------------------
37
38 shell_flags = {}
39
40 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
41 addflag('autoindent', 'InteractiveShell.autoindent',
42 'Turn on autoindenting.', 'Turn off autoindenting.'
43 )
44 addflag('automagic', 'InteractiveShell.automagic',
45 """Turn on the auto calling of magic commands. Type %%magic at the
46 IPython prompt for more information.""",
47 'Turn off the auto calling of magic commands.'
48 )
49 addflag('pdb', 'InteractiveShell.pdb',
50 "Enable auto calling the pdb debugger after every exception.",
51 "Disable auto calling the pdb debugger after every exception."
52 )
53 addflag('pprint', 'PlainTextFormatter.pprint',
54 "Enable auto pretty printing of results.",
55 "Disable auto auto pretty printing of results."
56 )
57 addflag('color-info', 'InteractiveShell.color_info',
58 """IPython can display information about objects via a set of func-
59 tions, and optionally can use colors for this, syntax highlighting
60 source code and various other elements. However, because this
61 information is passed through a pager (like 'less') and many pagers get
62 confused with color codes, this option is off by default. You can test
63 it and turn it on permanently in your ipython_config.py file if it
64 works for you. Test it and turn it on permanently if it works with
65 your system. The magic function %%color_info allows you to toggle this
66 inter- actively for testing.""",
67 "Disable using colors for info related things."
68 )
69 addflag('deep-reload', 'InteractiveShell.deep_reload',
70 """Enable deep (recursive) reloading by default. IPython can use the
71 deep_reload module which reloads changes in modules recursively (it
72 replaces the reload() function, so you don't need to change anything to
73 use it). deep_reload() forces a full reload of modules whose code may
74 have changed, which the default reload() function does not. When
75 deep_reload is off, IPython will use the normal reload(), but
76 deep_reload will still be available as dreload(). This feature is off
77 by default [which means that you have both normal reload() and
78 dreload()].""",
79 "Disable deep (recursive) reloading by default."
80 )
81
82 # it's possible we don't want short aliases for *all* of these:
83 shell_aliases = dict(
84 autocall='InteractiveShell.autocall',
85 cache_size='InteractiveShell.cache_size',
86 colors='InteractiveShell.colors',
87 logfile='InteractiveShell.logfile',
88 log_append='InteractiveShell.logappend',
89 pi1='InteractiveShell.prompt_in1',
90 pi2='InteractiveShell.prompt_in1',
91 po='InteractiveShell.prompt_out',
92 si='InteractiveShell.separate_in',
93 so='InteractiveShell.separate_out',
94 so2='InteractiveShell.separate_out2',
95 xmode='InteractiveShell.xmode',
96 c='InteractiveShellApp.code_to_run',
97 ext='InteractiveShellApp.extra_extension',
98 )
99
100 #-----------------------------------------------------------------------------
101 # Main classes and functions
102 #-----------------------------------------------------------------------------
103
104 class InteractiveShellApp(Configurable):
105 """A Mixin for applications that start InteractiveShell instances.
106
107 Provides configurables for loading extensions and executing files
108 as part of configuring a Shell environment.
109
110 Provides init_extensions() and init_code() methods, to be called
111 after init_shell(), which must be implemented by subclasses.
112 """
113 extensions = List(Unicode, config=True,
114 help="A list of dotted module names of IPython extensions to load."
115 )
116 extra_extension = Unicode('', config=True,
117 help="dotted module name of an IPython extension to load."
118 )
119 def _extra_extension_changed(self, name, old, new):
120 if new:
121 # add to self.extensions
122 self.extensions.append(new)
123
124 exec_files = List(Unicode, config=True,
125 help="""List of files to run at IPython startup."""
126 )
127 file_to_run = Unicode('', config=True,
128 help="""A file to be run""")
129
130 exec_lines = List(Unicode, config=True,
131 help="""lines of code to run at IPython startup."""
132 )
133 code_to_run = Unicode('', config=True,
134 help="Execute the given command string."
135 )
136 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
137
138 def init_shell(self):
139 raise NotImplementedError("Override in subclasses")
140
141 def init_extensions(self):
142 """Load all IPython extensions in IPythonApp.extensions.
143
144 This uses the :meth:`ExtensionManager.load_extensions` to load all
145 the extensions listed in ``self.extensions``.
146 """
147 if not self.extensions:
148 return
149 try:
150 self.log.debug("Loading IPython extensions...")
151 extensions = self.extensions
152 for ext in extensions:
153 try:
154 self.log.info("Loading IPython extension: %s" % ext)
155 self.shell.extension_manager.load_extension(ext)
156 except:
157 self.log.warn("Error in loading extension: %s" % ext)
158 self.shell.showtraceback()
159 except:
160 self.log.warn("Unknown error in loading extensions:")
161 self.shell.showtraceback()
162
163 def init_code(self):
164 """run the pre-flight code, specified via exec_lines"""
165 self._run_exec_lines()
166 self._run_exec_files()
167 self._run_cmd_line_code()
168
169 def _run_exec_lines(self):
170 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
171 if not self.exec_lines:
172 return
173 try:
174 self.log.debug("Running code from IPythonApp.exec_lines...")
175 for line in self.exec_lines:
176 try:
177 self.log.info("Running code in user namespace: %s" %
178 line)
179 self.shell.run_cell(line, store_history=False)
180 except:
181 self.log.warn("Error in executing line in user "
182 "namespace: %s" % line)
183 self.shell.showtraceback()
184 except:
185 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
186 self.shell.showtraceback()
187
188 def _exec_file(self, fname):
189 full_filename = filefind(fname, [u'.', self.ipython_dir])
190 if os.path.isfile(full_filename):
191 if full_filename.endswith(u'.py'):
192 self.log.info("Running file in user namespace: %s" %
193 full_filename)
194 # Ensure that __file__ is always defined to match Python behavior
195 self.shell.user_ns['__file__'] = fname
196 try:
197 self.shell.safe_execfile(full_filename, self.shell.user_ns)
198 finally:
199 del self.shell.user_ns['__file__']
200 elif full_filename.endswith('.ipy'):
201 self.log.info("Running file in user namespace: %s" %
202 full_filename)
203 self.shell.safe_execfile_ipy(full_filename)
204 else:
205 self.log.warn("File does not have a .py or .ipy extension: <%s>"
206 % full_filename)
207
208 def _run_exec_files(self):
209 """Run files from IPythonApp.exec_files"""
210 if not self.exec_files:
211 return
212
213 self.log.debug("Running files in IPythonApp.exec_files...")
214 try:
215 for fname in self.exec_files:
216 self._exec_file(fname)
217 except:
218 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
219 self.shell.showtraceback()
220
221 def _run_cmd_line_code(self):
222 """Run code or file specified at the command-line"""
223 if self.code_to_run:
224 line = self.code_to_run
225 try:
226 self.log.info("Running code given at command line (c=): %s" %
227 line)
228 self.shell.run_cell(line, store_history=False)
229 except:
230 self.log.warn("Error in executing line in user namespace: %s" %
231 line)
232 self.shell.showtraceback()
233
234 # Like Python itself, ignore the second if the first of these is present
235 elif self.file_to_run:
236 fname = self.file_to_run
237 try:
238 self._exec_file(fname)
239 except:
240 self.log.warn("Error in executing file in user namespace: %s" %
241 fname)
242 self.shell.showtraceback()
243
@@ -1,166 +1,165 b''
1 1 # Get the config being loaded so we can set attributes on it
2 2 c = get_config()
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Application-level options
6 6 #-----------------------------------------------------------------------------
7 app = c.IPythonApp
8 7
9 # app.display_banner = True
8 # c.TerminalIPythonApp.display_banner = True
10 9
11 # app.classic = False
10 # c.TerminalIPythonApp.classic = False
12 11
13 # app.nosep = True
12 # c.TerminalIPythonApp.nosep = True
14 13
15 14 # If you still use multiple versions of IPytho on the same machine,
16 15 # set this to True to suppress warnings about old configuration files
17 # app.ignore_old_config = False
16 # c.TerminalIPythonApp.ignore_old_config = False
18 17
19 18 # Set this to determine the detail of what is logged at startup.
20 19 # The default is 30 and possible values are 0,10,20,30,40,50.
21 # app.log_level = 20
20 # c.Application.log_level = 20
22 21
23 22 # This should be a list of importable Python modules that have an
24 23 # load_ipython_extension(ip) method. This method gets called when the extension
25 24 # is loaded. You can put your extensions anywhere they can be imported
26 25 # but we add the extensions subdir of the ipython directory to sys.path
27 26 # during extension loading, so you can put them there as well.
28 # app.extensions = [
27 # c.InteractiveShellApp.extensions = [
29 28 # 'myextension'
30 29 # ]
31 30
32 31 # These lines are run in IPython in the user's namespace after extensions
33 32 # are loaded. They can contain full IPython syntax with magics etc.
34 # app.exec_lines = [
33 # c.InteractiveShellApp.exec_lines = [
35 34 # 'import numpy',
36 35 # 'a = 10; b = 20',
37 36 # '1/0'
38 37 # ]
39 38
40 39 # These files are run in IPython in the user's namespace. Files with a .py
41 40 # extension need to be pure Python. Files with a .ipy extension can have
42 41 # custom IPython syntax (like magics, etc.).
43 42 # These files need to be in the cwd, the ipython_dir or be absolute paths.
44 # app.exec_files = [
43 # c.InteractiveShellApp.exec_files = [
45 44 # 'mycode.py',
46 45 # 'fancy.ipy'
47 46 # ]
48 47
49 48 #-----------------------------------------------------------------------------
50 49 # InteractiveShell options
51 50 #-----------------------------------------------------------------------------
52 51
53 52 # c.InteractiveShell.autocall = 1
54 53
55 54 # c.TerminalInteractiveShell.autoedit_syntax = False
56 55
57 56 # c.InteractiveShell.autoindent = True
58 57
59 58 # c.InteractiveShell.automagic = False
60 59
61 # c.TerminalTerminalInteractiveShell.banner1 = 'This if for overriding the default IPython banner'
60 # c.TerminalInteractiveShell.banner1 = 'This if for overriding the default IPython banner'
62 61
63 # c.TerminalTerminalInteractiveShell.banner2 = "This is for extra banner text"
62 # c.TerminalInteractiveShell.banner2 = "This is for extra banner text"
64 63
65 64 # c.InteractiveShell.cache_size = 1000
66 65
67 66 # c.InteractiveShell.colors = 'LightBG'
68 67
69 68 # c.InteractiveShell.color_info = True
70 69
71 70 # c.TerminalInteractiveShell.confirm_exit = True
72 71
73 72 # c.InteractiveShell.deep_reload = False
74 73
75 74 # c.TerminalInteractiveShell.editor = 'nano'
76 75
77 76 # c.InteractiveShell.logstart = True
78 77
79 78 # c.InteractiveShell.logfile = u'ipython_log.py'
80 79
81 80 # c.InteractiveShell.logappend = u'mylog.py'
82 81
83 82 # c.InteractiveShell.object_info_string_level = 0
84 83
85 84 # c.TerminalInteractiveShell.pager = 'less'
86 85
87 86 # c.InteractiveShell.pdb = False
88 87
89 88 # c.InteractiveShell.prompt_in1 = 'In [\#]: '
90 89 # c.InteractiveShell.prompt_in2 = ' .\D.: '
91 90 # c.InteractiveShell.prompt_out = 'Out[\#]: '
92 91 # c.InteractiveShell.prompts_pad_left = True
93 92
94 93 # c.InteractiveShell.quiet = False
95 94
96 95 # c.InteractiveShell.history_length = 10000
97 96
98 97 # Readline
99 98 # c.InteractiveShell.readline_use = True
100 99
101 100 # be careful with meta-key ('\M-<x>') bindings, because
102 101 # they conflict with 8-bit encodings (e.g. UTF8)
103 102
104 103 # c.InteractiveShell.readline_parse_and_bind = [
105 104 # 'tab: complete',
106 105 # '"\C-l": possible-completions',
107 106 # 'set show-all-if-ambiguous on',
108 107 # '"\C-o": tab-insert',
109 108 # '"\C-r": reverse-search-history',
110 109 # '"\C-s": forward-search-history',
111 110 # '"\C-p": history-search-backward',
112 111 # '"\C-n": history-search-forward',
113 112 # '"\e[A": history-search-backward',
114 113 # '"\e[B": history-search-forward',
115 114 # '"\C-k": kill-line',
116 115 # '"\C-u": unix-line-discard',
117 116 # ]
118 117 # c.InteractiveShell.readline_remove_delims = '-/~'
119 118 # c.InteractiveShell.readline_merge_completions = True
120 119 # c.InteractiveShell.readline_omit__names = 0
121 120
122 121 # c.TerminalInteractiveShell.screen_length = 0
123 122
124 123 # c.InteractiveShell.separate_in = '\n'
125 124 # c.InteractiveShell.separate_out = ''
126 125 # c.InteractiveShell.separate_out2 = ''
127 126
128 127 # c.TerminalInteractiveShell.term_title = False
129 128
130 129 # c.InteractiveShell.wildcards_case_sensitive = True
131 130
132 131 # c.InteractiveShell.xmode = 'Context'
133 132
134 133 #-----------------------------------------------------------------------------
135 134 # Formatter and display options
136 135 #-----------------------------------------------------------------------------
137 136
138 137 # c.PlainTextFormatter.pprint = True
139 138
140 139 #-----------------------------------------------------------------------------
141 140 # PrefilterManager options
142 141 #-----------------------------------------------------------------------------
143 142
144 143 # c.PrefilterManager.multi_line_specials = True
145 144
146 145 #-----------------------------------------------------------------------------
147 146 # AliasManager options
148 147 #-----------------------------------------------------------------------------
149 148
150 149 # Do this to disable all defaults
151 150 # c.AliasManager.default_aliases = []
152 151
153 152 # c.AliasManager.user_aliases = [
154 153 # ('foo', 'echo Hi')
155 154 # ]
156 155
157 156 #-----------------------------------------------------------------------------
158 157 # HistoryManager options
159 158 #-----------------------------------------------------------------------------
160 159
161 160 # Enable logging output as well as input to the database.
162 161 # c.HistoryManager.db_log_output = False
163 162
164 163 # Only write to the database every n commands - this can save disk
165 164 # access (and hence power) over the default of writing on every command.
166 165 # c.HistoryManager.db_cache_size = 0
@@ -1,540 +1,356 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 """
4 4 The :class:`~IPython.core.newapplication.Application` object for the command
5 5 line :command:`ipython` program.
6 6
7 7 Authors
8 8 -------
9 9
10 10 * Brian Granger
11 11 * Fernando Perez
12 12 * Min Ragan-Kelley
13 13 """
14 14
15 15 #-----------------------------------------------------------------------------
16 16 # Copyright (C) 2008-2010 The IPython Development Team
17 17 #
18 18 # Distributed under the terms of the BSD License. The full license is in
19 19 # the file COPYING, distributed as part of this software.
20 20 #-----------------------------------------------------------------------------
21 21
22 22 #-----------------------------------------------------------------------------
23 23 # Imports
24 24 #-----------------------------------------------------------------------------
25 25
26 26 from __future__ import absolute_import
27 27
28 28 import logging
29 29 import os
30 30 import sys
31 31
32 32 from IPython.config.loader import (
33 33 Config, PyFileConfigLoader
34 34 )
35 35 from IPython.config.application import boolean_flag
36 36 from IPython.core import release
37 37 from IPython.core import usage
38 38 from IPython.core.crashhandler import CrashHandler
39 39 from IPython.core.formatters import PlainTextFormatter
40 40 from IPython.core.newapplication import (
41 41 ProfileDir, BaseIPythonApplication, base_flags, base_aliases
42 42 )
43 from IPython.core.shellapp import (
44 InteractiveShellApp, shell_flags, shell_aliases
45 )
43 46 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
44 47 from IPython.lib import inputhook
45 from IPython.utils.path import filefind, get_ipython_dir, check_for_old_config
48 from IPython.utils.path import get_ipython_dir, check_for_old_config
46 49 from IPython.utils.traitlets import (
47 Bool, Unicode, Dict, Instance, List,CaselessStrEnum
50 Bool, Dict, CaselessStrEnum
48 51 )
49 52
50 53 #-----------------------------------------------------------------------------
51 54 # Globals, utilities and helpers
52 55 #-----------------------------------------------------------------------------
53 56
54 57 #: The default config file name for this application.
55 58 default_config_file_name = u'ipython_config.py'
56 59
57 60
58
59 61 #-----------------------------------------------------------------------------
60 62 # Crash handler for this application
61 63 #-----------------------------------------------------------------------------
62 64
63 65 _message_template = """\
64 66 Oops, $self.app_name crashed. We do our best to make it stable, but...
65 67
66 68 A crash report was automatically generated with the following information:
67 69 - A verbatim copy of the crash traceback.
68 70 - A copy of your input history during this session.
69 71 - Data on your current $self.app_name configuration.
70 72
71 73 It was left in the file named:
72 74 \t'$self.crash_report_fname'
73 75 If you can email this file to the developers, the information in it will help
74 76 them in understanding and correcting the problem.
75 77
76 78 You can mail it to: $self.contact_name at $self.contact_email
77 79 with the subject '$self.app_name Crash Report'.
78 80
79 81 If you want to do it now, the following command will work (under Unix):
80 82 mail -s '$self.app_name Crash Report' $self.contact_email < $self.crash_report_fname
81 83
82 84 To ensure accurate tracking of this issue, please file a report about it at:
83 85 $self.bug_tracker
84 86 """
85 87
86 88 class IPAppCrashHandler(CrashHandler):
87 89 """sys.excepthook for IPython itself, leaves a detailed report on disk."""
88 90
89 91 message_template = _message_template
90 92
91 93 def __init__(self, app):
92 94 contact_name = release.authors['Fernando'][0]
93 95 contact_email = release.authors['Fernando'][1]
94 96 bug_tracker = 'http://github.com/ipython/ipython/issues'
95 97 super(IPAppCrashHandler,self).__init__(
96 98 app, contact_name, contact_email, bug_tracker
97 99 )
98 100
99 101 def make_report(self,traceback):
100 102 """Return a string containing a crash report."""
101 103
102 104 sec_sep = self.section_sep
103 105 # Start with parent report
104 106 report = [super(IPAppCrashHandler, self).make_report(traceback)]
105 107 # Add interactive-specific info we may have
106 108 rpt_add = report.append
107 109 try:
108 110 rpt_add(sec_sep+"History of session input:")
109 111 for line in self.app.shell.user_ns['_ih']:
110 112 rpt_add(line)
111 113 rpt_add('\n*** Last line of input (may not be in above history):\n')
112 114 rpt_add(self.app.shell._last_input_line+'\n')
113 115 except:
114 116 pass
115 117
116 118 return ''.join(report)
117 119
118 120 #-----------------------------------------------------------------------------
119 121 # Aliases and Flags
120 122 #-----------------------------------------------------------------------------
121 123 flags = dict(base_flags)
122 flags.update({
123
124
125 })
124 flags.update(shell_flags)
126 125 addflag = lambda *args: flags.update(boolean_flag(*args))
127 addflag('autoindent', 'InteractiveShell.autoindent',
128 'Turn on autoindenting.', 'Turn off autoindenting.'
129 )
130 addflag('automagic', 'InteractiveShell.automagic',
131 """Turn on the auto calling of magic commands. Type %%magic at the
132 IPython prompt for more information.""",
133 'Turn off the auto calling of magic commands.'
134 )
135 126 addflag('autoedit-syntax', 'TerminalInteractiveShell.autoedit_syntax',
136 127 'Turn on auto editing of files with syntax errors.',
137 128 'Turn off auto editing of files with syntax errors.'
138 129 )
139 addflag('banner', 'IPythonApp.display_banner',
130 addflag('banner', 'TerminalIPythonApp.display_banner',
140 131 "Display a banner upon starting IPython.",
141 132 "Don't display a banner upon starting IPython."
142 133 )
143 addflag('pdb', 'InteractiveShell.pdb',
144 "Enable auto calling the pdb debugger after every exception.",
145 "Disable auto calling the pdb debugger after every exception."
146 )
147 addflag('pprint', 'PlainTextFormatter.pprint',
148 "Enable auto pretty printing of results.",
149 "Disable auto auto pretty printing of results."
150 )
151 addflag('color-info', 'InteractiveShell.color_info',
152 """IPython can display information about objects via a set of func-
153 tions, and optionally can use colors for this, syntax highlighting
154 source code and various other elements. However, because this
155 information is passed through a pager (like 'less') and many pagers get
156 confused with color codes, this option is off by default. You can test
157 it and turn it on permanently in your ipython_config.py file if it
158 works for you. Test it and turn it on permanently if it works with
159 your system. The magic function %%color_info allows you to toggle this
160 inter- actively for testing.""",
161 "Disable using colors for info related things."
162 )
163 134 addflag('confirm-exit', 'TerminalInteractiveShell.confirm_exit',
164 135 """Set to confirm when you try to exit IPython with an EOF (Control-D
165 136 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
166 137 you can force a direct exit without any confirmation.""",
167 138 "Don't prompt the user when exiting."
168 139 )
169 addflag('deep-reload', 'InteractiveShell.deep_reload',
170 """Enable deep (recursive) reloading by default. IPython can use the
171 deep_reload module which reloads changes in modules recursively (it
172 replaces the reload() function, so you don't need to change anything to
173 use it). deep_reload() forces a full reload of modules whose code may
174 have changed, which the default reload() function does not. When
175 deep_reload is off, IPython will use the normal reload(), but
176 deep_reload will still be available as dreload(). This feature is off
177 by default [which means that you have both normal reload() and
178 dreload()].""",
179 "Disable deep (recursive) reloading by default."
180 )
181 addflag('readline', 'InteractiveShell.readline_use',
182 "Enable readline for command line usage.",
183 "Disable readline for command line usage."
184 )
185 140 addflag('term-title', 'TerminalInteractiveShell.term_title',
186 141 "Enable auto setting the terminal title.",
187 142 "Disable auto setting the terminal title."
188 143 )
189 144 classic_config = Config()
190 145 classic_config.InteractiveShell.cache_size = 0
191 146 classic_config.PlainTextFormatter.pprint = False
192 147 classic_config.InteractiveShell.prompt_in1 = '>>> '
193 148 classic_config.InteractiveShell.prompt_in2 = '... '
194 149 classic_config.InteractiveShell.prompt_out = ''
195 150 classic_config.InteractiveShell.separate_in = ''
196 151 classic_config.InteractiveShell.separate_out = ''
197 152 classic_config.InteractiveShell.separate_out2 = ''
198 153 classic_config.InteractiveShell.colors = 'NoColor'
199 154 classic_config.InteractiveShell.xmode = 'Plain'
200 155
201 156 flags['classic']=(
202 157 classic_config,
203 158 "Gives IPython a similar feel to the classic Python prompt."
204 159 )
205 160 # # log doesn't make so much sense this way anymore
206 161 # paa('--log','-l',
207 162 # action='store_true', dest='InteractiveShell.logstart',
208 163 # help="Start logging to the default log file (./ipython_log.py).")
209 164 #
210 165 # # quick is harder to implement
211 166 flags['quick']=(
212 {'IPythonApp' : {'quick' : True}},
167 {'TerminalIPythonApp' : {'quick' : True}},
213 168 "Enable quick startup with no config files."
214 169 )
215 170
216 171 nosep_config = Config()
217 172 nosep_config.InteractiveShell.separate_in = ''
218 173 nosep_config.InteractiveShell.separate_out = ''
219 174 nosep_config.InteractiveShell.separate_out2 = ''
220 175
221 176 flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
222 177
223 178 flags['i'] = (
224 {'IPythonApp' : {'force_interact' : True}},
179 {'TerminalIPythonApp' : {'force_interact' : True}},
225 180 "If running code from the command line, become interactive afterwards."
226 181 )
227 182 flags['pylab'] = (
228 {'IPythonApp' : {'pylab' : 'auto'}},
183 {'TerminalIPythonApp' : {'pylab' : 'auto'}},
229 184 """Pre-load matplotlib and numpy for interactive use with
230 185 the default matplotlib backend."""
231 186 )
232 187
233 188 aliases = dict(base_aliases)
189 aliases.update(shell_aliases)
234 190
235 191 # it's possible we don't want short aliases for *all* of these:
236 192 aliases.update(dict(
237 autocall='InteractiveShell.autocall',
238 cache_size='InteractiveShell.cache_size',
239 colors='InteractiveShell.colors',
240 193 editor='TerminalInteractiveShell.editor',
241 logfile='InteractiveShell.logfile',
242 log_append='InteractiveShell.logappend',
243 pi1='InteractiveShell.prompt_in1',
244 pi2='InteractiveShell.prompt_in1',
245 po='InteractiveShell.prompt_out',
246 194 sl='TerminalInteractiveShell.screen_length',
247 si='InteractiveShell.separate_in',
248 so='InteractiveShell.separate_out',
249 so2='InteractiveShell.separate_out2',
250 xmode='InteractiveShell.xmode',
251 c='IPythonApp.code_to_run',
252 ext='IPythonApp.extra_extension',
253 gui='IPythonApp.gui',
254 pylab='IPythonApp.pylab',
195 gui='TerminalIPythonApp.gui',
196 pylab='TerminalIPythonApp.pylab',
255 197 ))
256 198
257 199 #-----------------------------------------------------------------------------
258 200 # Main classes and functions
259 201 #-----------------------------------------------------------------------------
260 202
261 class IPythonApp(BaseIPythonApplication):
203 class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
262 204 name = u'ipython'
263 205 description = usage.cl_usage
264 206 # command_line_loader = IPAppConfigLoader
265 207 default_config_file_name = default_config_file_name
266 208 crash_handler_class = IPAppCrashHandler
267 209 flags = Dict(flags)
268 210 aliases = Dict(aliases)
269 classes = [TerminalInteractiveShell, ProfileDir, PlainTextFormatter]
211 classes = [InteractiveShellApp, TerminalInteractiveShell, ProfileDir, PlainTextFormatter]
270 212 # *do* autocreate requested profile
271 213 auto_create=Bool(True)
272 214 copy_config_files=Bool(True)
273 215 # configurables
274 216 ignore_old_config=Bool(False, config=True,
275 217 help="Suppress warning messages about legacy config files"
276 218 )
277 219 quick = Bool(False, config=True,
278 220 help="""Start IPython quickly by skipping the loading of config files."""
279 221 )
280 222 def _quick_changed(self, name, old, new):
281 223 if new:
282 224 self.load_config_file = lambda *a, **kw: None
283 225 self.ignore_old_config=True
284 226
285 227 gui = CaselessStrEnum(('qt','wx','gtk'), config=True,
286 228 help="Enable GUI event loop integration ('qt', 'wx', 'gtk')."
287 229 )
288 230 pylab = CaselessStrEnum(['tk', 'qt', 'wx', 'gtk', 'osx', 'auto'],
289 231 config=True,
290 232 help="""Pre-load matplotlib and numpy for interactive use,
291 233 selecting a particular matplotlib backend and loop integration.
292 234 """
293 235 )
294 236 display_banner = Bool(True, config=True,
295 237 help="Whether to display a banner upon starting IPython."
296 238 )
297 extensions = List(Unicode, config=True,
298 help="A list of dotted module names of IPython extensions to load."
299 )
300 extra_extension = Unicode('', config=True,
301 help="dotted module name of an IPython extension to load."
302 )
303 def _extra_extension_changed(self, name, old, new):
304 if new:
305 # add to self.extensions
306 self.extensions.append(new)
307 239
308 240 # if there is code of files to run from the cmd line, don't interact
309 241 # unless the --i flag (App.force_interact) is true.
310 242 force_interact = Bool(False, config=True,
311 243 help="""If a command or file is given via the command-line,
312 244 e.g. 'ipython foo.py"""
313 245 )
314 246 def _force_interact_changed(self, name, old, new):
315 247 if new:
316 248 self.interact = True
317 249
318 exec_files = List(Unicode, config=True,
319 help="""List of files to run at IPython startup."""
320 )
321 file_to_run = Unicode('', config=True,
322 help="""A file to be run""")
323 250 def _file_to_run_changed(self, name, old, new):
324 251 if new and not self.force_interact:
325 252 self.interact = False
326
327 exec_lines = List(Unicode, config=True,
328 help="""lines of code to run at IPython startup."""
329 )
330 code_to_run = Unicode('', config=True,
331 help="Execute the given command string."
332 )
333 253 _code_to_run_changed = _file_to_run_changed
334 254
335 255 # internal, not-configurable
336 256 interact=Bool(True)
337 257
338 258
339 259 def initialize(self, argv=None):
340 260 """Do actions after construct, but before starting the app."""
341 super(IPythonApp, self).initialize(argv)
261 super(TerminalIPythonApp, self).initialize(argv)
342 262 if not self.ignore_old_config:
343 263 check_for_old_config(self.ipython_dir)
344 264
345 265 # print self.extra_args
346 266 if self.extra_args:
347 267 self.file_to_run = self.extra_args[0]
348 268 # create the shell
349 269 self.init_shell()
350 270 # and draw the banner
351 271 self.init_banner()
352 272 # Now a variety of things that happen after the banner is printed.
353 273 self.init_gui_pylab()
354 274 self.init_extensions()
355 275 self.init_code()
356 276
357 277 def init_shell(self):
358 278 """initialize the InteractiveShell instance"""
359 279 # I am a little hesitant to put these into InteractiveShell itself.
360 280 # But that might be the place for them
361 281 sys.path.insert(0, '')
362 282
363 283 # Create an InteractiveShell instance.
364 284 # shell.display_banner should always be False for the terminal
365 285 # based app, because we call shell.show_banner() by hand below
366 286 # so the banner shows *before* all extension loading stuff.
367 287 self.shell = TerminalInteractiveShell.instance(config=self.config,
368 288 display_banner=False, profile_dir=self.profile_dir,
369 289 ipython_dir=self.ipython_dir)
370 290
371 291 def init_banner(self):
372 292 """optionally display the banner"""
373 293 if self.display_banner and self.interact:
374 294 self.shell.show_banner()
375 295 # Make sure there is a space below the banner.
376 296 if self.log_level <= logging.INFO: print
377 297
378 298
379 299 def init_gui_pylab(self):
380 300 """Enable GUI event loop integration, taking pylab into account."""
381 301 gui = self.gui
382 302
383 303 # Using `pylab` will also require gui activation, though which toolkit
384 304 # to use may be chosen automatically based on mpl configuration.
385 305 if self.pylab:
386 306 activate = self.shell.enable_pylab
387 307 if self.pylab == 'auto':
388 308 gui = None
389 309 else:
390 310 gui = self.pylab
391 311 else:
392 312 # Enable only GUI integration, no pylab
393 313 activate = inputhook.enable_gui
394 314
395 315 if gui or self.pylab:
396 316 try:
397 317 self.log.info("Enabling GUI event loop integration, "
398 318 "toolkit=%s, pylab=%s" % (gui, self.pylab) )
399 319 activate(gui)
400 320 except:
401 321 self.log.warn("Error in enabling GUI event loop integration:")
402 322 self.shell.showtraceback()
403 323
404 def init_extensions(self):
405 """Load all IPython extensions in IPythonApp.extensions.
406
407 This uses the :meth:`ExtensionManager.load_extensions` to load all
408 the extensions listed in ``self.extensions``.
409 """
410 if not self.extensions:
411 return
412 try:
413 self.log.debug("Loading IPython extensions...")
414 extensions = self.extensions
415 for ext in extensions:
416 try:
417 self.log.info("Loading IPython extension: %s" % ext)
418 self.shell.extension_manager.load_extension(ext)
419 except:
420 self.log.warn("Error in loading extension: %s" % ext)
421 self.shell.showtraceback()
422 except:
423 self.log.warn("Unknown error in loading extensions:")
424 self.shell.showtraceback()
425
426 def init_code(self):
427 """run the pre-flight code, specified via exec_lines"""
428 self._run_exec_lines()
429 self._run_exec_files()
430 self._run_cmd_line_code()
431
432 def _run_exec_lines(self):
433 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
434 if not self.exec_lines:
435 return
436 try:
437 self.log.debug("Running code from IPythonApp.exec_lines...")
438 for line in self.exec_lines:
439 try:
440 self.log.info("Running code in user namespace: %s" %
441 line)
442 self.shell.run_cell(line, store_history=False)
443 except:
444 self.log.warn("Error in executing line in user "
445 "namespace: %s" % line)
446 self.shell.showtraceback()
447 except:
448 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
449 self.shell.showtraceback()
450
451 def _exec_file(self, fname):
452 full_filename = filefind(fname, [u'.', self.ipython_dir])
453 if os.path.isfile(full_filename):
454 if full_filename.endswith(u'.py'):
455 self.log.info("Running file in user namespace: %s" %
456 full_filename)
457 # Ensure that __file__ is always defined to match Python behavior
458 self.shell.user_ns['__file__'] = fname
459 try:
460 self.shell.safe_execfile(full_filename, self.shell.user_ns)
461 finally:
462 del self.shell.user_ns['__file__']
463 elif full_filename.endswith('.ipy'):
464 self.log.info("Running file in user namespace: %s" %
465 full_filename)
466 self.shell.safe_execfile_ipy(full_filename)
467 else:
468 self.log.warn("File does not have a .py or .ipy extension: <%s>"
469 % full_filename)
470
471 def _run_exec_files(self):
472 """Run files from IPythonApp.exec_files"""
473 if not self.exec_files:
474 return
475
476 self.log.debug("Running files in IPythonApp.exec_files...")
477 try:
478 for fname in self.exec_files:
479 self._exec_file(fname)
480 except:
481 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
482 self.shell.showtraceback()
483
484 def _run_cmd_line_code(self):
485 """Run code or file specified at the command-line"""
486 if self.code_to_run:
487 line = self.code_to_run
488 try:
489 self.log.info("Running code given at command line (c=): %s" %
490 line)
491 self.shell.run_cell(line, store_history=False)
492 except:
493 self.log.warn("Error in executing line in user namespace: %s" %
494 line)
495 self.shell.showtraceback()
496
497 # Like Python itself, ignore the second if the first of these is present
498 elif self.file_to_run:
499 fname = self.file_to_run
500 try:
501 self._exec_file(fname)
502 except:
503 self.log.warn("Error in executing file in user namespace: %s" %
504 fname)
505 self.shell.showtraceback()
506
507
508 324 def start(self):
509 325 # perform any prexec steps:
510 326 if self.interact:
511 327 self.log.debug("Starting IPython's mainloop...")
512 328 self.shell.mainloop()
513 329 else:
514 330 self.log.debug("IPython not interactive...")
515 331
516 332
517 333 def load_default_config(ipython_dir=None):
518 334 """Load the default config file from the default ipython_dir.
519 335
520 336 This is useful for embedded shells.
521 337 """
522 338 if ipython_dir is None:
523 339 ipython_dir = get_ipython_dir()
524 340 profile_dir = os.path.join(ipython_dir, 'profile_default')
525 341 cl = PyFileConfigLoader(default_config_file_name, profile_dir)
526 342 config = cl.load_config()
527 343 return config
528 344
529 345
530 346 def launch_new_instance():
531 347 """Create and run a full blown IPython instance"""
532 app = IPythonApp()
348 app = TerminalIPythonApp()
533 349 app.initialize()
534 350 # print app.config
535 351 # print app.profile_dir.location
536 352 app.start()
537 353
538 354
539 355 if __name__ == '__main__':
540 356 launch_new_instance()
General Comments 0
You need to be logged in to leave comments. Login now