# HG changeset patch # User Jeff Hammel # Date 1336085173 25200 # Node ID a2184db43fe2273a9e8539626d5851808c593970 # Parent 83d66a9bdef05197369212a3846d1d5c5274a42f fix dict command line processing diff -r 83d66a9bdef0 -r a2184db43fe2 configuration/configuration.py --- a/configuration/configuration.py Thu May 03 08:26:10 2012 -0700 +++ b/configuration/configuration.py Thu May 03 15:46:13 2012 -0700 @@ -111,6 +111,15 @@ """option that keeps track if it is seen""" # TODO: this should be configurable or something def take_action(self, action, dest, opt, value, values, parser): + + # switch on types + formatter = getattr(parser, 'cli_formatter') + if formatter: + formatter = formatter(dest) + if formatter: + value = formatter(value) + + # call the optparse front-end optparse.Option.take_action(self, action, dest, opt, value, values, parser) # add the parsed option to the set of things parsed @@ -118,13 +127,6 @@ parser.parsed = set() parser.parsed.add(dest) - # switch on types - formatter = getattr(parser, 'cli_formatter') - if formatter: - formatter = formatter(dest) - if formatter: - setattr(values, dest, formatter(getattr(values, dest))) - ### plugins for option types class BaseCLI(object): @@ -202,11 +204,20 @@ delimeter = '=' + def __call__(self, name, value): + + # optparse can't handle dict types OOTB + default = value.get('default') + if isinstance(default, dict): + value = copy.deepcopy(value) + value['default'] = default.items() + + return ListCLI.__call__(self, name, value) + def take_action(self, value): - bad = [i for i in value if self.delimeter not in i] - if bad: - raise AssertionError("Each value must be delimited by '%s': %s" % (self.delimeter, bad)) - return dict([i.split(self.delimeter, 1) for i in value]) + if self.delimeter not in value: + raise AssertionError("Each value must be delimited by '%s': %s" % (self.delimeter, value)) + return value.split(self.delimeter, 1) # TODO: 'dict'-type cli interface @@ -376,7 +387,7 @@ def cli_formatter(self, option): if option in self.option_dict: - handler = self.types[self.option_dict[option].get('type')] + handler = self.types[self.option_type(option)] return getattr(handler, 'take_action', lambda x: x) def option_type(self, name): diff -r 83d66a9bdef0 -r a2184db43fe2 tests/unit.py --- a/tests/unit.py Thu May 03 08:26:10 2012 -0700 +++ b/tests/unit.py Thu May 03 15:46:13 2012 -0700 @@ -41,6 +41,24 @@ self.assertEqual(example.config['activeTests'], ['ts']) self.assertEqual(example.config['browser_path'], '/home/jhammel/bin/firefox') + def test_dict(self): + """test dictionary parsing from the "command line" """ + + + # test adding a preference + example = ExampleConfiguration() + options, args = example.parse_args(['-a', 'ts', '--develop', '-e', '/home/jhammel/bin/firefox', + '--pref', 'hangmonitor.timeout=0']) + self.assertTrue('hangmonitor.timeout' in options.preferences) + + # test overriding a preference + example = ExampleConfiguration() + options, args = example.parse_args(['-a', 'ts', '--develop', '-e', '/home/jhammel/bin/firefox', + '--pref', 'browser.bookmarks.max_backups=1']) + self.assertTrue(options.preferences['browser.bookmarks.max_backups'] == '1') + + + def test_configuration_providers(self): """test file-based configuration providers""" # requires json/simplejson to be installed