From e957fe673d03881587048662fd33e66477b18c7e 2011-05-17 19:37:16 From: MinRK Date: 2011-05-17 19:37:16 Subject: [PATCH] rename macros/shortnames to flags/aliases also remove macro_help in favor of alias values being tuples. --- diff --git a/IPython/config/application.py b/IPython/config/application.py index 17de568..b2122cd 100644 --- a/IPython/config/application.py +++ b/IPython/config/application.py @@ -24,7 +24,7 @@ import sys from IPython.config.configurable import SingletonConfigurable from IPython.config.loader import ( - KeyValueConfigLoader, PyFileConfigLoader + KeyValueConfigLoader, PyFileConfigLoader, Config ) from IPython.utils.traitlets import ( @@ -36,14 +36,14 @@ from IPython.utils.text import indent # Descriptions for #----------------------------------------------------------------------------- -macro_description = """ +flag_description = """ Flags are command-line arguments passed as '--'. These take no parameters, unlike regular key-value arguments. They are typically used for setting boolean flags, or enabling modes that involve setting multiple options together. """.strip() # trim newlines of front and back -shortname_description = """ +alias_description = """ These are commonly set parameters, given abbreviated aliases for convenience. They are set in the same `name=value` way as class parameters, where is replaced by the real parameter for which it is an alias. @@ -72,13 +72,13 @@ class Application(SingletonConfigurable): # of the help. description = Unicode(u'This is an application.') # default section descriptions - macro_description = Unicode(macro_description) - shortname_description = Unicode(shortname_description) + flag_description = Unicode(flag_description) + alias_description = Unicode(alias_description) keyvalue_description = Unicode(keyvalue_description) # A sequence of Configurable subclasses whose config=True attributes will - # be exposed at the command line (shortnames and help). + # be exposed at the command line. classes = List([]) # The version string of this application. @@ -89,14 +89,14 @@ class Application(SingletonConfigurable): config=True, help="Set the log level (0,10,20,30,40,50).") - # the shortname map for configurables - shortnames = Dict(dict(log_level='Application.log_level')) + # the alias map for configurables + aliases = Dict(dict(log_level='Application.log_level')) - # macros for loading Configurables or store_const style flags - # macros are loaded from this dict by '--key' flags - macros = Dict() - # macro_help dict keys must match macros - macro_help = Dict() + # flags for loading Configurables or store_const style flags + # flags are loaded from this dict by '--key' flags + # this must be a dict of two-tuples, the first element being the Config/dict + # and the second being the help string for the flag + flags = Dict() def __init__(self, **kwargs): @@ -105,12 +105,11 @@ class Application(SingletonConfigurable): # options. self.classes.insert(0, self.__class__) - # check that macro_help has the right keys - # there is probably a better way to do this that doesn't use 2 dicts - keys = set(self.macros.keys()) - badkeys = keys.difference_update(set(self.macro_help.keys())) - if badkeys: - raise KeyError("macro %r has no help in `macro_help`!"%badkeys.pop()) + # ensure self.flags dict is valid + for key,value in self.flags.iteritems(): + assert len(value) == 2, "Bad flag: %r:%s"%(key,value) + assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value) + assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value) self.init_logging() def init_logging(self): @@ -131,50 +130,50 @@ class Application(SingletonConfigurable): """Adjust the log level when log_level is set.""" self.log.setLevel(new) - def print_shortname_help(self): - """print the shortname part of the help""" - if not self.shortnames: + def print_alias_help(self): + """print the alias part of the help""" + if not self.aliases: return print "Aliases" print "-------" - print self.shortname_description + print self.alias_description print classdict = {} for c in self.classes: classdict[c.__name__] = c - for shortname, longname in self.shortnames.iteritems(): + for alias, longname in self.aliases.iteritems(): classname, traitname = longname.split('.',1) cls = classdict[classname] trait = cls.class_traits(config=True)[traitname] help = trait.get_metadata('help') - print shortname, "(%s)"%longname, ':', trait.__class__.__name__ + print alias, "(%s)"%longname, ':', trait.__class__.__name__ if help: print indent(help) print - def print_macro_help(self): - """print the the macro part of the help""" - if not self.macros: + def print_flag_help(self): + """print the flag part of the help""" + if not self.flags: return print "Flags" print "-----" - print self.macro_description + print self.flag_description print - for m, cfg in self.macros.iteritems(): + for m, (cfg,help) in self.flags.iteritems(): print '--'+m - print indent(self.macro_help[m]) + print indent(help) print def print_help(self): """Print the help for each Configurable class in self.classes.""" - self.print_macro_help() - self.print_shortname_help() + self.print_flag_help() + self.print_alias_help() if self.classes: print "Class parameters" print "----------------" @@ -216,9 +215,9 @@ class Application(SingletonConfigurable): if '--version' in argv: self.print_version() sys.exit(1) - - loader = KeyValueConfigLoader(argv=argv, shortnames=self.shortnames, - macros=self.macros) + + loader = KeyValueConfigLoader(argv=argv, aliases=self.aliases, + flags=self.flags) config = loader.load_config() self.update_config(config) diff --git a/IPython/config/loader.py b/IPython/config/loader.py index 1415338..c9bb642 100644 --- a/IPython/config/loader.py +++ b/IPython/config/loader.py @@ -305,7 +305,7 @@ class CommandLineConfigLoader(ConfigLoader): """ kv_pattern = re.compile(r'[A-Za-z]\w*(\.\w+)*\=.+') -macro_pattern = re.compile(r'\-\-\w+(\-\w)*') +flag_pattern = re.compile(r'\-\-\w+(\-\w)*') class KeyValueConfigLoader(CommandLineConfigLoader): """A config loader that loads key value pairs from the command line. @@ -315,7 +315,7 @@ class KeyValueConfigLoader(CommandLineConfigLoader): ipython Global.profile="foo" InteractiveShell.autocall=False """ - def __init__(self, argv=None, shortnames=None, macros=None): + def __init__(self, argv=None, aliases=None, flags=None): """Create a key value pair config loader. Parameters @@ -324,14 +324,14 @@ class KeyValueConfigLoader(CommandLineConfigLoader): A list that has the form of sys.argv[1:] which has unicode elements of the form u"key=value". If this is None (default), then sys.argv[1:] will be used. - shortnames : dict + aliases : dict A dict of aliases for configurable traits. Keys are the short aliases, Values are the resolved trait. - Of the form: `{'shortname' : 'Configurable.trait'}` - macros : dict - A dict of macros, keyed by str name. Vaues can be Config objects, - dicts, or "key=value" strings. If Config or dict, when the macro - is triggered, The macro is loaded as `self.config.update(m)`. + Of the form: `{'alias' : 'Configurable.trait'}` + flags : dict + A dict of flags, keyed by str name. Vaues can be Config objects, + dicts, or "key=value" strings. If Config or dict, when the flag + is triggered, The flag is loaded as `self.config.update(m)`. Returns ------- @@ -349,10 +349,10 @@ class KeyValueConfigLoader(CommandLineConfigLoader): if argv is None: argv = sys.argv[1:] self.argv = argv - self.shortnames = shortnames or {} - self.macros = macros or {} + self.aliases = aliases or {} + self.flags = flags or {} - def load_config(self, argv=None, shortnames=None, macros=None): + def load_config(self, argv=None, aliases=None, flags=None): """Parse the configuration and generate the Config object. Parameters @@ -361,31 +361,31 @@ class KeyValueConfigLoader(CommandLineConfigLoader): A list that has the form of sys.argv[1:] which has unicode elements of the form u"key=value". If this is None (default), then self.argv will be used. - shortnames : dict + aliases : dict A dict of aliases for configurable traits. Keys are the short aliases, Values are the resolved trait. - Of the form: `{'shortname' : 'Configurable.trait'}` - macros : dict - A dict of macros, keyed by str name. Vaues can be Config objects, - dicts, or "key=value" strings. If Config or dict, when the macro - is triggered, The macro is loaded as `self.config.update(m)`. + Of the form: `{'alias' : 'Configurable.trait'}` + flags : dict + A dict of flags, keyed by str name. Values can be Config objects + or dicts. When the flag is triggered, The config is loaded as + `self.config.update(cfg)`. """ from IPython.config.configurable import Configurable self.clear() if argv is None: argv = self.argv - if shortnames is None: - shortnames = self.shortnames - if macros is None: - macros = self.macros + if aliases is None: + aliases = self.aliases + if flags is None: + flags = self.flags for item in argv: if kv_pattern.match(item): lhs,rhs = item.split('=',1) - # Substitute longnames for shortnames. - if lhs in shortnames: - lhs = shortnames[lhs] + # Substitute longnames for aliases. + if lhs in aliases: + lhs = aliases[lhs] exec_str = 'self.config.' + lhs + '=' + rhs try: # Try to see if regular Python syntax will work. This @@ -398,18 +398,17 @@ class KeyValueConfigLoader(CommandLineConfigLoader): # it succeeds. If it still fails, we let it raise. exec_str = 'self.config.' + lhs + '="' + rhs + '"' exec exec_str in locals(), globals() - elif macro_pattern.match(item): + elif flag_pattern.match(item): # trim leading '--' m = item[2:] - macro = macros.get(m, None) - if macro is None: - raise ValueError("Unrecognized argument: %r"%item) - macro = macros[m] - if isinstance(macro, (dict, Configurable)): + cfg,_ = flags.get(m, (None,None)) + if cfg is None: + raise ValueError("Unrecognized flag: %r"%item) + elif isinstance(cfg, (dict, Config)): # update self.config with Config: - self.config.update(macros[m]) + self.config.update(cfg) else: - raise ValueError("Invalid macro: %r"%macro) + raise ValueError("Invalid flag: %r"%flag) else: raise ValueError("Invalid argument: %r"%item) return self.config diff --git a/IPython/config/tests/test_application.py b/IPython/config/tests/test_application.py index 458cf66..d98166a 100644 --- a/IPython/config/tests/test_application.py +++ b/IPython/config/tests/test_application.py @@ -26,7 +26,7 @@ from IPython.config.application import ( ) from IPython.utils.traitlets import ( - Bool, Unicode, Int, Float, List + Bool, Unicode, Int, Float, List, Dict ) #----------------------------------------------------------------------------- @@ -48,21 +48,18 @@ class Bar(Configurable): class MyApp(Application): app_name = Unicode(u'myapp') - running = Bool(False, config=True, shortname="running", + running = Bool(False, config=True, help="Is the app running?") classes = List([Bar, Foo]) - config_file = Unicode(u'', config=True, shortname="config_file", + config_file = Unicode(u'', config=True, help="Load this config file") - shortnames = dict(i='Foo.i',j='Foo.j',name='Foo.name', - enabled='Bar.enabled', log_level='MyApp.log_level') + aliases = Dict(dict(i='Foo.i',j='Foo.j',name='Foo.name', + enabled='Bar.enabled', log_level='MyApp.log_level')) + + flags = Dict(dict(enable=({'Bar': {'enabled' : True}}, "Set Bar.enabled to True"), + disable=({'Bar': {'enabled' : False}}, "Set Bar.enabled to False"))) - macros = dict(enable={'Bar': {'enabled' : True}}, disable={'Bar': {'enabled' : False}}) - - macro_help = dict( - enable="""Enable bar""", - disable="""Disable bar""" - ) def init_foo(self): self.foo = Foo(config=self.config) @@ -97,7 +94,7 @@ class TestApplication(TestCase): self.assertEquals(app.foo.j, 10) self.assertEquals(app.bar.enabled, False) - def test_macro(self): + def test_alias(self): app = MyApp() app.parse_command_line(["--disable"]) app.init_bar() diff --git a/docs/examples/core/appconfig.py b/docs/examples/core/appconfig.py index b09ed61..d0c1d10 100644 --- a/docs/examples/core/appconfig.py +++ b/docs/examples/core/appconfig.py @@ -35,7 +35,7 @@ import sys from IPython.config.configurable import Configurable from IPython.config.application import Application from IPython.utils.traitlets import ( - Bool, Unicode, Int, Float, List + Bool, Unicode, Int, Float, List, Dict ) @@ -63,15 +63,14 @@ class MyApp(Application): config_file = Unicode(u'', config=True, help="Load this config file") - shortnames = dict(i='Foo.i',j='Foo.j',name='Foo.name', running='MyApp.running', - enabled='Bar.enabled') + aliases = Dict(dict(i='Foo.i',j='Foo.j',name='Foo.name', running='MyApp.running', + enabled='Bar.enabled', log_level='MyApp.log_level')) + + flags = Dict(dict(enable=({'Bar': {'enabled' : True}}, "Enable Bar"), + disable=({'Bar': {'enabled' : False}}, "Disable Bar"), + debug=({'MyApp':{'log_level':10}}, "Set loglevel to DEBUG") + )) - macros = dict(enable={'Bar': {'enabled' : True}}, disable={'Bar': {'enabled' : False}}) - macro_help = dict( - enable="""Set Bar.enabled to True""", - disable="""Set Bar.enabled to False""" - ) - def init_foo(self): # Pass config to other classes for them to inherit the config. self.foo = Foo(config=self.config) @@ -91,7 +90,6 @@ def main(): app.init_bar() print "app.config:" print app.config - print app.bar.enabled if __name__ == "__main__":