##// END OF EJS Templates
rename macros/shortnames to flags/aliases...
MinRK -
Show More
@@ -24,7 +24,7 b' import sys'
24
24
25 from IPython.config.configurable import SingletonConfigurable
25 from IPython.config.configurable import SingletonConfigurable
26 from IPython.config.loader import (
26 from IPython.config.loader import (
27 KeyValueConfigLoader, PyFileConfigLoader
27 KeyValueConfigLoader, PyFileConfigLoader, Config
28 )
28 )
29
29
30 from IPython.utils.traitlets import (
30 from IPython.utils.traitlets import (
@@ -36,14 +36,14 b' from IPython.utils.text import indent'
36 # Descriptions for
36 # Descriptions for
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 macro_description = """
39 flag_description = """
40 Flags are command-line arguments passed as '--<flag>'.
40 Flags are command-line arguments passed as '--<flag>'.
41 These take no parameters, unlike regular key-value arguments.
41 These take no parameters, unlike regular key-value arguments.
42 They are typically used for setting boolean flags, or enabling
42 They are typically used for setting boolean flags, or enabling
43 modes that involve setting multiple options together.
43 modes that involve setting multiple options together.
44 """.strip() # trim newlines of front and back
44 """.strip() # trim newlines of front and back
45
45
46 shortname_description = """
46 alias_description = """
47 These are commonly set parameters, given abbreviated aliases for convenience.
47 These are commonly set parameters, given abbreviated aliases for convenience.
48 They are set in the same `name=value` way as class parameters, where
48 They are set in the same `name=value` way as class parameters, where
49 <name> is replaced by the real parameter for which it is an alias.
49 <name> is replaced by the real parameter for which it is an alias.
@@ -72,13 +72,13 b' class Application(SingletonConfigurable):'
72 # of the help.
72 # of the help.
73 description = Unicode(u'This is an application.')
73 description = Unicode(u'This is an application.')
74 # default section descriptions
74 # default section descriptions
75 macro_description = Unicode(macro_description)
75 flag_description = Unicode(flag_description)
76 shortname_description = Unicode(shortname_description)
76 alias_description = Unicode(alias_description)
77 keyvalue_description = Unicode(keyvalue_description)
77 keyvalue_description = Unicode(keyvalue_description)
78
78
79
79
80 # A sequence of Configurable subclasses whose config=True attributes will
80 # A sequence of Configurable subclasses whose config=True attributes will
81 # be exposed at the command line (shortnames and help).
81 # be exposed at the command line.
82 classes = List([])
82 classes = List([])
83
83
84 # The version string of this application.
84 # The version string of this application.
@@ -89,14 +89,14 b' class Application(SingletonConfigurable):'
89 config=True,
89 config=True,
90 help="Set the log level (0,10,20,30,40,50).")
90 help="Set the log level (0,10,20,30,40,50).")
91
91
92 # the shortname map for configurables
92 # the alias map for configurables
93 shortnames = Dict(dict(log_level='Application.log_level'))
93 aliases = Dict(dict(log_level='Application.log_level'))
94
94
95 # macros for loading Configurables or store_const style flags
95 # flags for loading Configurables or store_const style flags
96 # macros are loaded from this dict by '--key' flags
96 # flags are loaded from this dict by '--key' flags
97 macros = Dict()
97 # this must be a dict of two-tuples, the first element being the Config/dict
98 # macro_help dict keys must match macros
98 # and the second being the help string for the flag
99 macro_help = Dict()
99 flags = Dict()
100
100
101
101
102 def __init__(self, **kwargs):
102 def __init__(self, **kwargs):
@@ -105,12 +105,11 b' class Application(SingletonConfigurable):'
105 # options.
105 # options.
106 self.classes.insert(0, self.__class__)
106 self.classes.insert(0, self.__class__)
107
107
108 # check that macro_help has the right keys
108 # ensure self.flags dict is valid
109 # there is probably a better way to do this that doesn't use 2 dicts
109 for key,value in self.flags.iteritems():
110 keys = set(self.macros.keys())
110 assert len(value) == 2, "Bad flag: %r:%s"%(key,value)
111 badkeys = keys.difference_update(set(self.macro_help.keys()))
111 assert isinstance(value[0], (dict, Config)), "Bad flag: %r:%s"%(key,value)
112 if badkeys:
112 assert isinstance(value[1], basestring), "Bad flag: %r:%s"%(key,value)
113 raise KeyError("macro %r has no help in `macro_help`!"%badkeys.pop())
114 self.init_logging()
113 self.init_logging()
115
114
116 def init_logging(self):
115 def init_logging(self):
@@ -131,50 +130,50 b' class Application(SingletonConfigurable):'
131 """Adjust the log level when log_level is set."""
130 """Adjust the log level when log_level is set."""
132 self.log.setLevel(new)
131 self.log.setLevel(new)
133
132
134 def print_shortname_help(self):
133 def print_alias_help(self):
135 """print the shortname part of the help"""
134 """print the alias part of the help"""
136 if not self.shortnames:
135 if not self.aliases:
137 return
136 return
138
137
139 print "Aliases"
138 print "Aliases"
140 print "-------"
139 print "-------"
141 print self.shortname_description
140 print self.alias_description
142 print
141 print
143
142
144 classdict = {}
143 classdict = {}
145 for c in self.classes:
144 for c in self.classes:
146 classdict[c.__name__] = c
145 classdict[c.__name__] = c
147
146
148 for shortname, longname in self.shortnames.iteritems():
147 for alias, longname in self.aliases.iteritems():
149 classname, traitname = longname.split('.',1)
148 classname, traitname = longname.split('.',1)
150 cls = classdict[classname]
149 cls = classdict[classname]
151
150
152 trait = cls.class_traits(config=True)[traitname]
151 trait = cls.class_traits(config=True)[traitname]
153 help = trait.get_metadata('help')
152 help = trait.get_metadata('help')
154 print shortname, "(%s)"%longname, ':', trait.__class__.__name__
153 print alias, "(%s)"%longname, ':', trait.__class__.__name__
155 if help:
154 if help:
156 print indent(help)
155 print indent(help)
157 print
156 print
158
157
159 def print_macro_help(self):
158 def print_flag_help(self):
160 """print the the macro part of the help"""
159 """print the flag part of the help"""
161 if not self.macros:
160 if not self.flags:
162 return
161 return
163
162
164 print "Flags"
163 print "Flags"
165 print "-----"
164 print "-----"
166 print self.macro_description
165 print self.flag_description
167 print
166 print
168
167
169 for m, cfg in self.macros.iteritems():
168 for m, (cfg,help) in self.flags.iteritems():
170 print '--'+m
169 print '--'+m
171 print indent(self.macro_help[m])
170 print indent(help)
172 print
171 print
173
172
174 def print_help(self):
173 def print_help(self):
175 """Print the help for each Configurable class in self.classes."""
174 """Print the help for each Configurable class in self.classes."""
176 self.print_macro_help()
175 self.print_flag_help()
177 self.print_shortname_help()
176 self.print_alias_help()
178 if self.classes:
177 if self.classes:
179 print "Class parameters"
178 print "Class parameters"
180 print "----------------"
179 print "----------------"
@@ -216,9 +215,9 b' class Application(SingletonConfigurable):'
216 if '--version' in argv:
215 if '--version' in argv:
217 self.print_version()
216 self.print_version()
218 sys.exit(1)
217 sys.exit(1)
219
218
220 loader = KeyValueConfigLoader(argv=argv, shortnames=self.shortnames,
219 loader = KeyValueConfigLoader(argv=argv, aliases=self.aliases,
221 macros=self.macros)
220 flags=self.flags)
222 config = loader.load_config()
221 config = loader.load_config()
223 self.update_config(config)
222 self.update_config(config)
224
223
@@ -305,7 +305,7 b' class CommandLineConfigLoader(ConfigLoader):'
305 """
305 """
306
306
307 kv_pattern = re.compile(r'[A-Za-z]\w*(\.\w+)*\=.+')
307 kv_pattern = re.compile(r'[A-Za-z]\w*(\.\w+)*\=.+')
308 macro_pattern = re.compile(r'\-\-\w+(\-\w)*')
308 flag_pattern = re.compile(r'\-\-\w+(\-\w)*')
309
309
310 class KeyValueConfigLoader(CommandLineConfigLoader):
310 class KeyValueConfigLoader(CommandLineConfigLoader):
311 """A config loader that loads key value pairs from the command line.
311 """A config loader that loads key value pairs from the command line.
@@ -315,7 +315,7 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
315 ipython Global.profile="foo" InteractiveShell.autocall=False
315 ipython Global.profile="foo" InteractiveShell.autocall=False
316 """
316 """
317
317
318 def __init__(self, argv=None, shortnames=None, macros=None):
318 def __init__(self, argv=None, aliases=None, flags=None):
319 """Create a key value pair config loader.
319 """Create a key value pair config loader.
320
320
321 Parameters
321 Parameters
@@ -324,14 +324,14 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
324 A list that has the form of sys.argv[1:] which has unicode
324 A list that has the form of sys.argv[1:] which has unicode
325 elements of the form u"key=value". If this is None (default),
325 elements of the form u"key=value". If this is None (default),
326 then sys.argv[1:] will be used.
326 then sys.argv[1:] will be used.
327 shortnames : dict
327 aliases : dict
328 A dict of aliases for configurable traits.
328 A dict of aliases for configurable traits.
329 Keys are the short aliases, Values are the resolved trait.
329 Keys are the short aliases, Values are the resolved trait.
330 Of the form: `{'shortname' : 'Configurable.trait'}`
330 Of the form: `{'alias' : 'Configurable.trait'}`
331 macros : dict
331 flags : dict
332 A dict of macros, keyed by str name. Vaues can be Config objects,
332 A dict of flags, keyed by str name. Vaues can be Config objects,
333 dicts, or "key=value" strings. If Config or dict, when the macro
333 dicts, or "key=value" strings. If Config or dict, when the flag
334 is triggered, The macro is loaded as `self.config.update(m)`.
334 is triggered, The flag is loaded as `self.config.update(m)`.
335
335
336 Returns
336 Returns
337 -------
337 -------
@@ -349,10 +349,10 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
349 if argv is None:
349 if argv is None:
350 argv = sys.argv[1:]
350 argv = sys.argv[1:]
351 self.argv = argv
351 self.argv = argv
352 self.shortnames = shortnames or {}
352 self.aliases = aliases or {}
353 self.macros = macros or {}
353 self.flags = flags or {}
354
354
355 def load_config(self, argv=None, shortnames=None, macros=None):
355 def load_config(self, argv=None, aliases=None, flags=None):
356 """Parse the configuration and generate the Config object.
356 """Parse the configuration and generate the Config object.
357
357
358 Parameters
358 Parameters
@@ -361,31 +361,31 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
361 A list that has the form of sys.argv[1:] which has unicode
361 A list that has the form of sys.argv[1:] which has unicode
362 elements of the form u"key=value". If this is None (default),
362 elements of the form u"key=value". If this is None (default),
363 then self.argv will be used.
363 then self.argv will be used.
364 shortnames : dict
364 aliases : dict
365 A dict of aliases for configurable traits.
365 A dict of aliases for configurable traits.
366 Keys are the short aliases, Values are the resolved trait.
366 Keys are the short aliases, Values are the resolved trait.
367 Of the form: `{'shortname' : 'Configurable.trait'}`
367 Of the form: `{'alias' : 'Configurable.trait'}`
368 macros : dict
368 flags : dict
369 A dict of macros, keyed by str name. Vaues can be Config objects,
369 A dict of flags, keyed by str name. Values can be Config objects
370 dicts, or "key=value" strings. If Config or dict, when the macro
370 or dicts. When the flag is triggered, The config is loaded as
371 is triggered, The macro is loaded as `self.config.update(m)`.
371 `self.config.update(cfg)`.
372 """
372 """
373 from IPython.config.configurable import Configurable
373 from IPython.config.configurable import Configurable
374
374
375 self.clear()
375 self.clear()
376 if argv is None:
376 if argv is None:
377 argv = self.argv
377 argv = self.argv
378 if shortnames is None:
378 if aliases is None:
379 shortnames = self.shortnames
379 aliases = self.aliases
380 if macros is None:
380 if flags is None:
381 macros = self.macros
381 flags = self.flags
382
382
383 for item in argv:
383 for item in argv:
384 if kv_pattern.match(item):
384 if kv_pattern.match(item):
385 lhs,rhs = item.split('=',1)
385 lhs,rhs = item.split('=',1)
386 # Substitute longnames for shortnames.
386 # Substitute longnames for aliases.
387 if lhs in shortnames:
387 if lhs in aliases:
388 lhs = shortnames[lhs]
388 lhs = aliases[lhs]
389 exec_str = 'self.config.' + lhs + '=' + rhs
389 exec_str = 'self.config.' + lhs + '=' + rhs
390 try:
390 try:
391 # Try to see if regular Python syntax will work. This
391 # Try to see if regular Python syntax will work. This
@@ -398,18 +398,17 b' class KeyValueConfigLoader(CommandLineConfigLoader):'
398 # it succeeds. If it still fails, we let it raise.
398 # it succeeds. If it still fails, we let it raise.
399 exec_str = 'self.config.' + lhs + '="' + rhs + '"'
399 exec_str = 'self.config.' + lhs + '="' + rhs + '"'
400 exec exec_str in locals(), globals()
400 exec exec_str in locals(), globals()
401 elif macro_pattern.match(item):
401 elif flag_pattern.match(item):
402 # trim leading '--'
402 # trim leading '--'
403 m = item[2:]
403 m = item[2:]
404 macro = macros.get(m, None)
404 cfg,_ = flags.get(m, (None,None))
405 if macro is None:
405 if cfg is None:
406 raise ValueError("Unrecognized argument: %r"%item)
406 raise ValueError("Unrecognized flag: %r"%item)
407 macro = macros[m]
407 elif isinstance(cfg, (dict, Config)):
408 if isinstance(macro, (dict, Configurable)):
409 # update self.config with Config:
408 # update self.config with Config:
410 self.config.update(macros[m])
409 self.config.update(cfg)
411 else:
410 else:
412 raise ValueError("Invalid macro: %r"%macro)
411 raise ValueError("Invalid flag: %r"%flag)
413 else:
412 else:
414 raise ValueError("Invalid argument: %r"%item)
413 raise ValueError("Invalid argument: %r"%item)
415 return self.config
414 return self.config
@@ -26,7 +26,7 b' from IPython.config.application import ('
26 )
26 )
27
27
28 from IPython.utils.traitlets import (
28 from IPython.utils.traitlets import (
29 Bool, Unicode, Int, Float, List
29 Bool, Unicode, Int, Float, List, Dict
30 )
30 )
31
31
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
@@ -48,21 +48,18 b' class Bar(Configurable):'
48 class MyApp(Application):
48 class MyApp(Application):
49
49
50 app_name = Unicode(u'myapp')
50 app_name = Unicode(u'myapp')
51 running = Bool(False, config=True, shortname="running",
51 running = Bool(False, config=True,
52 help="Is the app running?")
52 help="Is the app running?")
53 classes = List([Bar, Foo])
53 classes = List([Bar, Foo])
54 config_file = Unicode(u'', config=True, shortname="config_file",
54 config_file = Unicode(u'', config=True,
55 help="Load this config file")
55 help="Load this config file")
56
56
57 shortnames = dict(i='Foo.i',j='Foo.j',name='Foo.name',
57 aliases = Dict(dict(i='Foo.i',j='Foo.j',name='Foo.name',
58 enabled='Bar.enabled', log_level='MyApp.log_level')
58 enabled='Bar.enabled', log_level='MyApp.log_level'))
59
60 flags = Dict(dict(enable=({'Bar': {'enabled' : True}}, "Set Bar.enabled to True"),
61 disable=({'Bar': {'enabled' : False}}, "Set Bar.enabled to False")))
59
62
60 macros = dict(enable={'Bar': {'enabled' : True}}, disable={'Bar': {'enabled' : False}})
61
62 macro_help = dict(
63 enable="""Enable bar""",
64 disable="""Disable bar"""
65 )
66 def init_foo(self):
63 def init_foo(self):
67 self.foo = Foo(config=self.config)
64 self.foo = Foo(config=self.config)
68
65
@@ -97,7 +94,7 b' class TestApplication(TestCase):'
97 self.assertEquals(app.foo.j, 10)
94 self.assertEquals(app.foo.j, 10)
98 self.assertEquals(app.bar.enabled, False)
95 self.assertEquals(app.bar.enabled, False)
99
96
100 def test_macro(self):
97 def test_alias(self):
101 app = MyApp()
98 app = MyApp()
102 app.parse_command_line(["--disable"])
99 app.parse_command_line(["--disable"])
103 app.init_bar()
100 app.init_bar()
@@ -35,7 +35,7 b' import sys'
35 from IPython.config.configurable import Configurable
35 from IPython.config.configurable import Configurable
36 from IPython.config.application import Application
36 from IPython.config.application import Application
37 from IPython.utils.traitlets import (
37 from IPython.utils.traitlets import (
38 Bool, Unicode, Int, Float, List
38 Bool, Unicode, Int, Float, List, Dict
39 )
39 )
40
40
41
41
@@ -63,15 +63,14 b' class MyApp(Application):'
63 config_file = Unicode(u'', config=True,
63 config_file = Unicode(u'', config=True,
64 help="Load this config file")
64 help="Load this config file")
65
65
66 shortnames = dict(i='Foo.i',j='Foo.j',name='Foo.name', running='MyApp.running',
66 aliases = Dict(dict(i='Foo.i',j='Foo.j',name='Foo.name', running='MyApp.running',
67 enabled='Bar.enabled')
67 enabled='Bar.enabled', log_level='MyApp.log_level'))
68
69 flags = Dict(dict(enable=({'Bar': {'enabled' : True}}, "Enable Bar"),
70 disable=({'Bar': {'enabled' : False}}, "Disable Bar"),
71 debug=({'MyApp':{'log_level':10}}, "Set loglevel to DEBUG")
72 ))
68
73
69 macros = dict(enable={'Bar': {'enabled' : True}}, disable={'Bar': {'enabled' : False}})
70 macro_help = dict(
71 enable="""Set Bar.enabled to True""",
72 disable="""Set Bar.enabled to False"""
73 )
74
75 def init_foo(self):
74 def init_foo(self):
76 # Pass config to other classes for them to inherit the config.
75 # Pass config to other classes for them to inherit the config.
77 self.foo = Foo(config=self.config)
76 self.foo = Foo(config=self.config)
@@ -91,7 +90,6 b' def main():'
91 app.init_bar()
90 app.init_bar()
92 print "app.config:"
91 print "app.config:"
93 print app.config
92 print app.config
94 print app.bar.enabled
95
93
96
94
97 if __name__ == "__main__":
95 if __name__ == "__main__":
General Comments 0
You need to be logged in to leave comments. Login now