##// END OF EJS Templates
flush stdout/err after init_code...
MinRK -
Show More
@@ -1,292 +1,296 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 A mixin for :class:`~IPython.core.application.Application` classes that
3 A mixin for :class:`~IPython.core.application.Application` classes that
4 launch InteractiveShell instances, load extensions, etc.
4 launch InteractiveShell instances, load extensions, etc.
5
5
6 Authors
6 Authors
7 -------
7 -------
8
8
9 * Min Ragan-Kelley
9 * Min Ragan-Kelley
10 """
10 """
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Copyright (C) 2008-2011 The IPython Development Team
13 # Copyright (C) 2008-2011 The IPython Development Team
14 #
14 #
15 # Distributed under the terms of the BSD License. The full license is in
15 # Distributed under the terms of the BSD License. The full license is in
16 # the file COPYING, distributed as part of this software.
16 # the file COPYING, distributed as part of this software.
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Imports
20 # Imports
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22
22
23 from __future__ import absolute_import
23 from __future__ import absolute_import
24
24
25 import glob
25 import glob
26 import os
26 import os
27 import sys
27 import sys
28
28
29 from IPython.config.application import boolean_flag
29 from IPython.config.application import boolean_flag
30 from IPython.config.configurable import Configurable
30 from IPython.config.configurable import Configurable
31 from IPython.config.loader import Config
31 from IPython.config.loader import Config
32 from IPython.utils import py3compat
32 from IPython.utils import py3compat
33 from IPython.utils.path import filefind
33 from IPython.utils.path import filefind
34 from IPython.utils.traitlets import Unicode, Instance, List, Bool
34 from IPython.utils.traitlets import Unicode, Instance, List, Bool
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Aliases and Flags
37 # Aliases and Flags
38 #-----------------------------------------------------------------------------
38 #-----------------------------------------------------------------------------
39
39
40 shell_flags = {}
40 shell_flags = {}
41
41
42 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
42 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
43 addflag('autoindent', 'InteractiveShell.autoindent',
43 addflag('autoindent', 'InteractiveShell.autoindent',
44 'Turn on autoindenting.', 'Turn off autoindenting.'
44 'Turn on autoindenting.', 'Turn off autoindenting.'
45 )
45 )
46 addflag('automagic', 'InteractiveShell.automagic',
46 addflag('automagic', 'InteractiveShell.automagic',
47 """Turn on the auto calling of magic commands. Type %%magic at the
47 """Turn on the auto calling of magic commands. Type %%magic at the
48 IPython prompt for more information.""",
48 IPython prompt for more information.""",
49 'Turn off the auto calling of magic commands.'
49 'Turn off the auto calling of magic commands.'
50 )
50 )
51 addflag('pdb', 'InteractiveShell.pdb',
51 addflag('pdb', 'InteractiveShell.pdb',
52 "Enable auto calling the pdb debugger after every exception.",
52 "Enable auto calling the pdb debugger after every exception.",
53 "Disable auto calling the pdb debugger after every exception."
53 "Disable auto calling the pdb debugger after every exception."
54 )
54 )
55 # pydb flag doesn't do any config, as core.debugger switches on import,
55 # pydb flag doesn't do any config, as core.debugger switches on import,
56 # which is before parsing. This just allows the flag to be passed.
56 # which is before parsing. This just allows the flag to be passed.
57 shell_flags.update(dict(
57 shell_flags.update(dict(
58 pydb = ({},
58 pydb = ({},
59 """"Use the third party 'pydb' package as debugger, instead of pdb.
59 """"Use the third party 'pydb' package as debugger, instead of pdb.
60 Requires that pydb is installed."""
60 Requires that pydb is installed."""
61 )
61 )
62 ))
62 ))
63 addflag('pprint', 'PlainTextFormatter.pprint',
63 addflag('pprint', 'PlainTextFormatter.pprint',
64 "Enable auto pretty printing of results.",
64 "Enable auto pretty printing of results.",
65 "Disable auto auto pretty printing of results."
65 "Disable auto auto pretty printing of results."
66 )
66 )
67 addflag('color-info', 'InteractiveShell.color_info',
67 addflag('color-info', 'InteractiveShell.color_info',
68 """IPython can display information about objects via a set of func-
68 """IPython can display information about objects via a set of func-
69 tions, and optionally can use colors for this, syntax highlighting
69 tions, and optionally can use colors for this, syntax highlighting
70 source code and various other elements. However, because this
70 source code and various other elements. However, because this
71 information is passed through a pager (like 'less') and many pagers get
71 information is passed through a pager (like 'less') and many pagers get
72 confused with color codes, this option is off by default. You can test
72 confused with color codes, this option is off by default. You can test
73 it and turn it on permanently in your ipython_config.py file if it
73 it and turn it on permanently in your ipython_config.py file if it
74 works for you. Test it and turn it on permanently if it works with
74 works for you. Test it and turn it on permanently if it works with
75 your system. The magic function %%color_info allows you to toggle this
75 your system. The magic function %%color_info allows you to toggle this
76 interactively for testing.""",
76 interactively for testing.""",
77 "Disable using colors for info related things."
77 "Disable using colors for info related things."
78 )
78 )
79 addflag('deep-reload', 'InteractiveShell.deep_reload',
79 addflag('deep-reload', 'InteractiveShell.deep_reload',
80 """Enable deep (recursive) reloading by default. IPython can use the
80 """Enable deep (recursive) reloading by default. IPython can use the
81 deep_reload module which reloads changes in modules recursively (it
81 deep_reload module which reloads changes in modules recursively (it
82 replaces the reload() function, so you don't need to change anything to
82 replaces the reload() function, so you don't need to change anything to
83 use it). deep_reload() forces a full reload of modules whose code may
83 use it). deep_reload() forces a full reload of modules whose code may
84 have changed, which the default reload() function does not. When
84 have changed, which the default reload() function does not. When
85 deep_reload is off, IPython will use the normal reload(), but
85 deep_reload is off, IPython will use the normal reload(), but
86 deep_reload will still be available as dreload(). This feature is off
86 deep_reload will still be available as dreload(). This feature is off
87 by default [which means that you have both normal reload() and
87 by default [which means that you have both normal reload() and
88 dreload()].""",
88 dreload()].""",
89 "Disable deep (recursive) reloading by default."
89 "Disable deep (recursive) reloading by default."
90 )
90 )
91 nosep_config = Config()
91 nosep_config = Config()
92 nosep_config.InteractiveShell.separate_in = ''
92 nosep_config.InteractiveShell.separate_in = ''
93 nosep_config.InteractiveShell.separate_out = ''
93 nosep_config.InteractiveShell.separate_out = ''
94 nosep_config.InteractiveShell.separate_out2 = ''
94 nosep_config.InteractiveShell.separate_out2 = ''
95
95
96 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
96 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
97
97
98
98
99 # it's possible we don't want short aliases for *all* of these:
99 # it's possible we don't want short aliases for *all* of these:
100 shell_aliases = dict(
100 shell_aliases = dict(
101 autocall='InteractiveShell.autocall',
101 autocall='InteractiveShell.autocall',
102 colors='InteractiveShell.colors',
102 colors='InteractiveShell.colors',
103 logfile='InteractiveShell.logfile',
103 logfile='InteractiveShell.logfile',
104 logappend='InteractiveShell.logappend',
104 logappend='InteractiveShell.logappend',
105 c='InteractiveShellApp.code_to_run',
105 c='InteractiveShellApp.code_to_run',
106 ext='InteractiveShellApp.extra_extension',
106 ext='InteractiveShellApp.extra_extension',
107 )
107 )
108 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
108 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
109
109
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111 # Main classes and functions
111 # Main classes and functions
112 #-----------------------------------------------------------------------------
112 #-----------------------------------------------------------------------------
113
113
114 class InteractiveShellApp(Configurable):
114 class InteractiveShellApp(Configurable):
115 """A Mixin for applications that start InteractiveShell instances.
115 """A Mixin for applications that start InteractiveShell instances.
116
116
117 Provides configurables for loading extensions and executing files
117 Provides configurables for loading extensions and executing files
118 as part of configuring a Shell environment.
118 as part of configuring a Shell environment.
119
119
120 Provides init_extensions() and init_code() methods, to be called
120 Provides init_extensions() and init_code() methods, to be called
121 after init_shell(), which must be implemented by subclasses.
121 after init_shell(), which must be implemented by subclasses.
122 """
122 """
123 extensions = List(Unicode, config=True,
123 extensions = List(Unicode, config=True,
124 help="A list of dotted module names of IPython extensions to load."
124 help="A list of dotted module names of IPython extensions to load."
125 )
125 )
126 extra_extension = Unicode('', config=True,
126 extra_extension = Unicode('', config=True,
127 help="dotted module name of an IPython extension to load."
127 help="dotted module name of an IPython extension to load."
128 )
128 )
129 def _extra_extension_changed(self, name, old, new):
129 def _extra_extension_changed(self, name, old, new):
130 if new:
130 if new:
131 # add to self.extensions
131 # add to self.extensions
132 self.extensions.append(new)
132 self.extensions.append(new)
133
133
134 # Extensions that are always loaded (not configurable)
134 # Extensions that are always loaded (not configurable)
135 default_extensions = List(Unicode, [u'storemagic'], config=False)
135 default_extensions = List(Unicode, [u'storemagic'], config=False)
136
136
137 exec_files = List(Unicode, config=True,
137 exec_files = List(Unicode, config=True,
138 help="""List of files to run at IPython startup."""
138 help="""List of files to run at IPython startup."""
139 )
139 )
140 file_to_run = Unicode('', config=True,
140 file_to_run = Unicode('', config=True,
141 help="""A file to be run""")
141 help="""A file to be run""")
142
142
143 exec_lines = List(Unicode, config=True,
143 exec_lines = List(Unicode, config=True,
144 help="""lines of code to run at IPython startup."""
144 help="""lines of code to run at IPython startup."""
145 )
145 )
146 code_to_run = Unicode('', config=True,
146 code_to_run = Unicode('', config=True,
147 help="Execute the given command string."
147 help="Execute the given command string."
148 )
148 )
149 pylab_import_all = Bool(True, config=True,
149 pylab_import_all = Bool(True, config=True,
150 help="""If true, an 'import *' is done from numpy and pylab,
150 help="""If true, an 'import *' is done from numpy and pylab,
151 when using pylab"""
151 when using pylab"""
152 )
152 )
153 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
153 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
154
154
155 def init_shell(self):
155 def init_shell(self):
156 raise NotImplementedError("Override in subclasses")
156 raise NotImplementedError("Override in subclasses")
157
157
158 def init_extensions(self):
158 def init_extensions(self):
159 """Load all IPython extensions in IPythonApp.extensions.
159 """Load all IPython extensions in IPythonApp.extensions.
160
160
161 This uses the :meth:`ExtensionManager.load_extensions` to load all
161 This uses the :meth:`ExtensionManager.load_extensions` to load all
162 the extensions listed in ``self.extensions``.
162 the extensions listed in ``self.extensions``.
163 """
163 """
164 try:
164 try:
165 self.log.debug("Loading IPython extensions...")
165 self.log.debug("Loading IPython extensions...")
166 extensions = self.default_extensions + self.extensions
166 extensions = self.default_extensions + self.extensions
167 for ext in extensions:
167 for ext in extensions:
168 try:
168 try:
169 self.log.info("Loading IPython extension: %s" % ext)
169 self.log.info("Loading IPython extension: %s" % ext)
170 self.shell.extension_manager.load_extension(ext)
170 self.shell.extension_manager.load_extension(ext)
171 except:
171 except:
172 self.log.warn("Error in loading extension: %s" % ext +
172 self.log.warn("Error in loading extension: %s" % ext +
173 "\nCheck your config files in %s" % self.profile_dir.location
173 "\nCheck your config files in %s" % self.profile_dir.location
174 )
174 )
175 self.shell.showtraceback()
175 self.shell.showtraceback()
176 except:
176 except:
177 self.log.warn("Unknown error in loading extensions:")
177 self.log.warn("Unknown error in loading extensions:")
178 self.shell.showtraceback()
178 self.shell.showtraceback()
179
179
180 def init_code(self):
180 def init_code(self):
181 """run the pre-flight code, specified via exec_lines"""
181 """run the pre-flight code, specified via exec_lines"""
182 self._run_startup_files()
182 self._run_startup_files()
183 self._run_exec_lines()
183 self._run_exec_lines()
184 self._run_exec_files()
184 self._run_exec_files()
185 self._run_cmd_line_code()
185 self._run_cmd_line_code()
186
186
187 # flush output, so itwon't be attached to the first cell
188 sys.stdout.flush()
189 sys.stderr.flush()
190
187 # Hide variables defined here from %who etc.
191 # Hide variables defined here from %who etc.
188 self.shell.user_ns_hidden.update(self.shell.user_ns)
192 self.shell.user_ns_hidden.update(self.shell.user_ns)
189
193
190 def _run_exec_lines(self):
194 def _run_exec_lines(self):
191 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
195 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
192 if not self.exec_lines:
196 if not self.exec_lines:
193 return
197 return
194 try:
198 try:
195 self.log.debug("Running code from IPythonApp.exec_lines...")
199 self.log.debug("Running code from IPythonApp.exec_lines...")
196 for line in self.exec_lines:
200 for line in self.exec_lines:
197 try:
201 try:
198 self.log.info("Running code in user namespace: %s" %
202 self.log.info("Running code in user namespace: %s" %
199 line)
203 line)
200 self.shell.run_cell(line, store_history=False)
204 self.shell.run_cell(line, store_history=False)
201 except:
205 except:
202 self.log.warn("Error in executing line in user "
206 self.log.warn("Error in executing line in user "
203 "namespace: %s" % line)
207 "namespace: %s" % line)
204 self.shell.showtraceback()
208 self.shell.showtraceback()
205 except:
209 except:
206 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
210 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
207 self.shell.showtraceback()
211 self.shell.showtraceback()
208
212
209 def _exec_file(self, fname):
213 def _exec_file(self, fname):
210 try:
214 try:
211 full_filename = filefind(fname, [u'.', self.ipython_dir])
215 full_filename = filefind(fname, [u'.', self.ipython_dir])
212 except IOError as e:
216 except IOError as e:
213 self.log.warn("File not found: %r"%fname)
217 self.log.warn("File not found: %r"%fname)
214 return
218 return
215 # Make sure that the running script gets a proper sys.argv as if it
219 # Make sure that the running script gets a proper sys.argv as if it
216 # were run from a system shell.
220 # were run from a system shell.
217 save_argv = sys.argv
221 save_argv = sys.argv
218 sys.argv = [full_filename] + self.extra_args[1:]
222 sys.argv = [full_filename] + self.extra_args[1:]
219 # protect sys.argv from potential unicode strings on Python 2:
223 # protect sys.argv from potential unicode strings on Python 2:
220 if not py3compat.PY3:
224 if not py3compat.PY3:
221 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
225 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
222 try:
226 try:
223 if os.path.isfile(full_filename):
227 if os.path.isfile(full_filename):
224 if full_filename.endswith('.ipy'):
228 if full_filename.endswith('.ipy'):
225 self.log.info("Running file in user namespace: %s" %
229 self.log.info("Running file in user namespace: %s" %
226 full_filename)
230 full_filename)
227 self.shell.safe_execfile_ipy(full_filename)
231 self.shell.safe_execfile_ipy(full_filename)
228 else:
232 else:
229 # default to python, even without extension
233 # default to python, even without extension
230 self.log.info("Running file in user namespace: %s" %
234 self.log.info("Running file in user namespace: %s" %
231 full_filename)
235 full_filename)
232 # Ensure that __file__ is always defined to match Python behavior
236 # Ensure that __file__ is always defined to match Python behavior
233 self.shell.user_ns['__file__'] = fname
237 self.shell.user_ns['__file__'] = fname
234 try:
238 try:
235 self.shell.safe_execfile(full_filename, self.shell.user_ns)
239 self.shell.safe_execfile(full_filename, self.shell.user_ns)
236 finally:
240 finally:
237 del self.shell.user_ns['__file__']
241 del self.shell.user_ns['__file__']
238 finally:
242 finally:
239 sys.argv = save_argv
243 sys.argv = save_argv
240
244
241 def _run_startup_files(self):
245 def _run_startup_files(self):
242 """Run files from profile startup directory"""
246 """Run files from profile startup directory"""
243 startup_dir = self.profile_dir.startup_dir
247 startup_dir = self.profile_dir.startup_dir
244 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
248 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
245 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
249 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
246 if not startup_files:
250 if not startup_files:
247 return
251 return
248
252
249 self.log.debug("Running startup files from %s...", startup_dir)
253 self.log.debug("Running startup files from %s...", startup_dir)
250 try:
254 try:
251 for fname in sorted(startup_files):
255 for fname in sorted(startup_files):
252 self._exec_file(fname)
256 self._exec_file(fname)
253 except:
257 except:
254 self.log.warn("Unknown error in handling startup files:")
258 self.log.warn("Unknown error in handling startup files:")
255 self.shell.showtraceback()
259 self.shell.showtraceback()
256
260
257 def _run_exec_files(self):
261 def _run_exec_files(self):
258 """Run files from IPythonApp.exec_files"""
262 """Run files from IPythonApp.exec_files"""
259 if not self.exec_files:
263 if not self.exec_files:
260 return
264 return
261
265
262 self.log.debug("Running files in IPythonApp.exec_files...")
266 self.log.debug("Running files in IPythonApp.exec_files...")
263 try:
267 try:
264 for fname in self.exec_files:
268 for fname in self.exec_files:
265 self._exec_file(fname)
269 self._exec_file(fname)
266 except:
270 except:
267 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
271 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
268 self.shell.showtraceback()
272 self.shell.showtraceback()
269
273
270 def _run_cmd_line_code(self):
274 def _run_cmd_line_code(self):
271 """Run code or file specified at the command-line"""
275 """Run code or file specified at the command-line"""
272 if self.code_to_run:
276 if self.code_to_run:
273 line = self.code_to_run
277 line = self.code_to_run
274 try:
278 try:
275 self.log.info("Running code given at command line (c=): %s" %
279 self.log.info("Running code given at command line (c=): %s" %
276 line)
280 line)
277 self.shell.run_cell(line, store_history=False)
281 self.shell.run_cell(line, store_history=False)
278 except:
282 except:
279 self.log.warn("Error in executing line in user namespace: %s" %
283 self.log.warn("Error in executing line in user namespace: %s" %
280 line)
284 line)
281 self.shell.showtraceback()
285 self.shell.showtraceback()
282
286
283 # Like Python itself, ignore the second if the first of these is present
287 # Like Python itself, ignore the second if the first of these is present
284 elif self.file_to_run:
288 elif self.file_to_run:
285 fname = self.file_to_run
289 fname = self.file_to_run
286 try:
290 try:
287 self._exec_file(fname)
291 self._exec_file(fname)
288 except:
292 except:
289 self.log.warn("Error in executing file in user namespace: %s" %
293 self.log.warn("Error in executing file in user namespace: %s" %
290 fname)
294 fname)
291 self.shell.showtraceback()
295 self.shell.showtraceback()
292
296
General Comments 0
You need to be logged in to leave comments. Login now