Show More
@@ -19,10 +19,11 b' Authors:' | |||
|
19 | 19 | # Imports |
|
20 | 20 | #----------------------------------------------------------------------------- |
|
21 | 21 | |
|
22 | from copy import deepcopy | |
|
23 | 22 | import logging |
|
23 | import os | |
|
24 | 24 | import re |
|
25 | 25 | import sys |
|
26 | from copy import deepcopy | |
|
26 | 27 | |
|
27 | 28 | from IPython.config.configurable import SingletonConfigurable |
|
28 | 29 | from IPython.config.loader import ( |
@@ -98,9 +99,13 b' class Application(SingletonConfigurable):' | |||
|
98 | 99 | version = Unicode(u'0.0') |
|
99 | 100 | |
|
100 | 101 | # The log level for the application |
|
101 | log_level = Enum((0,10,20,30,40,50), default_value=logging.WARN, | |
|
102 | log_level = Enum((0,10,20,30,40,50,'DEBUG','INFO','WARN','ERROR','CRITICAL'), | |
|
103 | default_value=logging.WARN, | |
|
102 | 104 |
|
|
103 |
|
|
|
105 | help="Set the log level by value or name.") | |
|
106 | def _log_level_changed(self, name, old, new): | |
|
107 | if isinstance(new, basestring): | |
|
108 | self.log_level = getattr(logging, new) | |
|
104 | 109 | |
|
105 | 110 | # the alias map for configurables |
|
106 | 111 | aliases = Dict(dict(log_level='Application.log_level')) |
@@ -337,6 +342,16 b' class Application(SingletonConfigurable):' | |||
|
337 | 342 | config = loader.load_config() |
|
338 | 343 | self.update_config(config) |
|
339 | 344 | |
|
345 | def generate_config_file(self): | |
|
346 | """generate default config file from Configurables""" | |
|
347 | lines = ["# Configuration file for %s."%self.name] | |
|
348 | lines.append('') | |
|
349 | lines.append('c = get_config()') | |
|
350 | lines.append('') | |
|
351 | for cls in self.classes: | |
|
352 | lines.append(cls.class_config_section()) | |
|
353 | return '\n'.join(lines) | |
|
354 | ||
|
340 | 355 | def exit(self, exit_status=0): |
|
341 | 356 | self.log.debug("Exiting application: %s" % self.name) |
|
342 | 357 | sys.exit(exit_status) |
@@ -180,6 +180,38 b' class Configurable(HasTraits):' | |||
|
180 | 180 | """Get the help string for a single trait and print it.""" |
|
181 | 181 | print cls.class_get_help() |
|
182 | 182 | |
|
183 | @classmethod | |
|
184 | def class_config_section(cls): | |
|
185 | """Get the config class config section""" | |
|
186 | def c(s): | |
|
187 | """return a commented, wrapped block.""" | |
|
188 | s = '\n\n'.join(wrap_paragraphs(s, 78)) | |
|
189 | ||
|
190 | return '# ' + s.replace('\n', '\n# ') | |
|
191 | ||
|
192 | # section header | |
|
193 | breaker = '#' + '-'*78 | |
|
194 | s = "# %s configuration"%cls.__name__ | |
|
195 | lines = [breaker, s, breaker, ''] | |
|
196 | # get the description trait | |
|
197 | desc = cls.class_traits().get('description') | |
|
198 | if desc: | |
|
199 | desc = desc.default_value | |
|
200 | else: | |
|
201 | # no description trait, use __doc__ | |
|
202 | desc = getattr(cls, '__doc__', '') | |
|
203 | if desc: | |
|
204 | lines.append(c(desc)) | |
|
205 | lines.append('') | |
|
206 | ||
|
207 | for name,trait in cls.class_traits(config=True).iteritems(): | |
|
208 | help = trait.get_metadata('help') or '' | |
|
209 | lines.append(c(help)) | |
|
210 | lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value())) | |
|
211 | lines.append('') | |
|
212 | return '\n'.join(lines) | |
|
213 | ||
|
214 | ||
|
183 | 215 | |
|
184 | 216 | class SingletonConfigurable(Configurable): |
|
185 | 217 | """A configurable that only allows one instance. |
@@ -82,6 +82,8 b' class BaseIPythonApplication(Application):' | |||
|
82 | 82 | config_file_specified = Bool(False) |
|
83 | 83 | |
|
84 | 84 | config_file_name = Unicode(u'ipython_config.py') |
|
85 | def _config_file_name_default(self): | |
|
86 | return self.name.replace('-','_') + u'_config.py' | |
|
85 | 87 | def _config_file_name_changed(self, name, old, new): |
|
86 | 88 | if new != old: |
|
87 | 89 | self.config_file_specified = True |
@@ -103,7 +105,6 b' class BaseIPythonApplication(Application):' | |||
|
103 | 105 | get_ipython_package_dir(), u'config', u'profile', new |
|
104 | 106 | ) |
|
105 | 107 |
|
|
106 | ||
|
107 | 108 | ipython_dir = Unicode(get_ipython_dir(), config=True, |
|
108 | 109 | help=""" |
|
109 | 110 | The name of the IPython directory. This directory is used for logging |
@@ -123,7 +124,11 b' class BaseIPythonApplication(Application):' | |||
|
123 | 124 | return [u'ipython_config.py'] |
|
124 | 125 | |
|
125 | 126 | copy_config_files = Bool(False, config=True, |
|
126 |
help="""Whether to |
|
|
127 | help="""Whether to install the default config files into the profile dir. | |
|
128 | If a new profile is being created, and IPython contains config files for that | |
|
129 | profile, then they will be staged into the new directory. Otherwise, | |
|
130 | default config files will be automatically generated. | |
|
131 | """) | |
|
127 | 132 | |
|
128 | 133 | # The class to use as the crash handler. |
|
129 | 134 | crash_handler_class = Type(crashhandler.CrashHandler) |
@@ -162,6 +167,21 b' class BaseIPythonApplication(Application):' | |||
|
162 | 167 | printed on screen. For testing, the suppress_errors option is set |
|
163 | 168 | to False, so errors will make tests fail. |
|
164 | 169 | """ |
|
170 | base_config = 'ipython_config.py' | |
|
171 | self.log.debug("Attempting to load config file: %s" % | |
|
172 | base_config) | |
|
173 | try: | |
|
174 | Application.load_config_file( | |
|
175 | self, | |
|
176 | base_config, | |
|
177 | path=self.config_file_paths | |
|
178 | ) | |
|
179 | except IOError: | |
|
180 | # ignore errors loading parent | |
|
181 | pass | |
|
182 | if self.config_file_name == base_config: | |
|
183 | # don't load secondary config | |
|
184 | return | |
|
165 | 185 | self.log.debug("Attempting to load config file: %s" % |
|
166 | 186 | self.config_file_name) |
|
167 | 187 | try: |
@@ -235,21 +255,32 b' class BaseIPythonApplication(Application):' | |||
|
235 | 255 | if self.copy_config_files: |
|
236 | 256 | path = self.builtin_profile_dir |
|
237 | 257 | src = self.profile |
|
238 | if not os.path.exists(path): | |
|
239 | # use default if new profile doesn't have a preset | |
|
240 | path = None | |
|
241 | src = 'default' | |
|
242 | 258 | |
|
243 | self.log.debug("Staging %s config files into %r [overwrite=%s]"%( | |
|
244 | src, self.profile_dir.location, self.overwrite) | |
|
259 | cfg = self.config_file_name | |
|
260 | if path and os.path.exists(os.path.join(path, cfg)): | |
|
261 | self.log.warn("Staging %r from %s into %r [overwrite=%s]"%( | |
|
262 | cfg, src, self.profile_dir.location, self.overwrite) | |
|
245 | 263 | ) |
|
246 | ||
|
247 | for cfg in self.config_files: | |
|
248 | 264 | self.profile_dir.copy_config_file(cfg, path=path, overwrite=self.overwrite) |
|
265 | else: | |
|
266 | self.stage_default_config_file() | |
|
267 | ||
|
268 | def stage_default_config_file(self): | |
|
269 | """auto generate default config file, and stage it into the profile.""" | |
|
270 | s = self.generate_config_file() | |
|
271 | fname = os.path.join(self.profile_dir.location, self.config_file_name) | |
|
272 | if self.overwrite or not os.path.exists(fname): | |
|
273 | self.log.warn("Generating default config file: %r"%(fname)) | |
|
274 | with open(fname, 'w') as f: | |
|
275 | f.write(s) | |
|
276 | ||
|
249 | 277 | |
|
250 | 278 | def initialize(self, argv=None): |
|
251 | 279 | self.init_crash_handler() |
|
252 | 280 | self.parse_command_line(argv) |
|
281 | if self.subapp is not None: | |
|
282 | # stop here if subapp is taking over | |
|
283 | return | |
|
253 | 284 | cl_config = self.config |
|
254 | 285 | self.init_profile_dir() |
|
255 | 286 | self.init_config_files() |
@@ -163,6 +163,42 b' class ProfileCreate(BaseIPythonApplication):' | |||
|
163 | 163 | |
|
164 | 164 | classes = [ProfileDir] |
|
165 | 165 | |
|
166 | def init_config_files(self): | |
|
167 | super(ProfileCreate, self).init_config_files() | |
|
168 | # use local imports, since these classes may import from here | |
|
169 | from IPython.frontend.terminal.ipapp import TerminalIPythonApp | |
|
170 | apps = [TerminalIPythonApp] | |
|
171 | try: | |
|
172 | from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp | |
|
173 | except ImportError: | |
|
174 | pass | |
|
175 | else: | |
|
176 | apps.append(IPythonQtConsoleApp) | |
|
177 | if self.cluster: | |
|
178 | from IPython.parallel.apps.ipcontrollerapp import IPControllerApp | |
|
179 | from IPython.parallel.apps.ipengineapp import IPEngineApp | |
|
180 | from IPython.parallel.apps.ipclusterapp import IPClusterStart | |
|
181 | from IPython.parallel.apps.iploggerapp import IPLoggerApp | |
|
182 | apps.extend([ | |
|
183 | IPControllerApp, | |
|
184 | IPEngineApp, | |
|
185 | IPClusterStart, | |
|
186 | IPLoggerApp, | |
|
187 | ]) | |
|
188 | for App in apps: | |
|
189 | app = App() | |
|
190 | app.config.update(self.config) | |
|
191 | app.log = self.log | |
|
192 | app.overwrite = self.overwrite | |
|
193 | app.copy_config_files=True | |
|
194 | app.profile = self.profile | |
|
195 | app.init_profile_dir() | |
|
196 | app.init_config_files() | |
|
197 | print 'tic' | |
|
198 | ||
|
199 | def stage_default_config_file(self): | |
|
200 | pass | |
|
201 | ||
|
166 | 202 | class ProfileApp(Application): |
|
167 | 203 | name = u'ipython-profile' |
|
168 | 204 | description = profile_help |
@@ -208,9 +208,8 b' class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):' | |||
|
208 | 208 | "Create and manage IPython profiles.") |
|
209 | 209 | )) |
|
210 | 210 | |
|
211 | # *do* autocreate requested profile | |
|
211 | # *do* autocreate requested profile, but don't create the config file. | |
|
212 | 212 | auto_create=Bool(True) |
|
213 | copy_config_files=Bool(True) | |
|
214 | 213 | # configurables |
|
215 | 214 | ignore_old_config=Bool(False, config=True, |
|
216 | 215 | help="Suppress warning messages about legacy config files" |
@@ -322,7 +322,7 b' class IPClusterStart(IPClusterEngines):' | |||
|
322 | 322 | classes = List() |
|
323 | 323 | def _classes_default(self,): |
|
324 | 324 | from IPython.parallel.apps import launcher |
|
325 | return [ProfileDir]+launcher.all_launchers | |
|
325 | return [ProfileDir] + [IPClusterEngines] + launcher.all_launchers | |
|
326 | 326 | |
|
327 | 327 | clean_logs = Bool(True, config=True, |
|
328 | 328 | help="whether to cleanup old logs before starting") |
@@ -410,12 +410,11 b' class IPClusterStart(IPClusterEngines):' | |||
|
410 | 410 | |
|
411 | 411 | base='IPython.parallel.apps.ipclusterapp.IPCluster' |
|
412 | 412 | |
|
413 |
class IP |
|
|
413 | class IPClusterApp(Application): | |
|
414 | 414 | name = u'ipcluster' |
|
415 | 415 | description = _description |
|
416 | 416 | |
|
417 | subcommands = {'create' : (base+'Create', create_help), | |
|
418 | 'list' : (base+'List', list_help), | |
|
417 | subcommands = { | |
|
419 | 418 | 'start' : (base+'Start', start_help), |
|
420 | 419 | 'stop' : (base+'Stop', stop_help), |
|
421 | 420 | 'engines' : (base+'Engines', engines_help), |
@@ -103,7 +103,7 b' class MPI(Configurable):' | |||
|
103 | 103 | |
|
104 | 104 | class IPEngineApp(BaseParallelApplication): |
|
105 | 105 | |
|
106 |
|
|
|
106 | name = Unicode(u'ipengine') | |
|
107 | 107 | description = Unicode(_description) |
|
108 | 108 | config_file_name = Unicode(default_config_file_name) |
|
109 | 109 | classes = List([ProfileDir, Session, EngineFactory, Kernel, MPI]) |
@@ -61,7 +61,7 b" aliases.update(dict(url='LogWatcher.url', topics='LogWatcher.topics'))" | |||
|
61 | 61 | |
|
62 | 62 | class IPLoggerApp(BaseParallelApplication): |
|
63 | 63 | |
|
64 |
name = u'iplogger |
|
|
64 | name = u'iplogger' | |
|
65 | 65 | description = _description |
|
66 | 66 | config_file_name = Unicode(default_config_file_name) |
|
67 | 67 |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now