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