##// END OF EJS Templates
remove all trailling spaces
Bernardo B. Marques -
r4872:34c10438
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -109,10 +109,10 class Application(SingletonConfigurable):
109 new = getattr(logging, new)
109 new = getattr(logging, new)
110 self.log_level = new
110 self.log_level = new
111 self.log.setLevel(new)
111 self.log.setLevel(new)
112
112
113 # the alias map for configurables
113 # the alias map for configurables
114 aliases = Dict({'log-level' : 'Application.log_level'})
114 aliases = Dict({'log-level' : 'Application.log_level'})
115
115
116 # flags for loading Configurables or store_const style flags
116 # flags for loading Configurables or store_const style flags
117 # flags are loaded from this dict by '--key' flags
117 # flags are loaded from this dict by '--key' flags
118 # this must be a dict of two-tuples, the first element being the Config/dict
118 # this must be a dict of two-tuples, the first element being the Config/dict
@@ -124,20 +124,20 class Application(SingletonConfigurable):
124 assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
124 assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
125 assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
125 assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
126 assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value)
126 assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value)
127
127
128
128
129 # subcommands for launching other applications
129 # subcommands for launching other applications
130 # if this is not empty, this will be a parent Application
130 # if this is not empty, this will be a parent Application
131 # this must be a dict of two-tuples,
131 # this must be a dict of two-tuples,
132 # the first element being the application class/import string
132 # the first element being the application class/import string
133 # and the second being the help string for the subcommand
133 # and the second being the help string for the subcommand
134 subcommands = Dict()
134 subcommands = Dict()
135 # parse_command_line will initialize a subapp, if requested
135 # parse_command_line will initialize a subapp, if requested
136 subapp = Instance('IPython.config.application.Application', allow_none=True)
136 subapp = Instance('IPython.config.application.Application', allow_none=True)
137
137
138 # extra command-line arguments that don't set config values
138 # extra command-line arguments that don't set config values
139 extra_args = List(Unicode)
139 extra_args = List(Unicode)
140
140
141
141
142 def __init__(self, **kwargs):
142 def __init__(self, **kwargs):
143 SingletonConfigurable.__init__(self, **kwargs)
143 SingletonConfigurable.__init__(self, **kwargs)
@@ -145,7 +145,7 class Application(SingletonConfigurable):
145 # options and config files.
145 # options and config files.
146 if self.__class__ not in self.classes:
146 if self.__class__ not in self.classes:
147 self.classes.insert(0, self.__class__)
147 self.classes.insert(0, self.__class__)
148
148
149 self.init_logging()
149 self.init_logging()
150
150
151 def _config_changed(self, name, old, new):
151 def _config_changed(self, name, old, new):
@@ -157,7 +157,7 class Application(SingletonConfigurable):
157 """Start logging for this application.
157 """Start logging for this application.
158
158
159 The default is to log to stdout using a StreaHandler. The log level
159 The default is to log to stdout using a StreaHandler. The log level
160 starts at loggin.WARN, but this can be adjusted by setting the
160 starts at loggin.WARN, but this can be adjusted by setting the
161 ``log_level`` attribute.
161 ``log_level`` attribute.
162 """
162 """
163 self.log = logging.getLogger(self.__class__.__name__)
163 self.log = logging.getLogger(self.__class__.__name__)
@@ -174,36 +174,36 class Application(SingletonConfigurable):
174
174
175 def initialize(self, argv=None):
175 def initialize(self, argv=None):
176 """Do the basic steps to configure me.
176 """Do the basic steps to configure me.
177
177
178 Override in subclasses.
178 Override in subclasses.
179 """
179 """
180 self.parse_command_line(argv)
180 self.parse_command_line(argv)
181
181
182
182
183 def start(self):
183 def start(self):
184 """Start the app mainloop.
184 """Start the app mainloop.
185
185
186 Override in subclasses.
186 Override in subclasses.
187 """
187 """
188 if self.subapp is not None:
188 if self.subapp is not None:
189 return self.subapp.start()
189 return self.subapp.start()
190
190
191 def print_alias_help(self):
191 def print_alias_help(self):
192 """Print the alias part of the help."""
192 """Print the alias part of the help."""
193 if not self.aliases:
193 if not self.aliases:
194 return
194 return
195
195
196 lines = []
196 lines = []
197 classdict = {}
197 classdict = {}
198 for cls in self.classes:
198 for cls in self.classes:
199 # include all parents (up to, but excluding Configurable) in available names
199 # include all parents (up to, but excluding Configurable) in available names
200 for c in cls.mro()[:-3]:
200 for c in cls.mro()[:-3]:
201 classdict[c.__name__] = c
201 classdict[c.__name__] = c
202
202
203 for alias, longname in self.aliases.iteritems():
203 for alias, longname in self.aliases.iteritems():
204 classname, traitname = longname.split('.',1)
204 classname, traitname = longname.split('.',1)
205 cls = classdict[classname]
205 cls = classdict[classname]
206
206
207 trait = cls.class_traits(config=True)[traitname]
207 trait = cls.class_traits(config=True)[traitname]
208 help = cls.class_get_trait_help(trait).splitlines()
208 help = cls.class_get_trait_help(trait).splitlines()
209 # reformat first line
209 # reformat first line
@@ -213,12 +213,12 class Application(SingletonConfigurable):
213 lines.extend(help)
213 lines.extend(help)
214 # lines.append('')
214 # lines.append('')
215 print os.linesep.join(lines)
215 print os.linesep.join(lines)
216
216
217 def print_flag_help(self):
217 def print_flag_help(self):
218 """Print the flag part of the help."""
218 """Print the flag part of the help."""
219 if not self.flags:
219 if not self.flags:
220 return
220 return
221
221
222 lines = []
222 lines = []
223 for m, (cfg,help) in self.flags.iteritems():
223 for m, (cfg,help) in self.flags.iteritems():
224 prefix = '--' if len(m) > 1 else '-'
224 prefix = '--' if len(m) > 1 else '-'
@@ -226,7 +226,7 class Application(SingletonConfigurable):
226 lines.append(indent(dedent(help.strip())))
226 lines.append(indent(dedent(help.strip())))
227 # lines.append('')
227 # lines.append('')
228 print os.linesep.join(lines)
228 print os.linesep.join(lines)
229
229
230 def print_options(self):
230 def print_options(self):
231 if not self.flags and not self.aliases:
231 if not self.flags and not self.aliases:
232 return
232 return
@@ -240,12 +240,12 class Application(SingletonConfigurable):
240 self.print_flag_help()
240 self.print_flag_help()
241 self.print_alias_help()
241 self.print_alias_help()
242 print
242 print
243
243
244 def print_subcommands(self):
244 def print_subcommands(self):
245 """Print the subcommand part of the help."""
245 """Print the subcommand part of the help."""
246 if not self.subcommands:
246 if not self.subcommands:
247 return
247 return
248
248
249 lines = ["Subcommands"]
249 lines = ["Subcommands"]
250 lines.append('-'*len(lines[0]))
250 lines.append('-'*len(lines[0]))
251 lines.append('')
251 lines.append('')
@@ -258,15 +258,15 class Application(SingletonConfigurable):
258 lines.append(indent(dedent(help.strip())))
258 lines.append(indent(dedent(help.strip())))
259 lines.append('')
259 lines.append('')
260 print os.linesep.join(lines)
260 print os.linesep.join(lines)
261
261
262 def print_help(self, classes=False):
262 def print_help(self, classes=False):
263 """Print the help for each Configurable class in self.classes.
263 """Print the help for each Configurable class in self.classes.
264
264
265 If classes=False (the default), only flags and aliases are printed.
265 If classes=False (the default), only flags and aliases are printed.
266 """
266 """
267 self.print_subcommands()
267 self.print_subcommands()
268 self.print_options()
268 self.print_options()
269
269
270 if classes:
270 if classes:
271 if self.classes:
271 if self.classes:
272 print "Class parameters"
272 print "Class parameters"
@@ -275,7 +275,7 class Application(SingletonConfigurable):
275 for p in wrap_paragraphs(self.keyvalue_description):
275 for p in wrap_paragraphs(self.keyvalue_description):
276 print p
276 print p
277 print
277 print
278
278
279 for cls in self.classes:
279 for cls in self.classes:
280 cls.class_print_help()
280 cls.class_print_help()
281 print
281 print
@@ -315,21 +315,21 class Application(SingletonConfigurable):
315 # Save the combined config as self.config, which triggers the traits
315 # Save the combined config as self.config, which triggers the traits
316 # events.
316 # events.
317 self.config = newconfig
317 self.config = newconfig
318
318
319 def initialize_subcommand(self, subc, argv=None):
319 def initialize_subcommand(self, subc, argv=None):
320 """Initialize a subcommand with argv."""
320 """Initialize a subcommand with argv."""
321 subapp,help = self.subcommands.get(subc)
321 subapp,help = self.subcommands.get(subc)
322
322
323 if isinstance(subapp, basestring):
323 if isinstance(subapp, basestring):
324 subapp = import_item(subapp)
324 subapp = import_item(subapp)
325
325
326 # clear existing instances
326 # clear existing instances
327 self.__class__.clear_instance()
327 self.__class__.clear_instance()
328 # instantiate
328 # instantiate
329 self.subapp = subapp.instance()
329 self.subapp = subapp.instance()
330 # and initialize subapp
330 # and initialize subapp
331 self.subapp.initialize(argv)
331 self.subapp.initialize(argv)
332
332
333 def parse_command_line(self, argv=None):
333 def parse_command_line(self, argv=None):
334 """Parse the command line arguments."""
334 """Parse the command line arguments."""
335 argv = sys.argv[1:] if argv is None else argv
335 argv = sys.argv[1:] if argv is None else argv
@@ -340,7 +340,7 class Application(SingletonConfigurable):
340 if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
340 if re.match(r'^\w(\-?\w)*$', subc) and subc in self.subcommands:
341 # it's a subcommand, and *not* a flag or class parameter
341 # it's a subcommand, and *not* a flag or class parameter
342 return self.initialize_subcommand(subc, subargv)
342 return self.initialize_subcommand(subc, subargv)
343
343
344 if '-h' in argv or '--help' in argv or '--help-all' in argv:
344 if '-h' in argv or '--help' in argv or '--help-all' in argv:
345 self.print_description()
345 self.print_description()
346 self.print_help('--help-all' in argv)
346 self.print_help('--help-all' in argv)
@@ -350,7 +350,7 class Application(SingletonConfigurable):
350 if '--version' in argv:
350 if '--version' in argv:
351 self.print_version()
351 self.print_version()
352 self.exit(0)
352 self.exit(0)
353
353
354 loader = KVArgParseConfigLoader(argv=argv, aliases=self.aliases,
354 loader = KVArgParseConfigLoader(argv=argv, aliases=self.aliases,
355 flags=self.flags)
355 flags=self.flags)
356 try:
356 try:
@@ -383,7 +383,7 class Application(SingletonConfigurable):
383 else:
383 else:
384 self.log.debug("Loaded config file: %s", loader.full_filename)
384 self.log.debug("Loaded config file: %s", loader.full_filename)
385 self.update_config(config)
385 self.update_config(config)
386
386
387 def generate_config_file(self):
387 def generate_config_file(self):
388 """generate default config file from Configurables"""
388 """generate default config file from Configurables"""
389 lines = ["# Configuration file for %s."%self.name]
389 lines = ["# Configuration file for %s."%self.name]
@@ -404,10 +404,10 class Application(SingletonConfigurable):
404
404
405 def boolean_flag(name, configurable, set_help='', unset_help=''):
405 def boolean_flag(name, configurable, set_help='', unset_help=''):
406 """Helper for building basic --trait, --no-trait flags.
406 """Helper for building basic --trait, --no-trait flags.
407
407
408 Parameters
408 Parameters
409 ----------
409 ----------
410
410
411 name : str
411 name : str
412 The name of the flag.
412 The name of the flag.
413 configurable : str
413 configurable : str
@@ -416,10 +416,10 def boolean_flag(name, configurable, set_help='', unset_help=''):
416 help string for --name flag
416 help string for --name flag
417 unset_help : unicode
417 unset_help : unicode
418 help string for --no-name flag
418 help string for --no-name flag
419
419
420 Returns
420 Returns
421 -------
421 -------
422
422
423 cfg : dict
423 cfg : dict
424 A dict with two keys: 'name', and 'no-name', for setting and unsetting
424 A dict with two keys: 'name', and 'no-name', for setting and unsetting
425 the trait, respectively.
425 the trait, respectively.
@@ -427,9 +427,9 def boolean_flag(name, configurable, set_help='', unset_help=''):
427 # default helpstrings
427 # default helpstrings
428 set_help = set_help or "set %s=True"%configurable
428 set_help = set_help or "set %s=True"%configurable
429 unset_help = unset_help or "set %s=False"%configurable
429 unset_help = unset_help or "set %s=False"%configurable
430
430
431 cls,trait = configurable.split('.')
431 cls,trait = configurable.split('.')
432
432
433 setter = {cls : {trait : True}}
433 setter = {cls : {trait : True}}
434 unsetter = {cls : {trait : False}}
434 unsetter = {cls : {trait : False}}
435 return {name : (setter, set_help), 'no-'+name : (unsetter, unset_help)}
435 return {name : (setter, set_help), 'no-'+name : (unsetter, unset_help)}
@@ -55,16 +55,16 class Configurable(HasTraits):
55 Parameters
55 Parameters
56 ----------
56 ----------
57 config : Config
57 config : Config
58 If this is empty, default values are used. If config is a
58 If this is empty, default values are used. If config is a
59 :class:`Config` instance, it will be used to configure the
59 :class:`Config` instance, it will be used to configure the
60 instance.
60 instance.
61
61
62 Notes
62 Notes
63 -----
63 -----
64 Subclasses of Configurable must call the :meth:`__init__` method of
64 Subclasses of Configurable must call the :meth:`__init__` method of
65 :class:`Configurable` *before* doing anything else and using
65 :class:`Configurable` *before* doing anything else and using
66 :func:`super`::
66 :func:`super`::
67
67
68 class MyConfigurable(Configurable):
68 class MyConfigurable(Configurable):
69 def __init__(self, config=None):
69 def __init__(self, config=None):
70 super(MyConfigurable, self).__init__(config)
70 super(MyConfigurable, self).__init__(config)
@@ -82,7 +82,7 class Configurable(HasTraits):
82 # making that a class attribute.
82 # making that a class attribute.
83 # self.config = deepcopy(config)
83 # self.config = deepcopy(config)
84 self.config = config
84 self.config = config
85 # This should go second so individual keyword arguments override
85 # This should go second so individual keyword arguments override
86 # the values in config.
86 # the values in config.
87 super(Configurable, self).__init__(**kwargs)
87 super(Configurable, self).__init__(**kwargs)
88 self.created = datetime.datetime.now()
88 self.created = datetime.datetime.now()
@@ -105,11 +105,11 class Configurable(HasTraits):
105 # classes that are Configurable subclasses. This starts with Configurable
105 # classes that are Configurable subclasses. This starts with Configurable
106 # and works down the mro loading the config for each section.
106 # and works down the mro loading the config for each section.
107 section_names = [cls.__name__ for cls in \
107 section_names = [cls.__name__ for cls in \
108 reversed(self.__class__.__mro__) if
108 reversed(self.__class__.__mro__) if
109 issubclass(cls, Configurable) and issubclass(self.__class__, cls)]
109 issubclass(cls, Configurable) and issubclass(self.__class__, cls)]
110
110
111 for sname in section_names:
111 for sname in section_names:
112 # Don't do a blind getattr as that would cause the config to
112 # Don't do a blind getattr as that would cause the config to
113 # dynamically create the section with name self.__class__.__name__.
113 # dynamically create the section with name self.__class__.__name__.
114 if new._has_section(sname):
114 if new._has_section(sname):
115 my_config = new[sname]
115 my_config = new[sname]
@@ -149,7 +149,7 class Configurable(HasTraits):
149 help = cls.class_get_trait_help(v)
149 help = cls.class_get_trait_help(v)
150 final_help.append(help)
150 final_help.append(help)
151 return '\n'.join(final_help)
151 return '\n'.join(final_help)
152
152
153 @classmethod
153 @classmethod
154 def class_get_trait_help(cls, trait):
154 def class_get_trait_help(cls, trait):
155 """Get the help string for a single trait."""
155 """Get the help string for a single trait."""
@@ -167,7 +167,7 class Configurable(HasTraits):
167 if 'Enum' in trait.__class__.__name__:
167 if 'Enum' in trait.__class__.__name__:
168 # include Enum choices
168 # include Enum choices
169 lines.append(indent('Choices: %r'%(trait.values,)))
169 lines.append(indent('Choices: %r'%(trait.values,)))
170
170
171 help = trait.get_metadata('help')
171 help = trait.get_metadata('help')
172 if help is not None:
172 if help is not None:
173 help = '\n'.join(wrap_paragraphs(help, 76))
173 help = '\n'.join(wrap_paragraphs(help, 76))
@@ -185,9 +185,9 class Configurable(HasTraits):
185 def c(s):
185 def c(s):
186 """return a commented, wrapped block."""
186 """return a commented, wrapped block."""
187 s = '\n\n'.join(wrap_paragraphs(s, 78))
187 s = '\n\n'.join(wrap_paragraphs(s, 78))
188
188
189 return '# ' + s.replace('\n', '\n# ')
189 return '# ' + s.replace('\n', '\n# ')
190
190
191 # section header
191 # section header
192 breaker = '#' + '-'*78
192 breaker = '#' + '-'*78
193 s = "# %s configuration"%cls.__name__
193 s = "# %s configuration"%cls.__name__
@@ -202,7 +202,7 class Configurable(HasTraits):
202 if desc:
202 if desc:
203 lines.append(c(desc))
203 lines.append(c(desc))
204 lines.append('')
204 lines.append('')
205
205
206 parents = []
206 parents = []
207 for parent in cls.mro():
207 for parent in cls.mro():
208 # only include parents that are not base classes
208 # only include parents that are not base classes
@@ -211,20 +211,20 class Configurable(HasTraits):
211 if parent is not cls and issubclass(parent, Configurable) and \
211 if parent is not cls and issubclass(parent, Configurable) and \
212 parent.class_traits(config=True):
212 parent.class_traits(config=True):
213 parents.append(parent)
213 parents.append(parent)
214
214
215 if parents:
215 if parents:
216 pstr = ', '.join([ p.__name__ for p in parents ])
216 pstr = ', '.join([ p.__name__ for p in parents ])
217 lines.append(c('%s will inherit config from: %s'%(cls.__name__, pstr)))
217 lines.append(c('%s will inherit config from: %s'%(cls.__name__, pstr)))
218 lines.append('')
218 lines.append('')
219
219
220 for name,trait in cls.class_traits(config=True).iteritems():
220 for name,trait in cls.class_traits(config=True).iteritems():
221 help = trait.get_metadata('help') or ''
221 help = trait.get_metadata('help') or ''
222 lines.append(c(help))
222 lines.append(c(help))
223 lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value()))
223 lines.append('# c.%s.%s = %r'%(cls.__name__, name, trait.get_default_value()))
224 lines.append('')
224 lines.append('')
225 return '\n'.join(lines)
225 return '\n'.join(lines)
226
226
227
227
228
228
229 class SingletonConfigurable(Configurable):
229 class SingletonConfigurable(Configurable):
230 """A configurable that only allows one instance.
230 """A configurable that only allows one instance.
@@ -235,20 +235,20 class SingletonConfigurable(Configurable):
235 """
235 """
236
236
237 _instance = None
237 _instance = None
238
238
239 @classmethod
239 @classmethod
240 def _walk_mro(cls):
240 def _walk_mro(cls):
241 """Walk the cls.mro() for parent classes that are also singletons
241 """Walk the cls.mro() for parent classes that are also singletons
242
242
243 For use in instance()
243 For use in instance()
244 """
244 """
245
245
246 for subclass in cls.mro():
246 for subclass in cls.mro():
247 if issubclass(cls, subclass) and \
247 if issubclass(cls, subclass) and \
248 issubclass(subclass, SingletonConfigurable) and \
248 issubclass(subclass, SingletonConfigurable) and \
249 subclass != SingletonConfigurable:
249 subclass != SingletonConfigurable:
250 yield subclass
250 yield subclass
251
251
252 @classmethod
252 @classmethod
253 def clear_instance(cls):
253 def clear_instance(cls):
254 """unset _instance for this class and singleton parents.
254 """unset _instance for this class and singleton parents.
@@ -260,7 +260,7 class SingletonConfigurable(Configurable):
260 # only clear instances that are instances
260 # only clear instances that are instances
261 # of the calling class
261 # of the calling class
262 subclass._instance = None
262 subclass._instance = None
263
263
264 @classmethod
264 @classmethod
265 def instance(cls, *args, **kwargs):
265 def instance(cls, *args, **kwargs):
266 """Returns a global instance of this class.
266 """Returns a global instance of this class.
@@ -297,7 +297,7 class SingletonConfigurable(Configurable):
297 # parent classes' _instance attribute.
297 # parent classes' _instance attribute.
298 for subclass in cls._walk_mro():
298 for subclass in cls._walk_mro():
299 subclass._instance = inst
299 subclass._instance = inst
300
300
301 if isinstance(cls._instance, cls):
301 if isinstance(cls._instance, cls):
302 return cls._instance
302 return cls._instance
303 else:
303 else:
@@ -314,15 +314,15 class SingletonConfigurable(Configurable):
314
314
315 class LoggingConfigurable(Configurable):
315 class LoggingConfigurable(Configurable):
316 """A parent class for Configurables that log.
316 """A parent class for Configurables that log.
317
317
318 Subclasses have a log trait, and the default behavior
318 Subclasses have a log trait, and the default behavior
319 is to get the logger from the currently running Application
319 is to get the logger from the currently running Application
320 via Application.instance().log.
320 via Application.instance().log.
321 """
321 """
322
322
323 log = Instance('logging.Logger')
323 log = Instance('logging.Logger')
324 def _log_default(self):
324 def _log_default(self):
325 from IPython.config.application import Application
325 from IPython.config.application import Application
326 return Application.instance().log
326 return Application.instance().log
327
327
328
328
@@ -53,14 +53,14 class ArgumentError(ConfigLoaderError):
53
53
54 class ArgumentParser(argparse.ArgumentParser):
54 class ArgumentParser(argparse.ArgumentParser):
55 """Simple argparse subclass that prints help to stdout by default."""
55 """Simple argparse subclass that prints help to stdout by default."""
56
56
57 def print_help(self, file=None):
57 def print_help(self, file=None):
58 if file is None:
58 if file is None:
59 file = sys.stdout
59 file = sys.stdout
60 return super(ArgumentParser, self).print_help(file)
60 return super(ArgumentParser, self).print_help(file)
61
61
62 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
62 print_help.__doc__ = argparse.ArgumentParser.print_help.__doc__
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 # Config class for holding config information
65 # Config class for holding config information
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
@@ -125,10 +125,10 class Config(dict):
125 # infinite recursion on top of PyPy. Instead, we manually fish the
125 # infinite recursion on top of PyPy. Instead, we manually fish the
126 # bound method.
126 # bound method.
127 is_section_key = self.__class__._is_section_key.__get__(self)
127 is_section_key = self.__class__._is_section_key.__get__(self)
128
128
129 # Because we use this for an exec namespace, we need to delegate
129 # Because we use this for an exec namespace, we need to delegate
130 # the lookup of names in __builtin__ to itself. This means
130 # the lookup of names in __builtin__ to itself. This means
131 # that you can't have section or attribute names that are
131 # that you can't have section or attribute names that are
132 # builtins.
132 # builtins.
133 try:
133 try:
134 return getattr(builtin_mod, key)
134 return getattr(builtin_mod, key)
@@ -182,25 +182,25 class Config(dict):
182
182
183 class ConfigLoader(object):
183 class ConfigLoader(object):
184 """A object for loading configurations from just about anywhere.
184 """A object for loading configurations from just about anywhere.
185
185
186 The resulting configuration is packaged as a :class:`Struct`.
186 The resulting configuration is packaged as a :class:`Struct`.
187
187
188 Notes
188 Notes
189 -----
189 -----
190 A :class:`ConfigLoader` does one thing: load a config from a source
190 A :class:`ConfigLoader` does one thing: load a config from a source
191 (file, command line arguments) and returns the data as a :class:`Struct`.
191 (file, command line arguments) and returns the data as a :class:`Struct`.
192 There are lots of things that :class:`ConfigLoader` does not do. It does
192 There are lots of things that :class:`ConfigLoader` does not do. It does
193 not implement complex logic for finding config files. It does not handle
193 not implement complex logic for finding config files. It does not handle
194 default values or merge multiple configs. These things need to be
194 default values or merge multiple configs. These things need to be
195 handled elsewhere.
195 handled elsewhere.
196 """
196 """
197
197
198 def __init__(self):
198 def __init__(self):
199 """A base class for config loaders.
199 """A base class for config loaders.
200
200
201 Examples
201 Examples
202 --------
202 --------
203
203
204 >>> cl = ConfigLoader()
204 >>> cl = ConfigLoader()
205 >>> config = cl.load_config()
205 >>> config = cl.load_config()
206 >>> config
206 >>> config
@@ -213,7 +213,7 class ConfigLoader(object):
213
213
214 def load_config(self):
214 def load_config(self):
215 """Load a config from somewhere, return a :class:`Config` instance.
215 """Load a config from somewhere, return a :class:`Config` instance.
216
216
217 Usually, this will cause self.config to be set and then returned.
217 Usually, this will cause self.config to be set and then returned.
218 However, in most cases, :meth:`ConfigLoader.clear` should be called
218 However, in most cases, :meth:`ConfigLoader.clear` should be called
219 to erase any previous state.
219 to erase any previous state.
@@ -233,7 +233,7 class FileConfigLoader(ConfigLoader):
233
233
234 class PyFileConfigLoader(FileConfigLoader):
234 class PyFileConfigLoader(FileConfigLoader):
235 """A config loader for pure python files.
235 """A config loader for pure python files.
236
236
237 This calls execfile on a plain python file and looks for attributes
237 This calls execfile on a plain python file and looks for attributes
238 that are all caps. These attribute are added to the config Struct.
238 that are all caps. These attribute are added to the config Struct.
239 """
239 """
@@ -276,10 +276,10 class PyFileConfigLoader(FileConfigLoader):
276 # and self.config. The sub-config is loaded with the same path
276 # and self.config. The sub-config is loaded with the same path
277 # as the parent, but it uses an empty config which is then merged
277 # as the parent, but it uses an empty config which is then merged
278 # with the parents.
278 # with the parents.
279
279
280 # If a profile is specified, the config file will be loaded
280 # If a profile is specified, the config file will be loaded
281 # from that profile
281 # from that profile
282
282
283 def load_subconfig(fname, profile=None):
283 def load_subconfig(fname, profile=None):
284 # import here to prevent circular imports
284 # import here to prevent circular imports
285 from IPython.core.profiledir import ProfileDir, ProfileDirError
285 from IPython.core.profiledir import ProfileDir, ProfileDirError
@@ -303,7 +303,7 class PyFileConfigLoader(FileConfigLoader):
303 pass
303 pass
304 else:
304 else:
305 self.config._merge(sub_config)
305 self.config._merge(sub_config)
306
306
307 # Again, this needs to be a closure and should be used in config
307 # Again, this needs to be a closure and should be used in config
308 # files to get the config being loaded.
308 # files to get the config being loaded.
309 def get_config():
309 def get_config():
@@ -340,7 +340,7 class CommandLineConfigLoader(ConfigLoader):
340 # it succeeds. If it still fails, we let it raise.
340 # it succeeds. If it still fails, we let it raise.
341 exec_str = u'self.config.' + lhs + '=' + repr(rhs)
341 exec_str = u'self.config.' + lhs + '=' + repr(rhs)
342 exec exec_str in locals(), globals()
342 exec exec_str in locals(), globals()
343
343
344 def _load_flag(self, cfg):
344 def _load_flag(self, cfg):
345 """update self.config from a flag, which can be a dict or Config"""
345 """update self.config from a flag, which can be a dict or Config"""
346 if isinstance(cfg, (dict, Config)):
346 if isinstance(cfg, (dict, Config)):
@@ -373,7 +373,7 class KeyValueConfigLoader(CommandLineConfigLoader):
373 """A config loader that loads key value pairs from the command line.
373 """A config loader that loads key value pairs from the command line.
374
374
375 This allows command line options to be gives in the following form::
375 This allows command line options to be gives in the following form::
376
376
377 ipython --profile="foo" --InteractiveShell.autocall=False
377 ipython --profile="foo" --InteractiveShell.autocall=False
378 """
378 """
379
379
@@ -414,13 +414,13 class KeyValueConfigLoader(CommandLineConfigLoader):
414 self.argv = argv
414 self.argv = argv
415 self.aliases = aliases or {}
415 self.aliases = aliases or {}
416 self.flags = flags or {}
416 self.flags = flags or {}
417
417
418
418
419 def clear(self):
419 def clear(self):
420 super(KeyValueConfigLoader, self).clear()
420 super(KeyValueConfigLoader, self).clear()
421 self.extra_args = []
421 self.extra_args = []
422
422
423
423
424 def _decode_argv(self, argv, enc=None):
424 def _decode_argv(self, argv, enc=None):
425 """decode argv if bytes, using stin.encoding, falling back on default enc"""
425 """decode argv if bytes, using stin.encoding, falling back on default enc"""
426 uargv = []
426 uargv = []
@@ -432,16 +432,16 class KeyValueConfigLoader(CommandLineConfigLoader):
432 arg = arg.decode(enc)
432 arg = arg.decode(enc)
433 uargv.append(arg)
433 uargv.append(arg)
434 return uargv
434 return uargv
435
435
436
436
437 def load_config(self, argv=None, aliases=None, flags=None):
437 def load_config(self, argv=None, aliases=None, flags=None):
438 """Parse the configuration and generate the Config object.
438 """Parse the configuration and generate the Config object.
439
439
440 After loading, any arguments that are not key-value or
440 After loading, any arguments that are not key-value or
441 flags will be stored in self.extra_args - a list of
441 flags will be stored in self.extra_args - a list of
442 unparsed command-line arguments. This is used for
442 unparsed command-line arguments. This is used for
443 arguments such as input files or subcommands.
443 arguments such as input files or subcommands.
444
444
445 Parameters
445 Parameters
446 ----------
446 ----------
447 argv : list, optional
447 argv : list, optional
@@ -454,7 +454,7 class KeyValueConfigLoader(CommandLineConfigLoader):
454 Of the form: `{'alias' : 'Configurable.trait'}`
454 Of the form: `{'alias' : 'Configurable.trait'}`
455 flags : dict
455 flags : dict
456 A dict of flags, keyed by str name. Values can be Config objects
456 A dict of flags, keyed by str name. Values can be Config objects
457 or dicts. When the flag is triggered, The config is loaded as
457 or dicts. When the flag is triggered, The config is loaded as
458 `self.config.update(cfg)`.
458 `self.config.update(cfg)`.
459 """
459 """
460 from IPython.config.configurable import Configurable
460 from IPython.config.configurable import Configurable
@@ -466,20 +466,20 class KeyValueConfigLoader(CommandLineConfigLoader):
466 aliases = self.aliases
466 aliases = self.aliases
467 if flags is None:
467 if flags is None:
468 flags = self.flags
468 flags = self.flags
469
469
470 # ensure argv is a list of unicode strings:
470 # ensure argv is a list of unicode strings:
471 uargv = self._decode_argv(argv)
471 uargv = self._decode_argv(argv)
472 for idx,raw in enumerate(uargv):
472 for idx,raw in enumerate(uargv):
473 # strip leading '-'
473 # strip leading '-'
474 item = raw.lstrip('-')
474 item = raw.lstrip('-')
475
475
476 if raw == '--':
476 if raw == '--':
477 # don't parse arguments after '--'
477 # don't parse arguments after '--'
478 # this is useful for relaying arguments to scripts, e.g.
478 # this is useful for relaying arguments to scripts, e.g.
479 # ipython -i foo.py --pylab=qt -- args after '--' go-to-foo.py
479 # ipython -i foo.py --pylab=qt -- args after '--' go-to-foo.py
480 self.extra_args.extend(uargv[idx+1:])
480 self.extra_args.extend(uargv[idx+1:])
481 break
481 break
482
482
483 if kv_pattern.match(raw):
483 if kv_pattern.match(raw):
484 lhs,rhs = item.split('=',1)
484 lhs,rhs = item.split('=',1)
485 # Substitute longnames for aliases.
485 # Substitute longnames for aliases.
@@ -489,7 +489,7 class KeyValueConfigLoader(CommandLineConfigLoader):
489 # probably a mistyped alias, but not technically illegal
489 # probably a mistyped alias, but not technically illegal
490 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
490 warn.warn("Unrecognized alias: '%s', it will probably have no effect."%lhs)
491 self._exec_config_str(lhs, rhs)
491 self._exec_config_str(lhs, rhs)
492
492
493 elif flag_pattern.match(raw):
493 elif flag_pattern.match(raw):
494 if item in flags:
494 if item in flags:
495 cfg,help = flags[item]
495 cfg,help = flags[item]
@@ -503,7 +503,7 class KeyValueConfigLoader(CommandLineConfigLoader):
503 else:
503 else:
504 raise ArgumentError("Invalid argument: '%s'"%raw)
504 raise ArgumentError("Invalid argument: '%s'"%raw)
505 else:
505 else:
506 # keep all args that aren't valid in a list,
506 # keep all args that aren't valid in a list,
507 # in case our parent knows what to do with them.
507 # in case our parent knows what to do with them.
508 self.extra_args.append(item)
508 self.extra_args.append(item)
509 return self.config
509 return self.config
@@ -541,7 +541,7 class ArgParseConfigLoader(CommandLineConfigLoader):
541 self.argv = argv
541 self.argv = argv
542 self.aliases = aliases or {}
542 self.aliases = aliases or {}
543 self.flags = flags or {}
543 self.flags = flags or {}
544
544
545 self.parser_args = parser_args
545 self.parser_args = parser_args
546 self.version = parser_kw.pop("version", None)
546 self.version = parser_kw.pop("version", None)
547 kwargs = dict(argument_default=argparse.SUPPRESS)
547 kwargs = dict(argument_default=argparse.SUPPRESS)
@@ -597,10 +597,10 class ArgParseConfigLoader(CommandLineConfigLoader):
597
597
598 class KVArgParseConfigLoader(ArgParseConfigLoader):
598 class KVArgParseConfigLoader(ArgParseConfigLoader):
599 """A config loader that loads aliases and flags with argparse,
599 """A config loader that loads aliases and flags with argparse,
600 but will use KVLoader for the rest. This allows better parsing
600 but will use KVLoader for the rest. This allows better parsing
601 of common args, such as `ipython -c 'print 5'`, but still gets
601 of common args, such as `ipython -c 'print 5'`, but still gets
602 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
602 arbitrary config with `ipython --InteractiveShell.use_readline=False`"""
603
603
604 def _convert_to_config(self):
604 def _convert_to_config(self):
605 """self.parsed_data->self.config"""
605 """self.parsed_data->self.config"""
606 for k, v in vars(self.parsed_data).iteritems():
606 for k, v in vars(self.parsed_data).iteritems():
@@ -626,14 +626,14 class KVArgParseConfigLoader(ArgParseConfigLoader):
626 paa('--'+key, type=unicode, dest=value, nargs=nargs)
626 paa('--'+key, type=unicode, dest=value, nargs=nargs)
627 for key, (value, help) in flags.iteritems():
627 for key, (value, help) in flags.iteritems():
628 if key in self.aliases:
628 if key in self.aliases:
629 #
629 #
630 self.alias_flags[self.aliases[key]] = value
630 self.alias_flags[self.aliases[key]] = value
631 continue
631 continue
632 if len(key) is 1:
632 if len(key) is 1:
633 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
633 paa('-'+key, '--'+key, action='append_const', dest='_flags', const=value)
634 else:
634 else:
635 paa('--'+key, action='append_const', dest='_flags', const=value)
635 paa('--'+key, action='append_const', dest='_flags', const=value)
636
636
637 def _convert_to_config(self):
637 def _convert_to_config(self):
638 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
638 """self.parsed_data->self.config, parse unrecognized extra args via KVLoader."""
639 # remove subconfigs list from namespace before transforming the Namespace
639 # remove subconfigs list from namespace before transforming the Namespace
@@ -642,7 +642,7 class KVArgParseConfigLoader(ArgParseConfigLoader):
642 del self.parsed_data._flags
642 del self.parsed_data._flags
643 else:
643 else:
644 subcs = []
644 subcs = []
645
645
646 for k, v in vars(self.parsed_data).iteritems():
646 for k, v in vars(self.parsed_data).iteritems():
647 if v is None:
647 if v is None:
648 # it was a flag that shares the name of an alias
648 # it was a flag that shares the name of an alias
@@ -650,10 +650,10 class KVArgParseConfigLoader(ArgParseConfigLoader):
650 else:
650 else:
651 # eval the KV assignment
651 # eval the KV assignment
652 self._exec_config_str(k, v)
652 self._exec_config_str(k, v)
653
653
654 for subc in subcs:
654 for subc in subcs:
655 self._load_flag(subc)
655 self._load_flag(subc)
656
656
657 if self.extra_args:
657 if self.extra_args:
658 sub_parser = KeyValueConfigLoader()
658 sub_parser = KeyValueConfigLoader()
659 sub_parser.