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