##// END OF EJS Templates
Backport PR #12135: add configuration controlling whether the CWD gets added to sys.path
Matthias Bussonnier -
Show More
@@ -1,428 +1,440 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
6
7 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9
9
10 import glob
10 import glob
11 from itertools import chain
11 from itertools import chain
12 import os
12 import os
13 import sys
13 import sys
14
14
15 from traitlets.config.application import boolean_flag
15 from traitlets.config.application import boolean_flag
16 from traitlets.config.configurable import Configurable
16 from traitlets.config.configurable import Configurable
17 from traitlets.config.loader import Config
17 from traitlets.config.loader import Config
18 from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS
18 from IPython.core.application import SYSTEM_CONFIG_DIRS, ENV_CONFIG_DIRS
19 from IPython.core import pylabtools
19 from IPython.core import pylabtools
20 from IPython.utils.contexts import preserve_keys
20 from IPython.utils.contexts import preserve_keys
21 from IPython.utils.path import filefind
21 from IPython.utils.path import filefind
22 from traitlets import (
22 from traitlets import (
23 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
23 Unicode, Instance, List, Bool, CaselessStrEnum, observe,
24 )
24 )
25 from IPython.terminal import pt_inputhooks
25 from IPython.terminal import pt_inputhooks
26
26
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28 # Aliases and Flags
28 # Aliases and Flags
29 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
30
30
31 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
31 gui_keys = tuple(sorted(pt_inputhooks.backends) + sorted(pt_inputhooks.aliases))
32
32
33 backend_keys = sorted(pylabtools.backends.keys())
33 backend_keys = sorted(pylabtools.backends.keys())
34 backend_keys.insert(0, 'auto')
34 backend_keys.insert(0, 'auto')
35
35
36 shell_flags = {}
36 shell_flags = {}
37
37
38 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
38 addflag = lambda *args: shell_flags.update(boolean_flag(*args))
39 addflag('autoindent', 'InteractiveShell.autoindent',
39 addflag('autoindent', 'InteractiveShell.autoindent',
40 'Turn on autoindenting.', 'Turn off autoindenting.'
40 'Turn on autoindenting.', 'Turn off autoindenting.'
41 )
41 )
42 addflag('automagic', 'InteractiveShell.automagic',
42 addflag('automagic', 'InteractiveShell.automagic',
43 """Turn on the auto calling of magic commands. Type %%magic at the
43 """Turn on the auto calling of magic commands. Type %%magic at the
44 IPython prompt for more information.""",
44 IPython prompt for more information.""",
45 'Turn off the auto calling of magic commands.'
45 'Turn off the auto calling of magic commands.'
46 )
46 )
47 addflag('pdb', 'InteractiveShell.pdb',
47 addflag('pdb', 'InteractiveShell.pdb',
48 "Enable auto calling the pdb debugger after every exception.",
48 "Enable auto calling the pdb debugger after every exception.",
49 "Disable auto calling the pdb debugger after every exception."
49 "Disable auto calling the pdb debugger after every exception."
50 )
50 )
51 addflag('pprint', 'PlainTextFormatter.pprint',
51 addflag('pprint', 'PlainTextFormatter.pprint',
52 "Enable auto pretty printing of results.",
52 "Enable auto pretty printing of results.",
53 "Disable auto pretty printing of results."
53 "Disable auto pretty printing of results."
54 )
54 )
55 addflag('color-info', 'InteractiveShell.color_info',
55 addflag('color-info', 'InteractiveShell.color_info',
56 """IPython can display information about objects via a set of functions,
56 """IPython can display information about objects via a set of functions,
57 and optionally can use colors for this, syntax highlighting
57 and optionally can use colors for this, syntax highlighting
58 source code and various other elements. This is on by default, but can cause
58 source code and various other elements. This is on by default, but can cause
59 problems with some pagers. If you see such problems, you can disable the
59 problems with some pagers. If you see such problems, you can disable the
60 colours.""",
60 colours.""",
61 "Disable using colors for info related things."
61 "Disable using colors for info related things."
62 )
62 )
63 addflag('ignore-cwd', 'InteractiveShellApp.ignore_cwd',
64 "Exclude the current working directory from sys.path",
65 "Include the current working directory in sys.path",
66 )
63 nosep_config = Config()
67 nosep_config = Config()
64 nosep_config.InteractiveShell.separate_in = ''
68 nosep_config.InteractiveShell.separate_in = ''
65 nosep_config.InteractiveShell.separate_out = ''
69 nosep_config.InteractiveShell.separate_out = ''
66 nosep_config.InteractiveShell.separate_out2 = ''
70 nosep_config.InteractiveShell.separate_out2 = ''
67
71
68 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
72 shell_flags['nosep']=(nosep_config, "Eliminate all spacing between prompts.")
69 shell_flags['pylab'] = (
73 shell_flags['pylab'] = (
70 {'InteractiveShellApp' : {'pylab' : 'auto'}},
74 {'InteractiveShellApp' : {'pylab' : 'auto'}},
71 """Pre-load matplotlib and numpy for interactive use with
75 """Pre-load matplotlib and numpy for interactive use with
72 the default matplotlib backend."""
76 the default matplotlib backend."""
73 )
77 )
74 shell_flags['matplotlib'] = (
78 shell_flags['matplotlib'] = (
75 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
79 {'InteractiveShellApp' : {'matplotlib' : 'auto'}},
76 """Configure matplotlib for interactive use with
80 """Configure matplotlib for interactive use with
77 the default matplotlib backend."""
81 the default matplotlib backend."""
78 )
82 )
79
83
80 # it's possible we don't want short aliases for *all* of these:
84 # it's possible we don't want short aliases for *all* of these:
81 shell_aliases = dict(
85 shell_aliases = dict(
82 autocall='InteractiveShell.autocall',
86 autocall='InteractiveShell.autocall',
83 colors='InteractiveShell.colors',
87 colors='InteractiveShell.colors',
84 logfile='InteractiveShell.logfile',
88 logfile='InteractiveShell.logfile',
85 logappend='InteractiveShell.logappend',
89 logappend='InteractiveShell.logappend',
86 c='InteractiveShellApp.code_to_run',
90 c='InteractiveShellApp.code_to_run',
87 m='InteractiveShellApp.module_to_run',
91 m='InteractiveShellApp.module_to_run',
88 ext='InteractiveShellApp.extra_extension',
92 ext='InteractiveShellApp.extra_extension',
89 gui='InteractiveShellApp.gui',
93 gui='InteractiveShellApp.gui',
90 pylab='InteractiveShellApp.pylab',
94 pylab='InteractiveShellApp.pylab',
91 matplotlib='InteractiveShellApp.matplotlib',
95 matplotlib='InteractiveShellApp.matplotlib',
92 )
96 )
93 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
97 shell_aliases['cache-size'] = 'InteractiveShell.cache_size'
94
98
95 #-----------------------------------------------------------------------------
99 #-----------------------------------------------------------------------------
96 # Main classes and functions
100 # Main classes and functions
97 #-----------------------------------------------------------------------------
101 #-----------------------------------------------------------------------------
98
102
99 class InteractiveShellApp(Configurable):
103 class InteractiveShellApp(Configurable):
100 """A Mixin for applications that start InteractiveShell instances.
104 """A Mixin for applications that start InteractiveShell instances.
101
105
102 Provides configurables for loading extensions and executing files
106 Provides configurables for loading extensions and executing files
103 as part of configuring a Shell environment.
107 as part of configuring a Shell environment.
104
108
105 The following methods should be called by the :meth:`initialize` method
109 The following methods should be called by the :meth:`initialize` method
106 of the subclass:
110 of the subclass:
107
111
108 - :meth:`init_path`
112 - :meth:`init_path`
109 - :meth:`init_shell` (to be implemented by the subclass)
113 - :meth:`init_shell` (to be implemented by the subclass)
110 - :meth:`init_gui_pylab`
114 - :meth:`init_gui_pylab`
111 - :meth:`init_extensions`
115 - :meth:`init_extensions`
112 - :meth:`init_code`
116 - :meth:`init_code`
113 """
117 """
114 extensions = List(Unicode(),
118 extensions = List(Unicode(),
115 help="A list of dotted module names of IPython extensions to load."
119 help="A list of dotted module names of IPython extensions to load."
116 ).tag(config=True)
120 ).tag(config=True)
117 extra_extension = Unicode('',
121 extra_extension = Unicode('',
118 help="dotted module name of an IPython extension to load."
122 help="dotted module name of an IPython extension to load."
119 ).tag(config=True)
123 ).tag(config=True)
120
124
121 reraise_ipython_extension_failures = Bool(False,
125 reraise_ipython_extension_failures = Bool(False,
122 help="Reraise exceptions encountered loading IPython extensions?",
126 help="Reraise exceptions encountered loading IPython extensions?",
123 ).tag(config=True)
127 ).tag(config=True)
124
128
125 # Extensions that are always loaded (not configurable)
129 # Extensions that are always loaded (not configurable)
126 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
130 default_extensions = List(Unicode(), [u'storemagic']).tag(config=False)
127
131
128 hide_initial_ns = Bool(True,
132 hide_initial_ns = Bool(True,
129 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
133 help="""Should variables loaded at startup (by startup files, exec_lines, etc.)
130 be hidden from tools like %who?"""
134 be hidden from tools like %who?"""
131 ).tag(config=True)
135 ).tag(config=True)
132
136
133 exec_files = List(Unicode(),
137 exec_files = List(Unicode(),
134 help="""List of files to run at IPython startup."""
138 help="""List of files to run at IPython startup."""
135 ).tag(config=True)
139 ).tag(config=True)
136 exec_PYTHONSTARTUP = Bool(True,
140 exec_PYTHONSTARTUP = Bool(True,
137 help="""Run the file referenced by the PYTHONSTARTUP environment
141 help="""Run the file referenced by the PYTHONSTARTUP environment
138 variable at IPython startup."""
142 variable at IPython startup."""
139 ).tag(config=True)
143 ).tag(config=True)
140 file_to_run = Unicode('',
144 file_to_run = Unicode('',
141 help="""A file to be run""").tag(config=True)
145 help="""A file to be run""").tag(config=True)
142
146
143 exec_lines = List(Unicode(),
147 exec_lines = List(Unicode(),
144 help="""lines of code to run at IPython startup."""
148 help="""lines of code to run at IPython startup."""
145 ).tag(config=True)
149 ).tag(config=True)
146 code_to_run = Unicode('',
150 code_to_run = Unicode('',
147 help="Execute the given command string."
151 help="Execute the given command string."
148 ).tag(config=True)
152 ).tag(config=True)
149 module_to_run = Unicode('',
153 module_to_run = Unicode('',
150 help="Run the module as a script."
154 help="Run the module as a script."
151 ).tag(config=True)
155 ).tag(config=True)
152 gui = CaselessStrEnum(gui_keys, allow_none=True,
156 gui = CaselessStrEnum(gui_keys, allow_none=True,
153 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
157 help="Enable GUI event loop integration with any of {0}.".format(gui_keys)
154 ).tag(config=True)
158 ).tag(config=True)
155 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
159 matplotlib = CaselessStrEnum(backend_keys, allow_none=True,
156 help="""Configure matplotlib for interactive use with
160 help="""Configure matplotlib for interactive use with
157 the default matplotlib backend."""
161 the default matplotlib backend."""
158 ).tag(config=True)
162 ).tag(config=True)
159 pylab = CaselessStrEnum(backend_keys, allow_none=True,
163 pylab = CaselessStrEnum(backend_keys, allow_none=True,
160 help="""Pre-load matplotlib and numpy for interactive use,
164 help="""Pre-load matplotlib and numpy for interactive use,
161 selecting a particular matplotlib backend and loop integration.
165 selecting a particular matplotlib backend and loop integration.
162 """
166 """
163 ).tag(config=True)
167 ).tag(config=True)
164 pylab_import_all = Bool(True,
168 pylab_import_all = Bool(True,
165 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
169 help="""If true, IPython will populate the user namespace with numpy, pylab, etc.
166 and an ``import *`` is done from numpy and pylab, when using pylab mode.
170 and an ``import *`` is done from numpy and pylab, when using pylab mode.
167
171
168 When False, pylab mode should not import any names into the user namespace.
172 When False, pylab mode should not import any names into the user namespace.
169 """
173 """
170 ).tag(config=True)
174 ).tag(config=True)
175 ignore_cwd = Bool(
176 False,
177 help="""If True, IPython will not add the current working directory to sys.path.
178 When False, the current working directory is added to sys.path, allowing imports
179 of modules defined in the current directory."""
180 ).tag(config=True)
171 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
181 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC',
172 allow_none=True)
182 allow_none=True)
173 # whether interact-loop should start
183 # whether interact-loop should start
174 interact = Bool(True)
184 interact = Bool(True)
175
185
176 user_ns = Instance(dict, args=None, allow_none=True)
186 user_ns = Instance(dict, args=None, allow_none=True)
177 @observe('user_ns')
187 @observe('user_ns')
178 def _user_ns_changed(self, change):
188 def _user_ns_changed(self, change):
179 if self.shell is not None:
189 if self.shell is not None:
180 self.shell.user_ns = change['new']
190 self.shell.user_ns = change['new']
181 self.shell.init_user_ns()
191 self.shell.init_user_ns()
182
192
183 def init_path(self):
193 def init_path(self):
184 """Add current working directory, '', to sys.path
194 """Add current working directory, '', to sys.path
185
195
186 Unlike Python's default, we insert before the first `site-packages`
196 Unlike Python's default, we insert before the first `site-packages`
187 or `dist-packages` directory,
197 or `dist-packages` directory,
188 so that it is after the standard library.
198 so that it is after the standard library.
189
199
190 .. versionchanged:: 7.2
200 .. versionchanged:: 7.2
191 Try to insert after the standard library, instead of first.
201 Try to insert after the standard library, instead of first.
202 .. versionchanged:: 8.0
203 Allow optionally not including the current directory in sys.path
192 """
204 """
193 if '' in sys.path:
205 if '' in sys.path or self.ignore_cwd:
194 return
206 return
195 for idx, path in enumerate(sys.path):
207 for idx, path in enumerate(sys.path):
196 parent, last_part = os.path.split(path)
208 parent, last_part = os.path.split(path)
197 if last_part in {'site-packages', 'dist-packages'}:
209 if last_part in {'site-packages', 'dist-packages'}:
198 break
210 break
199 else:
211 else:
200 # no site-packages or dist-packages found (?!)
212 # no site-packages or dist-packages found (?!)
201 # back to original behavior of inserting at the front
213 # back to original behavior of inserting at the front
202 idx = 0
214 idx = 0
203 sys.path.insert(idx, '')
215 sys.path.insert(idx, '')
204
216
205 def init_shell(self):
217 def init_shell(self):
206 raise NotImplementedError("Override in subclasses")
218 raise NotImplementedError("Override in subclasses")
207
219
208 def init_gui_pylab(self):
220 def init_gui_pylab(self):
209 """Enable GUI event loop integration, taking pylab into account."""
221 """Enable GUI event loop integration, taking pylab into account."""
210 enable = False
222 enable = False
211 shell = self.shell
223 shell = self.shell
212 if self.pylab:
224 if self.pylab:
213 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
225 enable = lambda key: shell.enable_pylab(key, import_all=self.pylab_import_all)
214 key = self.pylab
226 key = self.pylab
215 elif self.matplotlib:
227 elif self.matplotlib:
216 enable = shell.enable_matplotlib
228 enable = shell.enable_matplotlib
217 key = self.matplotlib
229 key = self.matplotlib
218 elif self.gui:
230 elif self.gui:
219 enable = shell.enable_gui
231 enable = shell.enable_gui
220 key = self.gui
232 key = self.gui
221
233
222 if not enable:
234 if not enable:
223 return
235 return
224
236
225 try:
237 try:
226 r = enable(key)
238 r = enable(key)
227 except ImportError:
239 except ImportError:
228 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
240 self.log.warning("Eventloop or matplotlib integration failed. Is matplotlib installed?")
229 self.shell.showtraceback()
241 self.shell.showtraceback()
230 return
242 return
231 except Exception:
243 except Exception:
232 self.log.warning("GUI event loop or pylab initialization failed")
244 self.log.warning("GUI event loop or pylab initialization failed")
233 self.shell.showtraceback()
245 self.shell.showtraceback()
234 return
246 return
235
247
236 if isinstance(r, tuple):
248 if isinstance(r, tuple):
237 gui, backend = r[:2]
249 gui, backend = r[:2]
238 self.log.info("Enabling GUI event loop integration, "
250 self.log.info("Enabling GUI event loop integration, "
239 "eventloop=%s, matplotlib=%s", gui, backend)
251 "eventloop=%s, matplotlib=%s", gui, backend)
240 if key == "auto":
252 if key == "auto":
241 print("Using matplotlib backend: %s" % backend)
253 print("Using matplotlib backend: %s" % backend)
242 else:
254 else:
243 gui = r
255 gui = r
244 self.log.info("Enabling GUI event loop integration, "
256 self.log.info("Enabling GUI event loop integration, "
245 "eventloop=%s", gui)
257 "eventloop=%s", gui)
246
258
247 def init_extensions(self):
259 def init_extensions(self):
248 """Load all IPython extensions in IPythonApp.extensions.
260 """Load all IPython extensions in IPythonApp.extensions.
249
261
250 This uses the :meth:`ExtensionManager.load_extensions` to load all
262 This uses the :meth:`ExtensionManager.load_extensions` to load all
251 the extensions listed in ``self.extensions``.
263 the extensions listed in ``self.extensions``.
252 """
264 """
253 try:
265 try:
254 self.log.debug("Loading IPython extensions...")
266 self.log.debug("Loading IPython extensions...")
255 extensions = self.default_extensions + self.extensions
267 extensions = self.default_extensions + self.extensions
256 if self.extra_extension:
268 if self.extra_extension:
257 extensions.append(self.extra_extension)
269 extensions.append(self.extra_extension)
258 for ext in extensions:
270 for ext in extensions:
259 try:
271 try:
260 self.log.info("Loading IPython extension: %s" % ext)
272 self.log.info("Loading IPython extension: %s" % ext)
261 self.shell.extension_manager.load_extension(ext)
273 self.shell.extension_manager.load_extension(ext)
262 except:
274 except:
263 if self.reraise_ipython_extension_failures:
275 if self.reraise_ipython_extension_failures:
264 raise
276 raise
265 msg = ("Error in loading extension: {ext}\n"
277 msg = ("Error in loading extension: {ext}\n"
266 "Check your config files in {location}".format(
278 "Check your config files in {location}".format(
267 ext=ext,
279 ext=ext,
268 location=self.profile_dir.location
280 location=self.profile_dir.location
269 ))
281 ))
270 self.log.warning(msg, exc_info=True)
282 self.log.warning(msg, exc_info=True)
271 except:
283 except:
272 if self.reraise_ipython_extension_failures:
284 if self.reraise_ipython_extension_failures:
273 raise
285 raise
274 self.log.warning("Unknown error in loading extensions:", exc_info=True)
286 self.log.warning("Unknown error in loading extensions:", exc_info=True)
275
287
276 def init_code(self):
288 def init_code(self):
277 """run the pre-flight code, specified via exec_lines"""
289 """run the pre-flight code, specified via exec_lines"""
278 self._run_startup_files()
290 self._run_startup_files()
279 self._run_exec_lines()
291 self._run_exec_lines()
280 self._run_exec_files()
292 self._run_exec_files()
281
293
282 # Hide variables defined here from %who etc.
294 # Hide variables defined here from %who etc.
283 if self.hide_initial_ns:
295 if self.hide_initial_ns:
284 self.shell.user_ns_hidden.update(self.shell.user_ns)
296 self.shell.user_ns_hidden.update(self.shell.user_ns)
285
297
286 # command-line execution (ipython -i script.py, ipython -m module)
298 # command-line execution (ipython -i script.py, ipython -m module)
287 # should *not* be excluded from %whos
299 # should *not* be excluded from %whos
288 self._run_cmd_line_code()
300 self._run_cmd_line_code()
289 self._run_module()
301 self._run_module()
290
302
291 # flush output, so itwon't be attached to the first cell
303 # flush output, so itwon't be attached to the first cell
292 sys.stdout.flush()
304 sys.stdout.flush()
293 sys.stderr.flush()
305 sys.stderr.flush()
294
306
295 def _run_exec_lines(self):
307 def _run_exec_lines(self):
296 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
308 """Run lines of code in IPythonApp.exec_lines in the user's namespace."""
297 if not self.exec_lines:
309 if not self.exec_lines:
298 return
310 return
299 try:
311 try:
300 self.log.debug("Running code from IPythonApp.exec_lines...")
312 self.log.debug("Running code from IPythonApp.exec_lines...")
301 for line in self.exec_lines:
313 for line in self.exec_lines:
302 try:
314 try:
303 self.log.info("Running code in user namespace: %s" %
315 self.log.info("Running code in user namespace: %s" %
304 line)
316 line)
305 self.shell.run_cell(line, store_history=False)
317 self.shell.run_cell(line, store_history=False)
306 except:
318 except:
307 self.log.warning("Error in executing line in user "
319 self.log.warning("Error in executing line in user "
308 "namespace: %s" % line)
320 "namespace: %s" % line)
309 self.shell.showtraceback()
321 self.shell.showtraceback()
310 except:
322 except:
311 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
323 self.log.warning("Unknown error in handling IPythonApp.exec_lines:")
312 self.shell.showtraceback()
324 self.shell.showtraceback()
313
325
314 def _exec_file(self, fname, shell_futures=False):
326 def _exec_file(self, fname, shell_futures=False):
315 try:
327 try:
316 full_filename = filefind(fname, [u'.', self.ipython_dir])
328 full_filename = filefind(fname, [u'.', self.ipython_dir])
317 except IOError:
329 except IOError:
318 self.log.warning("File not found: %r"%fname)
330 self.log.warning("File not found: %r"%fname)
319 return
331 return
320 # Make sure that the running script gets a proper sys.argv as if it
332 # Make sure that the running script gets a proper sys.argv as if it
321 # were run from a system shell.
333 # were run from a system shell.
322 save_argv = sys.argv
334 save_argv = sys.argv
323 sys.argv = [full_filename] + self.extra_args[1:]
335 sys.argv = [full_filename] + self.extra_args[1:]
324 try:
336 try:
325 if os.path.isfile(full_filename):
337 if os.path.isfile(full_filename):
326 self.log.info("Running file in user namespace: %s" %
338 self.log.info("Running file in user namespace: %s" %
327 full_filename)
339 full_filename)
328 # Ensure that __file__ is always defined to match Python
340 # Ensure that __file__ is always defined to match Python
329 # behavior.
341 # behavior.
330 with preserve_keys(self.shell.user_ns, '__file__'):
342 with preserve_keys(self.shell.user_ns, '__file__'):
331 self.shell.user_ns['__file__'] = fname
343 self.shell.user_ns['__file__'] = fname
332 if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'):
344 if full_filename.endswith('.ipy') or full_filename.endswith('.ipynb'):
333 self.shell.safe_execfile_ipy(full_filename,
345 self.shell.safe_execfile_ipy(full_filename,
334 shell_futures=shell_futures)
346 shell_futures=shell_futures)
335 else:
347 else:
336 # default to python, even without extension
348 # default to python, even without extension
337 self.shell.safe_execfile(full_filename,
349 self.shell.safe_execfile(full_filename,
338 self.shell.user_ns,
350 self.shell.user_ns,
339 shell_futures=shell_futures,
351 shell_futures=shell_futures,
340 raise_exceptions=True)
352 raise_exceptions=True)
341 finally:
353 finally:
342 sys.argv = save_argv
354 sys.argv = save_argv
343
355
344 def _run_startup_files(self):
356 def _run_startup_files(self):
345 """Run files from profile startup directory"""
357 """Run files from profile startup directory"""
346 startup_dirs = [self.profile_dir.startup_dir] + [
358 startup_dirs = [self.profile_dir.startup_dir] + [
347 os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS)
359 os.path.join(p, 'startup') for p in chain(ENV_CONFIG_DIRS, SYSTEM_CONFIG_DIRS)
348 ]
360 ]
349 startup_files = []
361 startup_files = []
350
362
351 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
363 if self.exec_PYTHONSTARTUP and os.environ.get('PYTHONSTARTUP', False) and \
352 not (self.file_to_run or self.code_to_run or self.module_to_run):
364 not (self.file_to_run or self.code_to_run or self.module_to_run):
353 python_startup = os.environ['PYTHONSTARTUP']
365 python_startup = os.environ['PYTHONSTARTUP']
354 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
366 self.log.debug("Running PYTHONSTARTUP file %s...", python_startup)
355 try:
367 try:
356 self._exec_file(python_startup)
368 self._exec_file(python_startup)
357 except:
369 except:
358 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
370 self.log.warning("Unknown error in handling PYTHONSTARTUP file %s:", python_startup)
359 self.shell.showtraceback()
371 self.shell.showtraceback()
360 for startup_dir in startup_dirs[::-1]:
372 for startup_dir in startup_dirs[::-1]:
361 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
373 startup_files += glob.glob(os.path.join(startup_dir, '*.py'))
362 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
374 startup_files += glob.glob(os.path.join(startup_dir, '*.ipy'))
363 if not startup_files:
375 if not startup_files:
364 return
376 return
365
377
366 self.log.debug("Running startup files from %s...", startup_dir)
378 self.log.debug("Running startup files from %s...", startup_dir)
367 try:
379 try:
368 for fname in sorted(startup_files):
380 for fname in sorted(startup_files):
369 self._exec_file(fname)
381 self._exec_file(fname)
370 except:
382 except:
371 self.log.warning("Unknown error in handling startup files:")
383 self.log.warning("Unknown error in handling startup files:")
372 self.shell.showtraceback()
384 self.shell.showtraceback()
373
385
374 def _run_exec_files(self):
386 def _run_exec_files(self):
375 """Run files from IPythonApp.exec_files"""
387 """Run files from IPythonApp.exec_files"""
376 if not self.exec_files:
388 if not self.exec_files:
377 return
389 return
378
390
379 self.log.debug("Running files in IPythonApp.exec_files...")
391 self.log.debug("Running files in IPythonApp.exec_files...")
380 try:
392 try:
381 for fname in self.exec_files:
393 for fname in self.exec_files:
382 self._exec_file(fname)
394 self._exec_file(fname)
383 except:
395 except:
384 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
396 self.log.warning("Unknown error in handling IPythonApp.exec_files:")
385 self.shell.showtraceback()
397 self.shell.showtraceback()
386
398
387 def _run_cmd_line_code(self):
399 def _run_cmd_line_code(self):
388 """Run code or file specified at the command-line"""
400 """Run code or file specified at the command-line"""
389 if self.code_to_run:
401 if self.code_to_run:
390 line = self.code_to_run
402 line = self.code_to_run
391 try:
403 try:
392 self.log.info("Running code given at command line (c=): %s" %
404 self.log.info("Running code given at command line (c=): %s" %
393 line)
405 line)
394 self.shell.run_cell(line, store_history=False)
406 self.shell.run_cell(line, store_history=False)
395 except:
407 except:
396 self.log.warning("Error in executing line in user namespace: %s" %
408 self.log.warning("Error in executing line in user namespace: %s" %
397 line)
409 line)
398 self.shell.showtraceback()
410 self.shell.showtraceback()
399 if not self.interact:
411 if not self.interact:
400 self.exit(1)
412 self.exit(1)
401
413
402 # Like Python itself, ignore the second if the first of these is present
414 # Like Python itself, ignore the second if the first of these is present
403 elif self.file_to_run:
415 elif self.file_to_run:
404 fname = self.file_to_run
416 fname = self.file_to_run
405 if os.path.isdir(fname):
417 if os.path.isdir(fname):
406 fname = os.path.join(fname, "__main__.py")
418 fname = os.path.join(fname, "__main__.py")
407 if not os.path.exists(fname):
419 if not os.path.exists(fname):
408 self.log.warning("File '%s' doesn't exist", fname)
420 self.log.warning("File '%s' doesn't exist", fname)
409 self.exit(2)
421 self.exit(2)
410 try:
422 try:
411 self._exec_file(fname, shell_futures=True)
423 self._exec_file(fname, shell_futures=True)
412 except:
424 except:
413 self.shell.showtraceback(tb_offset=4)
425 self.shell.showtraceback(tb_offset=4)
414 if not self.interact:
426 if not self.interact:
415 self.exit(1)
427 self.exit(1)
416
428
417 def _run_module(self):
429 def _run_module(self):
418 """Run module specified at the command-line."""
430 """Run module specified at the command-line."""
419 if self.module_to_run:
431 if self.module_to_run:
420 # Make sure that the module gets a proper sys.argv as if it were
432 # Make sure that the module gets a proper sys.argv as if it were
421 # run using `python -m`.
433 # run using `python -m`.
422 save_argv = sys.argv
434 save_argv = sys.argv
423 sys.argv = [sys.executable] + self.extra_args
435 sys.argv = [sys.executable] + self.extra_args
424 try:
436 try:
425 self.shell.safe_run_module(self.module_to_run,
437 self.shell.safe_run_module(self.module_to_run,
426 self.shell.user_ns)
438 self.shell.user_ns)
427 finally:
439 finally:
428 sys.argv = save_argv
440 sys.argv = save_argv
General Comments 0
You need to be logged in to leave comments. Login now