##// END OF EJS Templates
Override sys.argv when calling run_module.
Bradley M. Froehle -
Show More
@@ -1,305 +1,313 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 m='InteractiveShellApp.module_to_run',
106 m='InteractiveShellApp.module_to_run',
107 ext='InteractiveShellApp.extra_extension',
107 ext='InteractiveShellApp.extra_extension',
108 )
108 )
109 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
109 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
110
110
111 #-----------------------------------------------------------------------------
111 #-----------------------------------------------------------------------------
112 # Main classes and functions
112 # Main classes and functions
113 #-----------------------------------------------------------------------------
113 #-----------------------------------------------------------------------------
114
114
115 class InteractiveShellApp(Configurable):
115 class InteractiveShellApp(Configurable):
116 """A Mixin for applications that start InteractiveShell instances.
116 """A Mixin for applications that start InteractiveShell instances.
117
117
118 Provides configurables for loading extensions and executing files
118 Provides configurables for loading extensions and executing files
119 as part of configuring a Shell environment.
119 as part of configuring a Shell environment.
120
120
121 Provides init_extensions() and init_code() methods, to be called
121 Provides init_extensions() and init_code() methods, to be called
122 after init_shell(), which must be implemented by subclasses.
122 after init_shell(), which must be implemented by subclasses.
123 """
123 """
124 extensions = List(Unicode, config=True,
124 extensions = List(Unicode, config=True,
125 help="A list of dotted module names of IPython extensions to load."
125 help="A list of dotted module names of IPython extensions to load."
126 )
126 )
127 extra_extension = Unicode('', config=True,
127 extra_extension = Unicode('', config=True,
128 help="dotted module name of an IPython extension to load."
128 help="dotted module name of an IPython extension to load."
129 )
129 )
130 def _extra_extension_changed(self, name, old, new):
130 def _extra_extension_changed(self, name, old, new):
131 if new:
131 if new:
132 # add to self.extensions
132 # add to self.extensions
133 self.extensions.append(new)
133 self.extensions.append(new)
134
134
135 # Extensions that are always loaded (not configurable)
135 # Extensions that are always loaded (not configurable)
136 default_extensions = List(Unicode, [u'storemagic'], config=False)
136 default_extensions = List(Unicode, [u'storemagic'], config=False)
137
137
138 exec_files = List(Unicode, config=True,
138 exec_files = List(Unicode, config=True,
139 help="""List of files to run at IPython startup."""
139 help="""List of files to run at IPython startup."""
140 )
140 )
141 file_to_run = Unicode('', config=True,
141 file_to_run = Unicode('', config=True,
142 help="""A file to be run""")
142 help="""A file to be run""")
143
143
144 exec_lines = List(Unicode, config=True,
144 exec_lines = List(Unicode, config=True,
145 help="""lines of code to run at IPython startup."""
145 help="""lines of code to run at IPython startup."""
146 )
146 )
147 code_to_run = Unicode('', config=True,
147 code_to_run = Unicode('', config=True,
148 help="Execute the given command string."
148 help="Execute the given command string."
149 )
149 )
150 module_to_run = Unicode('', config=True,
150 module_to_run = Unicode('', config=True,
151 help="Run the module as a script."
151 help="Run the module as a script."
152 )
152 )
153 pylab_import_all = Bool(True, config=True,
153 pylab_import_all = Bool(True, config=True,
154 help="""If true, an 'import *' is done from numpy and pylab,
154 help="""If true, an 'import *' is done from numpy and pylab,
155 when using pylab"""
155 when using pylab"""
156 )
156 )
157 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
157 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
158
158
159 def init_shell(self):
159 def init_shell(self):
160 raise NotImplementedError("Override in subclasses")
160 raise NotImplementedError("Override in subclasses")
161
161
162 def init_extensions(self):
162 def init_extensions(self):
163 """Load all IPython extensions in IPythonApp.extensions.
163 """Load all IPython extensions in IPythonApp.extensions.
164
164
165 This uses the :meth:`ExtensionManager.load_extensions` to load all
165 This uses the :meth:`ExtensionManager.load_extensions` to load all
166 the extensions listed in ``self.extensions``.
166 the extensions listed in ``self.extensions``.
167 """
167 """
168 try:
168 try:
169 self.log.debug("Loading IPython extensions...")
169 self.log.debug("Loading IPython extensions...")
170 extensions = self.default_extensions + self.extensions
170 extensions = self.default_extensions + self.extensions
171 for ext in extensions:
171 for ext in extensions:
172 try:
172 try:
173 self.log.info("Loading IPython extension: %s" % ext)
173 self.log.info("Loading IPython extension: %s" % ext)
174 self.shell.extension_manager.load_extension(ext)
174 self.shell.extension_manager.load_extension(ext)
175 except:
175 except:
176 self.log.warn("Error in loading extension: %s" % ext +
176 self.log.warn("Error in loading extension: %s" % ext +
177 "\nCheck your config files in %s" % self.profile_dir.location
177 "\nCheck your config files in %s" % self.profile_dir.location
178 )
178 )
179 self.shell.showtraceback()
179 self.shell.showtraceback()
180 except:
180 except:
181 self.log.warn("Unknown error in loading extensions:")
181 self.log.warn("Unknown error in loading extensions:")
182 self.shell.showtraceback()
182 self.shell.showtraceback()
183
183
184 def init_code(self):
184 def init_code(self):
185 """run the pre-flight code, specified via exec_lines"""
185 """run the pre-flight code, specified via exec_lines"""
186 self._run_startup_files()
186 self._run_startup_files()
187 self._run_exec_lines()
187 self._run_exec_lines()
188 self._run_exec_files()
188 self._run_exec_files()
189 self._run_cmd_line_code()
189 self._run_cmd_line_code()
190 self._run_module()
190 self._run_module()
191
191
192 # flush output, so itwon't be attached to the first cell
192 # flush output, so itwon't be attached to the first cell
193 sys.stdout.flush()
193 sys.stdout.flush()
194 sys.stderr.flush()
194 sys.stderr.flush()
195
195
196 # Hide variables defined here from %who etc.
196 # Hide variables defined here from %who etc.
197 self.shell.user_ns_hidden.update(self.shell.user_ns)
197 self.shell.user_ns_hidden.update(self.shell.user_ns)
198
198
199 def _run_exec_lines(self):
199 def _run_exec_lines(self):
200 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
200 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
201 if not self.exec_lines:
201 if not self.exec_lines:
202 return
202 return
203 try:
203 try:
204 self.log.debug("Running code from IPythonApp.exec_lines...")
204 self.log.debug("Running code from IPythonApp.exec_lines...")
205 for line in self.exec_lines:
205 for line in self.exec_lines:
206 try:
206 try:
207 self.log.info("Running code in user namespace: %s" %
207 self.log.info("Running code in user namespace: %s" %
208 line)
208 line)
209 self.shell.run_cell(line, store_history=False)
209 self.shell.run_cell(line, store_history=False)
210 except:
210 except:
211 self.log.warn("Error in executing line in user "
211 self.log.warn("Error in executing line in user "
212 "namespace: %s" % line)
212 "namespace: %s" % line)
213 self.shell.showtraceback()
213 self.shell.showtraceback()
214 except:
214 except:
215 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
215 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
216 self.shell.showtraceback()
216 self.shell.showtraceback()
217
217
218 def _exec_file(self, fname):
218 def _exec_file(self, fname):
219 try:
219 try:
220 full_filename = filefind(fname, [u'.', self.ipython_dir])
220 full_filename = filefind(fname, [u'.', self.ipython_dir])
221 except IOError as e:
221 except IOError as e:
222 self.log.warn("File not found: %r"%fname)
222 self.log.warn("File not found: %r"%fname)
223 return
223 return
224 # Make sure that the running script gets a proper sys.argv as if it
224 # Make sure that the running script gets a proper sys.argv as if it
225 # were run from a system shell.
225 # were run from a system shell.
226 save_argv = sys.argv
226 save_argv = sys.argv
227 sys.argv = [full_filename] + self.extra_args[1:]
227 sys.argv = [full_filename] + self.extra_args[1:]
228 # protect sys.argv from potential unicode strings on Python 2:
228 # protect sys.argv from potential unicode strings on Python 2:
229 if not py3compat.PY3:
229 if not py3compat.PY3:
230 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
230 sys.argv = [ py3compat.cast_bytes(a) for a in sys.argv ]
231 try:
231 try:
232 if os.path.isfile(full_filename):
232 if os.path.isfile(full_filename):
233 if full_filename.endswith('.ipy'):
233 if full_filename.endswith('.ipy'):
234 self.log.info("Running file in user namespace: %s" %
234 self.log.info("Running file in user namespace: %s" %
235 full_filename)
235 full_filename)
236 self.shell.safe_execfile_ipy(full_filename)
236 self.shell.safe_execfile_ipy(full_filename)
237 else:
237 else:
238 # default to python, even without extension
238 # default to python, even without extension
239 self.log.info("Running file in user namespace: %s" %
239 self.log.info("Running file in user namespace: %s" %
240 full_filename)
240 full_filename)
241 # Ensure that __file__ is always defined to match Python behavior
241 # Ensure that __file__ is always defined to match Python behavior
242 self.shell.user_ns['__file__'] = fname
242 self.shell.user_ns['__file__'] = fname
243 try:
243 try:
244 self.shell.safe_execfile(full_filename, self.shell.user_ns)
244 self.shell.safe_execfile(full_filename, self.shell.user_ns)
245 finally:
245 finally:
246 del self.shell.user_ns['__file__']
246 del self.shell.user_ns['__file__']
247 finally:
247 finally:
248 sys.argv = save_argv
248 sys.argv = save_argv
249
249
250 def _run_startup_files(self):
250 def _run_startup_files(self):
251 """Run files from profile startup directory"""
251 """Run files from profile startup directory"""
252 startup_dir = self.profile_dir.startup_dir
252 startup_dir = self.profile_dir.startup_dir
253 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
253 startup_files = glob.glob(os.path.join(startup_dir, '*.py'))
254 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
254 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
255 if not startup_files:
255 if not startup_files:
256 return
256 return
257
257
258 self.log.debug("Running startup files from %s...", startup_dir)
258 self.log.debug("Running startup files from %s...", startup_dir)
259 try:
259 try:
260 for fname in sorted(startup_files):
260 for fname in sorted(startup_files):
261 self._exec_file(fname)
261 self._exec_file(fname)
262 except:
262 except:
263 self.log.warn("Unknown error in handling startup files:")
263 self.log.warn("Unknown error in handling startup files:")
264 self.shell.showtraceback()
264 self.shell.showtraceback()
265
265
266 def _run_exec_files(self):
266 def _run_exec_files(self):
267 """Run files from IPythonApp.exec_files"""
267 """Run files from IPythonApp.exec_files"""
268 if not self.exec_files:
268 if not self.exec_files:
269 return
269 return
270
270
271 self.log.debug("Running files in IPythonApp.exec_files...")
271 self.log.debug("Running files in IPythonApp.exec_files...")
272 try:
272 try:
273 for fname in self.exec_files:
273 for fname in self.exec_files:
274 self._exec_file(fname)
274 self._exec_file(fname)
275 except:
275 except:
276 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
276 self.log.warn("Unknown error in handling IPythonApp.exec_files:")
277 self.shell.showtraceback()
277 self.shell.showtraceback()
278
278
279 def _run_cmd_line_code(self):
279 def _run_cmd_line_code(self):
280 """Run code or file specified at the command-line"""
280 """Run code or file specified at the command-line"""
281 if self.code_to_run:
281 if self.code_to_run:
282 line = self.code_to_run
282 line = self.code_to_run
283 try:
283 try:
284 self.log.info("Running code given at command line (c=): %s" %
284 self.log.info("Running code given at command line (c=): %s" %
285 line)
285 line)
286 self.shell.run_cell(line, store_history=False)
286 self.shell.run_cell(line, store_history=False)
287 except:
287 except:
288 self.log.warn("Error in executing line in user namespace: %s" %
288 self.log.warn("Error in executing line in user namespace: %s" %
289 line)
289 line)
290 self.shell.showtraceback()
290 self.shell.showtraceback()
291
291
292 # Like Python itself, ignore the second if the first of these is present
292 # Like Python itself, ignore the second if the first of these is present
293 elif self.file_to_run:
293 elif self.file_to_run:
294 fname = self.file_to_run
294 fname = self.file_to_run
295 try:
295 try:
296 self._exec_file(fname)
296 self._exec_file(fname)
297 except:
297 except:
298 self.log.warn("Error in executing file in user namespace: %s" %
298 self.log.warn("Error in executing file in user namespace: %s" %
299 fname)
299 fname)
300 self.shell.showtraceback()
300 self.shell.showtraceback()
301
301
302 def _run_module(self):
302 def _run_module(self):
303 """Run module specified at the command-line."""
303 """Run module specified at the command-line."""
304 if self.module_to_run:
304 if self.module_to_run:
305 self.shell.safe_run_module(self.module_to_run, self.shell.user_ns)
305 # Make sure that the module gets a proper sys.argv as if it were
306 # run using `python -m`.
307 save_argv = sys.argv
308 sys.argv = [sys.executable] + self.extra_args
309 try:
310 self.shell.safe_run_module(self.module_to_run,
311 self.shell.user_ns)
312 finally:
313 sys.argv = save_argv
General Comments 0
You need to be logged in to leave comments. Login now