def setup_definitions(source, destination): for key, val in source.items(): if key.startswith('__'): continue # ignore these if isinstance(val, Option): destination[key] = val if not val.name: val.name = key val.set_value(val.default) elif isinstance(val, Aggregation): destination[key] = val elif isinstance(val, collections.Mapping): if 'name' in val and 'default' in val: # this is an Option in the form of a dict, not a Namespace if key == 'not_for_definition' and val is True: continue # ignore this element params = str_dict_keys(val) destination[key] = Option(**params) elif 'function' in val: # this is an Aggregation params = str_dict_keys(val) destination[key] = Aggregation(**params) else: # this is a Namespace if key not in destination: try: destination[key] = Namespace(doc=val._doc) except AttributeError: destination[key] = Namespace() # recurse! setup_definitions(val, destination[key]) else: destination[key] = Option(name=key, doc=key, default=val)
def test_option_constructor_more_complex_default_converters(self): data = { 'default': '2011-12-31', 'doc': "lucy's bday", 'from_string_converter': dtu.date_from_ISO_string, } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, datetime.date(2011, 12, 31)) self.assertEqual(o.doc, "lucy's bday") self.assertEqual(o.from_string_converter, dtu.date_from_ISO_string) self.assertEqual(o.value, datetime.date(2011, 12, 31)) data = { 'default': '2011-12-31', 'doc': "lucy's bday", 'from_string_converter': \ 'configman.datetime_util.date_from_ISO_string', } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, datetime.date(2011, 12, 31)) self.assertEqual(o.doc, "lucy's bday") self.assertEqual(o.from_string_converter, dtu.date_from_ISO_string) self.assertEqual(o.value, datetime.date(2011, 12, 31))
def test_list_converter_inOption(self): some_list = ['some', 'values', 'here'] opt = Option('some name', default=some_list) self.assertEqual(opt.default, some_list) self.assertEqual(opt.from_string_converter, list_converter) opt.set_value('list, of, things') self.assertEqual(opt.value, ['list', 'of', 'things'])
def test_set_value_from_mapping(self): o1 = Option('name') val = {'default': u'Peter'} o1.set_value(val) self.assertEqual(o1.value, 'Peter') val = {'justanother': 'dict!'} o1.set_value(val) self.assertEqual(o1.value, val)
def test_list_converter_inOption(self): some_list = ['some', 'values', 'here'] opt = Option('some name', default=some_list) self.assertEqual(opt.default, some_list) self.assertEqual(opt.from_string_converter, conv.list_converter) opt.set_value('list, of, things') self.assertEqual(opt.value, ['list', 'of', 'things'])
def test_regexp_converter_inOption(self): regex_str = '\w+' sample_regex = re.compile(regex_str) opt = Option('name', default=sample_regex) self.assertEqual(opt.default, sample_regex) self.assertEqual(opt.from_string_converter, regex_converter) opt.set_value(regex_str) self.assertEqual(opt.value.pattern, sample_regex.pattern)
def test_regexp_converter_inOption(self): regex_str = '\w+' sample_regex = re.compile(regex_str) opt = Option('name', default=sample_regex) self.assertEqual(opt.default, sample_regex) self.assertEqual(opt.from_string_converter, conv.regex_converter) opt.set_value(regex_str) self.assertEqual(opt.value.pattern, sample_regex.pattern)
def test_option_comparison(self): o1 = Option('name') o2 = Option('name') self.assertEqual(o1, o2) o1 = Option('name', 'Peter') o2 = Option('name', u'Peter') self.assertEqual(o1, o2) o1 = Option('name', 'Peter') o2 = Option('name', 'Ashley') self.assertNotEqual(o1, o2) o1 = Option('name', doc='Aaa') o2 = Option('name', doc='Bee') self.assertNotEqual(o1, o2) o1 = Option('name', doc='Aaa') o2 = Option('name', doc='Aaa') self.assertEqual(o1, o2) o1 = Option('name', doc='Aaa', short_form='n') o2 = Option('name', doc='Aaa', short_form='N') self.assertNotEqual(o1, o2) o1 = Option('name') o1.set_value('Peter') o2 = Option('name') self.assertNotEqual(o1, o2)
def test_setting_known_from_string_converter_onOption(self): opt = Option('name', default=u'Peter') self.assertEqual(opt.default, u'Peter') self.assertEqual(opt.from_string_converter, unicode) opt = Option('name', default=100) self.assertEqual(opt.default, 100) self.assertEqual(opt.from_string_converter, int) opt = Option('name', default=100L) self.assertEqual(opt.default, 100L) self.assertEqual(opt.from_string_converter, long) opt = Option('name', default=100.0) self.assertEqual(opt.default, 100.0) self.assertEqual(opt.from_string_converter, float) opt = Option('name', default=Decimal('100.0')) self.assertEqual(opt.default, Decimal('100.0')) self.assertEqual(opt.from_string_converter, Decimal) opt = Option('name', default=False) self.assertEqual(opt.default, False) self.assertEqual(opt.from_string_converter, boolean_converter) dt = datetime.datetime(2011, 8, 10, 0, 0, 0) opt = Option('name', default=dt) self.assertEqual(opt.default, dt) self.assertEqual(opt.from_string_converter, datetime_from_ISO_string) dt = datetime.date(2011, 8, 10) opt = Option('name', default=dt) self.assertEqual(opt.default, dt) self.assertEqual(opt.from_string_converter, date_from_ISO_string)
def test__str__(self): opt = Option('name') self.assertEqual(str(opt), '') opt = Option('name', 3.14) self.assertEqual(str(opt), '3.14') opt = Option('name', Decimal('3.14')) self.assertEqual(str(opt), '3.14') opt = Option('name', [['one', 'One'], ['two', 'Two']], to_string_converter=lambda seq: ', '.join('%s: %s' % (a, b) for (a, b) in seq)) self.assertEqual(str(opt), 'one: One, two: Two')
def set_value(self, name, value, strict=True): name_parts = name.split('.', 1) prefix = name_parts[0] try: candidate = getattr(self, prefix) except KeyError: if strict: raise candidate = Option(name) setattr(self, prefix, candidate) candidate_type = type(candidate) if candidate_type == Namespace: candidate.set_value(name_parts[1], value, strict) else: candidate.set_value(value)
def __setattr__(self, name, value): if isinstance(value, (Option, Namespace, Aggregation)): # then they know what they're doing already o = value else: o = Option(name=name, default=value, value=value) super(Namespace, self).__setattr__(name, o)
def test_copy(self): o = Option( name='dwight', default=17, doc='the doc', from_string_converter=int, value=0, short_form='d', exclude_from_print_conf=True, exclude_from_dump_conf=True, is_argument=False, likely_to_be_changed=False, not_for_definition=False, reference_value_from='external.postgresql' ) o2 = o.copy() self.assertEqual(o, o2)
def test_copy(self): o = Option( name='dwight', default=17, doc='the doc', from_string_converter=int, value=0, short_form='d', exclude_from_print_conf=True, exclude_from_dump_conf=True, is_argument=False, likely_to_be_changed=False, not_for_definition=False, reference_value_from='external.postgresql', secret=True, ) o2 = o.copy() self.assertEqual(o, o2)
def test_set_default(self): o1 = Option('name', default=23) self.assertEqual(o1.value, 23) self.assertRaises(OptionError, o1.set_default, 68) o1.set_default(78, force=True) self.assertTrue(o1.value, 68) self.assertTrue(o1.default, 68) o2 = Option('name', default=None) self.assertTrue(o2.value is None) o2.set_default(68) self.assertTrue(o2.value, 68) self.assertTrue(o2.default, 68)
def test_add_option_returns_option(self): n = config_manager.Namespace() option = n.add_option('name', 'Peter') self.assertEqual(option.name, 'name') self.assertEqual(option.value, 'Peter') self.assertEqual(option, n['name']) # should work the same if you add an option straight o = Option('dwight') option = n.add_option(o) self.assertEqual(option, o)
def add_option(self, name, *args, **kwargs): """add an option to the namespace. This can take two forms: 'name' is a string representing the name of an option and the kwargs are its parameters, or 'name' is an instance of an Option object """ if isinstance(name, Option): an_option = name name = an_option.name else: an_option = Option(name, *args, **kwargs) current_namespace = self name_parts = name.split('.') for a_path_component in name_parts[:-1]: if a_path_component not in current_namespace: current_namespace[a_path_component] = Namespace() current_namespace = current_namespace[a_path_component] an_option.name = name_parts[-1] setattr(current_namespace, an_option.name, an_option)
def test_option_constructor_more_complex_default_converters(self): data = { 'default': '2011-12-31', 'doc': "lucy's bday", 'from_string_converter': dtu.date_from_ISO_string, } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, '2011-12-31') self.assertEqual(o.doc, "lucy's bday") self.assertEqual(o.from_string_converter, dtu.date_from_ISO_string) o.set_value() self.assertEqual(o.value, datetime.date(2011, 12, 31)) data = { 'default': '2011-12-31', 'doc': "lucy's bday", 'from_string_converter': 'configman.datetime_util.date_from_ISO_string', } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, '2011-12-31') self.assertEqual(o.doc, "lucy's bday") self.assertEqual(o.from_string_converter, dtu.date_from_ISO_string) self.assertEqual(o.value, '2011-12-31') o.set_value() self.assertEqual(o.value, datetime.date(2011, 12, 31))
def test_timedelta_converter_inOption(self): one_day = datetime.timedelta(days=1) opt = Option('some name', default=one_day) self.assertEqual(opt.default, one_day) self.assertEqual(opt.from_string_converter, timedelta_converter) two_days = datetime.timedelta(days=2) timedelta_as_string = timedelta_to_str(two_days) assert isinstance(timedelta_as_string, basestring) opt.set_value(timedelta_as_string) self.assertEqual(opt.value, two_days) opt.set_value(unicode(timedelta_as_string)) self.assertEqual(opt.value, two_days) opt.set_value(two_days) self.assertEqual(opt.value, two_days) self.assertRaises(CannotConvertError, opt.set_value, 'JUNK') self.assertRaises(CannotConvertError, opt.set_value, '0:x:0:0')
def test_set_default(self): o1 = Option( 'name', default=23 ) self.assertEqual(o1.value, 23) self.assertRaises(OptionError, o1.set_default, 68) o1.set_default(78, force=True) self.assertTrue(o1.value, 68) self.assertTrue(o1.default, 68) o2 = Option( 'name', default=None ) self.assertTrue(o2.value is None) o2.set_default(68) self.assertTrue(o2.value, 68) self.assertTrue(o2.default, 68)
def test_timedelta_converter_inOption(self): one_day = datetime.timedelta(days=1) opt = Option('some name', default=one_day) self.assertEqual(opt.default, one_day) self.assertEqual(opt.from_string_converter, conv.timedelta_converter) two_days = datetime.timedelta(days=2) timedelta_as_string = dtu.timedelta_to_str(two_days) assert isinstance(timedelta_as_string, basestring) opt.set_value(timedelta_as_string) self.assertEqual(opt.value, two_days) opt.set_value(unicode(timedelta_as_string)) self.assertEqual(opt.value, two_days) opt.set_value(two_days) self.assertEqual(opt.value, two_days) self.assertRaises(CannotConvertError, opt.set_value, 'JUNK') self.assertRaises(CannotConvertError, opt.set_value, '0:x:0:0')
def test_option_constructor_basics(self): o = Option('name') self.assertEqual(o.name, 'name') self.assertEqual(o.default, None) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, None) self.assertEqual(o.value, None) o = Option('lucy') self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, None) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, None) self.assertEqual(o.value, None) o = Option(u'spa\xa0e') self.assertEqual(o.name, u'spa\xa0e') self.assertEqual(o.default, None) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, None) self.assertEqual(o.value, None) data = { 'name': 'lucy', 'default': 1, 'doc': "lucy's integer" } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, 1) self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, 1) data = { 'name': 'lucy', 'default': 1, 'doc': "lucy's integer", 'value': '1' } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, 1) self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, '1') data = { 'name': 'lucy', 'default': '1', 'doc': "lucy's integer", 'from_string_converter': int } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, '1') self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, '1') o.set_value() self.assertEqual(o.default, '1') self.assertEqual(o.value, 1) data = { 'name': 'lucy', 'default': '1', 'doc': "lucy's integer", 'from_string_converter': int, } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, '1') self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, '1') data = { 'default': '1', 'doc': "lucy's integer", 'from_string_converter': int, } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, '1') self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, '1') d = datetime.datetime.now() o = Option('now', default=d) self.assertEqual(o.name, 'now') self.assertEqual(o.default, d) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, dtu.datetime_from_ISO_string) self.assertEqual(o.value, d) data = { 'default': '1.0', 'doc': "lucy's height", 'from_string_converter': float, } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, '1.0') self.assertEqual(o.doc, "lucy's height") self.assertEqual(o.from_string_converter, float) self.assertEqual(o.value, '1.0') o.set_value() self.assertEqual(o.default, '1.0') self.assertEqual(o.value, 1.0)
def test_reference_value_from(self): o1 = Option(name='fred', reference_value_from='external.postgresql') self.assertEqual(o1.reference_value_from, 'external.postgresql')
def test_boolean_converter_inOption(self): opt = Option('name', default=False) self.assertEqual(opt.default, False) self.assertEqual(opt.from_string_converter, conv.boolean_converter) opt.set_value('true') self.assertEqual(opt.value, True) opt.set_value('false') self.assertEqual(opt.value, False) opt.set_value('1') self.assertEqual(opt.value, True) opt.set_value('t') self.assertEqual(opt.value, True) opt.set_value(True) self.assertEqual(opt.value, True) opt.set_value(False) self.assertEqual(opt.value, False) opt.set_value('False') self.assertEqual(opt.value, False) opt.set_value('True') self.assertEqual(opt.value, True) opt.set_value('None') self.assertEqual(opt.value, False) opt.set_value('YES') self.assertEqual(opt.value, True) opt.set_value(u'1') self.assertEqual(opt.value, True) opt.set_value(u'y') self.assertEqual(opt.value, True) opt.set_value(u't') self.assertEqual(opt.value, True)
def test_set_value_from_other_option(self): o1 = Option('name') o1.set_value('Peter') o2 = Option('name') o2.set_value(o1) self.assertEqual(o2.value, None) o1 = Option('name', default='Your name here') o1.set_value('Peter') o2 = Option('name') o2.set_value(o1) self.assertEqual(o2.value, 'Your name here')
def _setup_auto_help(self): help_option = Option(name='help', doc='print this', default=False) self.definition_source_list.append({'help': help_option})
def test_option_constructor_basics(self): o = Option('name') self.assertEqual(o.name, 'name') self.assertEqual(o.default, None) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, None) self.assertEqual(o.value, None) o = Option('lucy') self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, None) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, None) self.assertEqual(o.value, None) o = Option(u'spa\xa0e') self.assertEqual(o.name, u'spa\xa0e') self.assertEqual(o.default, None) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, None) self.assertEqual(o.value, None) data = { 'name': 'lucy', 'default': 1, 'doc': "lucy's integer" } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, 1) self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, 1) data = { 'name': 'lucy', 'default': 1, 'doc': "lucy's integer", 'value': '1' } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, 1) self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, 1) data = { 'name': 'lucy', 'default': '1', 'doc': "lucy's integer", 'from_string_converter': int } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, 1) # converted using `int` self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, 1) data = { 'name': 'lucy', 'default': '1', 'doc': "lucy's integer", 'from_string_converter': int, } o = Option(**data) self.assertEqual(o.name, 'lucy') self.assertEqual(o.default, 1) self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, 1) data = { 'default': '1', 'doc': "lucy's integer", 'from_string_converter': int, } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, 1) self.assertEqual(o.doc, "lucy's integer") self.assertEqual(o.from_string_converter, int) self.assertEqual(o.value, 1) d = datetime.datetime.now() o = Option('now', default=d) self.assertEqual(o.name, 'now') self.assertEqual(o.default, d) self.assertEqual(o.doc, None) self.assertEqual(o.from_string_converter, dtu.datetime_from_ISO_string) self.assertEqual(o.value, d) data = { 'default': '1.0', 'doc': "lucy's height", 'from_string_converter': float, } o = Option('now', **data) self.assertEqual(o.name, 'now') self.assertEqual(o.default, 1.0) self.assertEqual(o.doc, "lucy's height") self.assertEqual(o.from_string_converter, float) self.assertEqual(o.value, 1.0)
def test_add_option_with_option(self): o = Option('dwight') n = config_manager.Namespace() n.add_option(o) self.assertTrue(o is n.dwight)
def test_write_with_imported_module_with_internal_mappings(self): import os from configman.tests.values_for_module_tests_1 import Alpha, foo d = { 'a': 18, 'b': 'hello', 'c': [1, 2, 3], 'd': { 'host': 'localhost', 'port': 5432, } } definitions = { 'os_module': os, 'a': 17, 'imported_class': Alpha, 'imported_function': foo, 'xxx': { 'yyy': Option('yyy', default=d) }, 'e': None, } required_config = Namespace() required_config.add_option( 'minimal_version_for_understanding_refusal', doc='ignore the Thottleable protocol', default={'Firefox': '3.5.4'}, ) cm = ConfigurationManager( [definitions, required_config], values_source_list=[], ) config = cm.get_config() s = StringIO() @contextlib.contextmanager def s_opener(): yield s cm.write_conf('py', s_opener) generated_python_module_text = s.getvalue() expected = """# generated Python configman file from configman.dotdict import DotDict from configman.tests.values_for_module_tests_1 import ( foo, Alpha, ) import os # the following symbols will be ignored by configman when # this module is used as a value source. This will # suppress the mismatch warning since these symbols are # values for options, not option names themselves. ignore_symbol_list = [ "Alpha", "DotDict", "foo", "os", ] # a a = 17 # e e = None # imported_class imported_class = Alpha # imported_function imported_function = foo # ignore the Thottleable protocol minimal_version_for_understanding_refusal = { "Firefox": "3.5.4" } # os_module os_module = os # Namespace: xxx xxx = DotDict() xxx.yyy = { "a": 18, "b": "hello", "c": [ 1, 2, 3 ], "d": { "host": "localhost", "port": 5432 } } """ self.assertEqual(generated_python_module_text, expected)