When you validate a configuration configobj can tell you which options or sections in the configuration weren’t in your configspec this can be useful for finding errors in the user’s configuration when specifying optional values (presumably option-name misspellings).
config_spec = """
[TEST]
option_1 = integer
[[SUBTEST]]
option_2 = integer
""".splitlines()
configspec = ConfigObj(config_spec,
list_values=False,
_inspec=True)
config = """
extra = option
[TEST]
option_1 = 1
option_3 = 3
[[SUBTEST]]
option_2 = 2
option_4 = 4
[[SUBTEST2]]
option_5 = 5
[[[SUBSUBTEST]]]
option_6 = 6
""".splitlines()
configuration = ConfigObj(config,
configspec=configspec)
validator = Validator()
outcome = configuration.validate(validator)
assert outcome
Now the extra values.
for sections, option in get_extra_values(configuration):
print sections, option
() extra
('TEST',) option_3
('TEST',) SUBTEST2
('TEST', 'SUBTEST') option_4
According to the documentation, the return value for get_extra_values is a list of tuples. looking at the output it appears they are of the form ((section, subsection), option), with the subsection being empty for the top-section. The sub-sections also appear to only go one deep so it isn’t a tree going all the way to the leaves. .. ‘
This is the way the documentation suggests getting the values.
def process_extras(configuration, verbose=True):
had_extras = False
for sections, name in get_extra_values(configuration):
had_extras = True
bottom_section = configuration
for section in sections:
bottom_section = bottom_section[section]
value = bottom_section[name]
item_type = 'Value'
if isinstance(value, dict):
item_type = 'Section'
section = ','.join(sections) or 'top level'
if verbose:
message = "Extra entry in '{0}' section. {1}: '{2}'".format(section,
item_type,
name)
if item_type == 'Value':
message += '= {0}'.format(value)
print message
return had_extras
process_extras(configuration)
Extra entry in 'top level' section. Value: 'extra'= option
Extra entry in 'TEST' section. Value: 'option_3'= 3
Extra entry in 'TEST' section. Section: 'SUBTEST2'
Extra entry in 'TEST,SUBTEST' section. Value: 'option_4'= 4
While printing this information is useful, I think it would be useful to check if there actually were extra values. What happens when the configuration doesn’t have extra values? ..’
config_2 = """
[TEST]
option_1 = 2
[[SUBTEST]]
option_2 = 1
""".splitlines()
configuration_2 = ConfigObj(config_2,
configspec=configspec)
had_extras = process_extras(configuration_2, False)
print "There were extras in the second configuration: {0}".format(had_extras)
print "There were extras in the first configuration: {0}".format(process_extras(configuration, False))
There were extras in the second configuration: False
There were extras in the first configuration: True
So it looks like all you have to do is see if get extra_values puts anything in the returned list.
extra_1 = get_extra_values(configuration)
extra_2 = get_extra_values(configuration_2)
print extra_1
print len(extra_1)
print extra_2
print len(extra_2)
[((), 'extra'), (('TEST',), 'option_3'), (('TEST',), 'SUBTEST2'), (('TEST', 'SUBTEST'), 'option_4')]
4
[]
0