Extra Values ============ 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). Getting Extra Values -------------------- :: 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. .. ' Getting the Values ------------------ 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 No Missing Values ----------------- 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