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