##// END OF EJS Templates
don't add unicode paths to sys.path...
MinRK -
Show More
@@ -1,382 +1,388 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 An application for IPython.
3 An application for IPython.
4
4
5 All top-level applications should use the classes in this module for
5 All top-level applications should use the classes in this module for
6 handling configuration and creating configurables.
6 handling configuration and creating configurables.
7
7
8 The job of an :class:`Application` is to create the master configuration
8 The job of an :class:`Application` is to create the master configuration
9 object and then create the configurable objects, passing the config to them.
9 object and then create the configurable objects, passing the config to them.
10
10
11 Authors:
11 Authors:
12
12
13 * Brian Granger
13 * Brian Granger
14 * Fernando Perez
14 * Fernando Perez
15 * Min RK
15 * Min RK
16
16
17 """
17 """
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Copyright (C) 2008 The IPython Development Team
20 # Copyright (C) 2008 The IPython Development Team
21 #
21 #
22 # Distributed under the terms of the BSD License. The full license is in
22 # Distributed under the terms of the BSD License. The full license is in
23 # the file COPYING, distributed as part of this software.
23 # the file COPYING, distributed as part of this software.
24 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
25
25
26 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
27 # Imports
27 # Imports
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29
29
30 import atexit
30 import atexit
31 import errno
31 import errno
32 import glob
32 import glob
33 import logging
33 import logging
34 import os
34 import os
35 import shutil
35 import shutil
36 import sys
36 import sys
37
37
38 from IPython.config.application import Application, catch_config_error
38 from IPython.config.application import Application, catch_config_error
39 from IPython.config.loader import ConfigFileNotFound
39 from IPython.config.loader import ConfigFileNotFound
40 from IPython.core import release, crashhandler
40 from IPython.core import release, crashhandler
41 from IPython.core.profiledir import ProfileDir, ProfileDirError
41 from IPython.core.profiledir import ProfileDir, ProfileDirError
42 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
42 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
43 from IPython.utils import py3compat
43 from IPython.utils import py3compat
44 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, Set, Instance
44 from IPython.utils.traitlets import List, Unicode, Type, Bool, Dict, Set, Instance
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Classes and functions
47 # Classes and functions
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49
49
50
50
51 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
52 # Base Application Class
52 # Base Application Class
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54
54
55 # aliases and flags
55 # aliases and flags
56
56
57 base_aliases = {
57 base_aliases = {
58 'profile-dir' : 'ProfileDir.location',
58 'profile-dir' : 'ProfileDir.location',
59 'profile' : 'BaseIPythonApplication.profile',
59 'profile' : 'BaseIPythonApplication.profile',
60 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
60 'ipython-dir' : 'BaseIPythonApplication.ipython_dir',
61 'log-level' : 'Application.log_level',
61 'log-level' : 'Application.log_level',
62 'config' : 'BaseIPythonApplication.extra_config_file',
62 'config' : 'BaseIPythonApplication.extra_config_file',
63 }
63 }
64
64
65 base_flags = dict(
65 base_flags = dict(
66 debug = ({'Application' : {'log_level' : logging.DEBUG}},
66 debug = ({'Application' : {'log_level' : logging.DEBUG}},
67 "set log level to logging.DEBUG (maximize logging output)"),
67 "set log level to logging.DEBUG (maximize logging output)"),
68 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
68 quiet = ({'Application' : {'log_level' : logging.CRITICAL}},
69 "set log level to logging.CRITICAL (minimize logging output)"),
69 "set log level to logging.CRITICAL (minimize logging output)"),
70 init = ({'BaseIPythonApplication' : {
70 init = ({'BaseIPythonApplication' : {
71 'copy_config_files' : True,
71 'copy_config_files' : True,
72 'auto_create' : True}
72 'auto_create' : True}
73 }, """Initialize profile with default config files. This is equivalent
73 }, """Initialize profile with default config files. This is equivalent
74 to running `ipython profile create <profile>` prior to startup.
74 to running `ipython profile create <profile>` prior to startup.
75 """)
75 """)
76 )
76 )
77
77
78
78
79 class BaseIPythonApplication(Application):
79 class BaseIPythonApplication(Application):
80
80
81 name = Unicode(u'ipython')
81 name = Unicode(u'ipython')
82 description = Unicode(u'IPython: an enhanced interactive Python shell.')
82 description = Unicode(u'IPython: an enhanced interactive Python shell.')
83 version = Unicode(release.version)
83 version = Unicode(release.version)
84
84
85 aliases = Dict(base_aliases)
85 aliases = Dict(base_aliases)
86 flags = Dict(base_flags)
86 flags = Dict(base_flags)
87 classes = List([ProfileDir])
87 classes = List([ProfileDir])
88
88
89 # Track whether the config_file has changed,
89 # Track whether the config_file has changed,
90 # because some logic happens only if we aren't using the default.
90 # because some logic happens only if we aren't using the default.
91 config_file_specified = Set()
91 config_file_specified = Set()
92
92
93 config_file_name = Unicode()
93 config_file_name = Unicode()
94 def _config_file_name_default(self):
94 def _config_file_name_default(self):
95 return self.name.replace('-','_') + u'_config.py'
95 return self.name.replace('-','_') + u'_config.py'
96 def _config_file_name_changed(self, name, old, new):
96 def _config_file_name_changed(self, name, old, new):
97 if new != old:
97 if new != old:
98 self.config_file_specified.add(new)
98 self.config_file_specified.add(new)
99
99
100 # The directory that contains IPython's builtin profiles.
100 # The directory that contains IPython's builtin profiles.
101 builtin_profile_dir = Unicode(
101 builtin_profile_dir = Unicode(
102 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
102 os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
103 )
103 )
104
104
105 config_file_paths = List(Unicode)
105 config_file_paths = List(Unicode)
106 def _config_file_paths_default(self):
106 def _config_file_paths_default(self):
107 return [py3compat.getcwd()]
107 return [py3compat.getcwd()]
108
108
109 extra_config_file = Unicode(config=True,
109 extra_config_file = Unicode(config=True,
110 help="""Path to an extra config file to load.
110 help="""Path to an extra config file to load.
111
111
112 If specified, load this config file in addition to any other IPython config.
112 If specified, load this config file in addition to any other IPython config.
113 """)
113 """)
114 def _extra_config_file_changed(self, name, old, new):
114 def _extra_config_file_changed(self, name, old, new):
115 try:
115 try:
116 self.config_files.remove(old)
116 self.config_files.remove(old)
117 except ValueError:
117 except ValueError:
118 pass
118 pass
119 self.config_file_specified.add(new)
119 self.config_file_specified.add(new)
120 self.config_files.append(new)
120 self.config_files.append(new)
121
121
122 profile = Unicode(u'default', config=True,
122 profile = Unicode(u'default', config=True,
123 help="""The IPython profile to use."""
123 help="""The IPython profile to use."""
124 )
124 )
125
125
126 def _profile_changed(self, name, old, new):
126 def _profile_changed(self, name, old, new):
127 self.builtin_profile_dir = os.path.join(
127 self.builtin_profile_dir = os.path.join(
128 get_ipython_package_dir(), u'config', u'profile', new
128 get_ipython_package_dir(), u'config', u'profile', new
129 )
129 )
130
130
131 ipython_dir = Unicode(config=True,
131 ipython_dir = Unicode(config=True,
132 help="""
132 help="""
133 The name of the IPython directory. This directory is used for logging
133 The name of the IPython directory. This directory is used for logging
134 configuration (through profiles), history storage, etc. The default
134 configuration (through profiles), history storage, etc. The default
135 is usually $HOME/.ipython. This options can also be specified through
135 is usually $HOME/.ipython. This options can also be specified through
136 the environment variable IPYTHONDIR.
136 the environment variable IPYTHONDIR.
137 """
137 """
138 )
138 )
139 def _ipython_dir_default(self):
139 def _ipython_dir_default(self):
140 d = get_ipython_dir()
140 d = get_ipython_dir()
141 self._ipython_dir_changed('ipython_dir', d, d)
141 self._ipython_dir_changed('ipython_dir', d, d)
142 return d
142 return d
143
143
144 _in_init_profile_dir = False
144 _in_init_profile_dir = False
145 profile_dir = Instance(ProfileDir)
145 profile_dir = Instance(ProfileDir)
146 def _profile_dir_default(self):
146 def _profile_dir_default(self):
147 # avoid recursion
147 # avoid recursion
148 if self._in_init_profile_dir:
148 if self._in_init_profile_dir:
149 return
149 return
150 # profile_dir requested early, force initialization
150 # profile_dir requested early, force initialization
151 self.init_profile_dir()
151 self.init_profile_dir()
152 return self.profile_dir
152 return self.profile_dir
153
153
154 overwrite = Bool(False, config=True,
154 overwrite = Bool(False, config=True,
155 help="""Whether to overwrite existing config files when copying""")
155 help="""Whether to overwrite existing config files when copying""")
156 auto_create = Bool(False, config=True,
156 auto_create = Bool(False, config=True,
157 help="""Whether to create profile dir if it doesn't exist""")
157 help="""Whether to create profile dir if it doesn't exist""")
158
158
159 config_files = List(Unicode)
159 config_files = List(Unicode)
160 def _config_files_default(self):
160 def _config_files_default(self):
161 return [self.config_file_name]
161 return [self.config_file_name]
162
162
163 copy_config_files = Bool(False, config=True,
163 copy_config_files = Bool(False, config=True,
164 help="""Whether to install the default config files into the profile dir.
164 help="""Whether to install the default config files into the profile dir.
165 If a new profile is being created, and IPython contains config files for that
165 If a new profile is being created, and IPython contains config files for that
166 profile, then they will be staged into the new directory. Otherwise,
166 profile, then they will be staged into the new directory. Otherwise,
167 default config files will be automatically generated.
167 default config files will be automatically generated.
168 """)
168 """)
169
169
170 verbose_crash = Bool(False, config=True,
170 verbose_crash = Bool(False, config=True,
171 help="""Create a massive crash report when IPython encounters what may be an
171 help="""Create a massive crash report when IPython encounters what may be an
172 internal error. The default is to append a short message to the
172 internal error. The default is to append a short message to the
173 usual traceback""")
173 usual traceback""")
174
174
175 # The class to use as the crash handler.
175 # The class to use as the crash handler.
176 crash_handler_class = Type(crashhandler.CrashHandler)
176 crash_handler_class = Type(crashhandler.CrashHandler)
177
177
178 @catch_config_error
178 @catch_config_error
179 def __init__(self, **kwargs):
179 def __init__(self, **kwargs):
180 super(BaseIPythonApplication, self).__init__(**kwargs)
180 super(BaseIPythonApplication, self).__init__(**kwargs)
181 # ensure current working directory exists
181 # ensure current working directory exists
182 try:
182 try:
183 directory = py3compat.getcwd()
183 directory = py3compat.getcwd()
184 except:
184 except:
185 # raise exception
185 # raise exception
186 self.log.error("Current working directory doesn't exist.")
186 self.log.error("Current working directory doesn't exist.")
187 raise
187 raise
188
188
189 #-------------------------------------------------------------------------
189 #-------------------------------------------------------------------------
190 # Various stages of Application creation
190 # Various stages of Application creation
191 #-------------------------------------------------------------------------
191 #-------------------------------------------------------------------------
192
192
193 def init_crash_handler(self):
193 def init_crash_handler(self):
194 """Create a crash handler, typically setting sys.excepthook to it."""
194 """Create a crash handler, typically setting sys.excepthook to it."""
195 self.crash_handler = self.crash_handler_class(self)
195 self.crash_handler = self.crash_handler_class(self)
196 sys.excepthook = self.excepthook
196 sys.excepthook = self.excepthook
197 def unset_crashhandler():
197 def unset_crashhandler():
198 sys.excepthook = sys.__excepthook__
198 sys.excepthook = sys.__excepthook__
199 atexit.register(unset_crashhandler)
199 atexit.register(unset_crashhandler)
200
200
201 def excepthook(self, etype, evalue, tb):
201 def excepthook(self, etype, evalue, tb):
202 """this is sys.excepthook after init_crashhandler
202 """this is sys.excepthook after init_crashhandler
203
203
204 set self.verbose_crash=True to use our full crashhandler, instead of
204 set self.verbose_crash=True to use our full crashhandler, instead of
205 a regular traceback with a short message (crash_handler_lite)
205 a regular traceback with a short message (crash_handler_lite)
206 """
206 """
207
207
208 if self.verbose_crash:
208 if self.verbose_crash:
209 return self.crash_handler(etype, evalue, tb)
209 return self.crash_handler(etype, evalue, tb)
210 else:
210 else:
211 return crashhandler.crash_handler_lite(etype, evalue, tb)
211 return crashhandler.crash_handler_lite(etype, evalue, tb)
212
212
213 def _ipython_dir_changed(self, name, old, new):
213 def _ipython_dir_changed(self, name, old, new):
214 if old in sys.path:
214 str_old = py3compat.cast_bytes_py2(os.path.abspath(old),
215 sys.path.remove(old)
215 sys.getfilesystemencoding()
216 sys.path.append(os.path.abspath(new))
216 )
217 if str_old in sys.path:
218 sys.path.remove(str_old)
219 str_path = py3compat.cast_bytes_py2(os.path.abspath(new),
220 sys.getfilesystemencoding()
221 )
222 sys.path.append(str_path)
217 if not os.path.isdir(new):
223 if not os.path.isdir(new):
218 os.makedirs(new, mode=0o777)
224 os.makedirs(new, mode=0o777)
219 readme = os.path.join(new, 'README')
225 readme = os.path.join(new, 'README')
220 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
226 readme_src = os.path.join(get_ipython_package_dir(), u'config', u'profile', 'README')
221 if not os.path.exists(readme) and os.path.exists(readme_src):
227 if not os.path.exists(readme) and os.path.exists(readme_src):
222 shutil.copy(readme_src, readme)
228 shutil.copy(readme_src, readme)
223 for d in ('extensions', 'nbextensions'):
229 for d in ('extensions', 'nbextensions'):
224 path = os.path.join(new, d)
230 path = os.path.join(new, d)
225 if not os.path.exists(path):
231 if not os.path.exists(path):
226 try:
232 try:
227 os.mkdir(path)
233 os.mkdir(path)
228 except OSError as e:
234 except OSError as e:
229 if e.errno != errno.EEXIST:
235 if e.errno != errno.EEXIST:
230 self.log.error("couldn't create path %s: %s", path, e)
236 self.log.error("couldn't create path %s: %s", path, e)
231 self.log.debug("IPYTHONDIR set to: %s" % new)
237 self.log.debug("IPYTHONDIR set to: %s" % new)
232
238
233 def load_config_file(self, suppress_errors=True):
239 def load_config_file(self, suppress_errors=True):
234 """Load the config file.
240 """Load the config file.
235
241
236 By default, errors in loading config are handled, and a warning
242 By default, errors in loading config are handled, and a warning
237 printed on screen. For testing, the suppress_errors option is set
243 printed on screen. For testing, the suppress_errors option is set
238 to False, so errors will make tests fail.
244 to False, so errors will make tests fail.
239 """
245 """
240 self.log.debug("Searching path %s for config files", self.config_file_paths)
246 self.log.debug("Searching path %s for config files", self.config_file_paths)
241 base_config = 'ipython_config.py'
247 base_config = 'ipython_config.py'
242 self.log.debug("Attempting to load config file: %s" %
248 self.log.debug("Attempting to load config file: %s" %
243 base_config)
249 base_config)
244 try:
250 try:
245 Application.load_config_file(
251 Application.load_config_file(
246 self,
252 self,
247 base_config,
253 base_config,
248 path=self.config_file_paths
254 path=self.config_file_paths
249 )
255 )
250 except ConfigFileNotFound:
256 except ConfigFileNotFound:
251 # ignore errors loading parent
257 # ignore errors loading parent
252 self.log.debug("Config file %s not found", base_config)
258 self.log.debug("Config file %s not found", base_config)
253 pass
259 pass
254
260
255 for config_file_name in self.config_files:
261 for config_file_name in self.config_files:
256 if not config_file_name or config_file_name == base_config:
262 if not config_file_name or config_file_name == base_config:
257 continue
263 continue
258 self.log.debug("Attempting to load config file: %s" %
264 self.log.debug("Attempting to load config file: %s" %
259 self.config_file_name)
265 self.config_file_name)
260 try:
266 try:
261 Application.load_config_file(
267 Application.load_config_file(
262 self,
268 self,
263 config_file_name,
269 config_file_name,
264 path=self.config_file_paths
270 path=self.config_file_paths
265 )
271 )
266 except ConfigFileNotFound:
272 except ConfigFileNotFound:
267 # Only warn if the default config file was NOT being used.
273 # Only warn if the default config file was NOT being used.
268 if config_file_name in self.config_file_specified:
274 if config_file_name in self.config_file_specified:
269 msg = self.log.warn
275 msg = self.log.warn
270 else:
276 else:
271 msg = self.log.debug
277 msg = self.log.debug
272 msg("Config file not found, skipping: %s", config_file_name)
278 msg("Config file not found, skipping: %s", config_file_name)
273 except:
279 except:
274 # For testing purposes.
280 # For testing purposes.
275 if not suppress_errors:
281 if not suppress_errors:
276 raise
282 raise
277 self.log.warn("Error loading config file: %s" %
283 self.log.warn("Error loading config file: %s" %
278 self.config_file_name, exc_info=True)
284 self.config_file_name, exc_info=True)
279
285
280 def init_profile_dir(self):
286 def init_profile_dir(self):
281 """initialize the profile dir"""
287 """initialize the profile dir"""
282 self._in_init_profile_dir = True
288 self._in_init_profile_dir = True
283 if self.profile_dir is not None:
289 if self.profile_dir is not None:
284 # already ran
290 # already ran
285 return
291 return
286 if 'ProfileDir.location' not in self.config:
292 if 'ProfileDir.location' not in self.config:
287 # location not specified, find by profile name
293 # location not specified, find by profile name
288 try:
294 try:
289 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
295 p = ProfileDir.find_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
290 except ProfileDirError:
296 except ProfileDirError:
291 # not found, maybe create it (always create default profile)
297 # not found, maybe create it (always create default profile)
292 if self.auto_create or self.profile == 'default':
298 if self.auto_create or self.profile == 'default':
293 try:
299 try:
294 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
300 p = ProfileDir.create_profile_dir_by_name(self.ipython_dir, self.profile, self.config)
295 except ProfileDirError:
301 except ProfileDirError:
296 self.log.fatal("Could not create profile: %r"%self.profile)
302 self.log.fatal("Could not create profile: %r"%self.profile)
297 self.exit(1)
303 self.exit(1)
298 else:
304 else:
299 self.log.info("Created profile dir: %r"%p.location)
305 self.log.info("Created profile dir: %r"%p.location)
300 else:
306 else:
301 self.log.fatal("Profile %r not found."%self.profile)
307 self.log.fatal("Profile %r not found."%self.profile)
302 self.exit(1)
308 self.exit(1)
303 else:
309 else:
304 self.log.info("Using existing profile dir: %r"%p.location)
310 self.log.info("Using existing profile dir: %r"%p.location)
305 else:
311 else:
306 location = self.config.ProfileDir.location
312 location = self.config.ProfileDir.location
307 # location is fully specified
313 # location is fully specified
308 try:
314 try:
309 p = ProfileDir.find_profile_dir(location, self.config)
315 p = ProfileDir.find_profile_dir(location, self.config)
310 except ProfileDirError:
316 except ProfileDirError:
311 # not found, maybe create it
317 # not found, maybe create it
312 if self.auto_create:
318 if self.auto_create:
313 try:
319 try:
314 p = ProfileDir.create_profile_dir(location, self.config)
320 p = ProfileDir.create_profile_dir(location, self.config)
315 except ProfileDirError:
321 except ProfileDirError:
316 self.log.fatal("Could not create profile directory: %r"%location)
322 self.log.fatal("Could not create profile directory: %r"%location)
317 self.exit(1)
323 self.exit(1)
318 else:
324 else:
319 self.log.info("Creating new profile dir: %r"%location)
325 self.log.info("Creating new profile dir: %r"%location)
320 else:
326 else:
321 self.log.fatal("Profile directory %r not found."%location)
327 self.log.fatal("Profile directory %r not found."%location)
322 self.exit(1)
328 self.exit(1)
323 else:
329 else:
324 self.log.info("Using existing profile dir: %r"%location)
330 self.log.info("Using existing profile dir: %r"%location)
325
331
326 self.profile_dir = p
332 self.profile_dir = p
327 self.config_file_paths.append(p.location)
333 self.config_file_paths.append(p.location)
328 self._in_init_profile_dir = False
334 self._in_init_profile_dir = False
329
335
330 def init_config_files(self):
336 def init_config_files(self):
331 """[optionally] copy default config files into profile dir."""
337 """[optionally] copy default config files into profile dir."""
332 # copy config files
338 # copy config files
333 path = self.builtin_profile_dir
339 path = self.builtin_profile_dir
334 if self.copy_config_files:
340 if self.copy_config_files:
335 src = self.profile
341 src = self.profile
336
342
337 cfg = self.config_file_name
343 cfg = self.config_file_name
338 if path and os.path.exists(os.path.join(path, cfg)):
344 if path and os.path.exists(os.path.join(path, cfg)):
339 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
345 self.log.warn("Staging %r from %s into %r [overwrite=%s]"%(
340 cfg, src, self.profile_dir.location, self.overwrite)
346 cfg, src, self.profile_dir.location, self.overwrite)
341 )
347 )
342 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
348 self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite)
343 else:
349 else:
344 self.stage_default_config_file()
350 self.stage_default_config_file()
345 else:
351 else:
346 # Still stage *bundled* config files, but not generated ones
352 # Still stage *bundled* config files, but not generated ones
347 # This is necessary for `ipython profile=sympy` to load the profile
353 # This is necessary for `ipython profile=sympy` to load the profile
348 # on the first go
354 # on the first go
349 files = glob.glob(os.path.join(path, '*.py'))
355 files = glob.glob(os.path.join(path, '*.py'))
350 for fullpath in files:
356 for fullpath in files:
351 cfg = os.path.basename(fullpath)
357 cfg = os.path.basename(fullpath)
352 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
358 if self.profile_dir.copy_config_file(cfg, path=path, overwrite=False):
353 # file was copied
359 # file was copied
354 self.log.warn("Staging bundled %s from %s into %r"%(
360 self.log.warn("Staging bundled %s from %s into %r"%(
355 cfg, self.profile, self.profile_dir.location)
361 cfg, self.profile, self.profile_dir.location)
356 )
362 )
357
363
358
364
359 def stage_default_config_file(self):
365 def stage_default_config_file(self):
360 """auto generate default config file, and stage it into the profile."""
366 """auto generate default config file, and stage it into the profile."""
361 s = self.generate_config_file()
367 s = self.generate_config_file()
362 fname = os.path.join(self.profile_dir.location, self.config_file_name)
368 fname = os.path.join(self.profile_dir.location, self.config_file_name)
363 if self.overwrite or not os.path.exists(fname):
369 if self.overwrite or not os.path.exists(fname):
364 self.log.warn("Generating default config file: %r"%(fname))
370 self.log.warn("Generating default config file: %r"%(fname))
365 with open(fname, 'w') as f:
371 with open(fname, 'w') as f:
366 f.write(s)
372 f.write(s)
367
373
368 @catch_config_error
374 @catch_config_error
369 def initialize(self, argv=None):
375 def initialize(self, argv=None):
370 # don't hook up crash handler before parsing command-line
376 # don't hook up crash handler before parsing command-line
371 self.parse_command_line(argv)
377 self.parse_command_line(argv)
372 self.init_crash_handler()
378 self.init_crash_handler()
373 if self.subapp is not None:
379 if self.subapp is not None:
374 # stop here if subapp is taking over
380 # stop here if subapp is taking over
375 return
381 return
376 cl_config = self.config
382 cl_config = self.config
377 self.init_profile_dir()
383 self.init_profile_dir()
378 self.init_config_files()
384 self.init_config_files()
379 self.load_config_file()
385 self.load_config_file()
380 # enforce cl-opts override configfile opts:
386 # enforce cl-opts override configfile opts:
381 self.update_config(cl_config)
387 self.update_config(cl_config)
382
388
@@ -1,69 +1,71 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Context managers for adding things to sys.path temporarily.
3 Context managers for adding things to sys.path temporarily.
4
4
5 Authors:
5 Authors:
6
6
7 * Brian Granger
7 * Brian Granger
8 """
8 """
9
9
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2011 The IPython Development Team
11 # Copyright (C) 2008-2011 The IPython Development Team
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Imports
18 # Imports
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20
20
21 import sys
21 import sys
22
22
23 from IPython.utils.py3compat import cast_bytes_py2
24
23 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
24 # Code
26 # Code
25 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
26
28
27 class appended_to_syspath(object):
29 class appended_to_syspath(object):
28 """A context for appending a directory to sys.path for a second."""
30 """A context for appending a directory to sys.path for a second."""
29
31
30 def __init__(self, dir):
32 def __init__(self, dir):
31 self.dir = dir
33 self.dir = cast_bytes_py2(dir, sys.getdefaultencoding())
32
34
33 def __enter__(self):
35 def __enter__(self):
34 if self.dir not in sys.path:
36 if self.dir not in sys.path:
35 sys.path.append(self.dir)
37 sys.path.append(self.dir)
36 self.added = True
38 self.added = True
37 else:
39 else:
38 self.added = False
40 self.added = False
39
41
40 def __exit__(self, type, value, traceback):
42 def __exit__(self, type, value, traceback):
41 if self.added:
43 if self.added:
42 try:
44 try:
43 sys.path.remove(self.dir)
45 sys.path.remove(self.dir)
44 except ValueError:
46 except ValueError:
45 pass
47 pass
46 # Returning False causes any exceptions to be re-raised.
48 # Returning False causes any exceptions to be re-raised.
47 return False
49 return False
48
50
49 class prepended_to_syspath(object):
51 class prepended_to_syspath(object):
50 """A context for prepending a directory to sys.path for a second."""
52 """A context for prepending a directory to sys.path for a second."""
51
53
52 def __init__(self, dir):
54 def __init__(self, dir):
53 self.dir = dir
55 self.dir = cast_bytes_py2(dir, sys.getdefaultencoding())
54
56
55 def __enter__(self):
57 def __enter__(self):
56 if self.dir not in sys.path:
58 if self.dir not in sys.path:
57 sys.path.insert(0,self.dir)
59 sys.path.insert(0,self.dir)
58 self.added = True
60 self.added = True
59 else:
61 else:
60 self.added = False
62 self.added = False
61
63
62 def __exit__(self, type, value, traceback):
64 def __exit__(self, type, value, traceback):
63 if self.added:
65 if self.added:
64 try:
66 try:
65 sys.path.remove(self.dir)
67 sys.path.remove(self.dir)
66 except ValueError:
68 except ValueError:
67 pass
69 pass
68 # Returning False causes any exceptions to be re-raised.
70 # Returning False causes any exceptions to be re-raised.
69 return False
71 return False
General Comments 0
You need to be logged in to leave comments. Login now