I've been looking at ConfigObj and I've run into a problem with validation and single element lists. Say I have a config specification that looks like the following:
config_specification = """[Data]
[[__many__]]
type = option('sense.xml')
transport = string
sensors = list
[[[Identifier]]]
type = option("name", "mac", "uuid")
adapter = string(default='')
name = string(default='')
file = string(default='')"""
Now that list can actually just be one element, or more than one. I can do more than one easily:
[Data]
[[primary]]
type = sense.xml
transport = $http
sensors = $virtual, $gpio, $adc
[[[Identifier]]]
type = name
name = VirtualRelay01
But the following is invalid. It won't convert it to a list of 1:
sensors = $virtual
I've tried a couple of variations. This one doesn't work
sensors = {$virtual}
Neither does this one:
sensors = [$virtual]
And if I do this, it gives me a list with two elements! One the empty string:
sensors = ($virtual,)
I have several of these sections and I've got them in a for loop. I apply them to classes that only take lists and I don't want to have to individually code all the special cases to add a list around those (not to mention, it fails validation).
For completeness, here is how I validate things:
cfg = ConfigObj(filename, configspec=config_specification.split('\n'))
test = cfg.validate(Validator())
valid = True
for (section_list, key, _) in flatten_errors(cfg, test):
if key is not None:
print('Invalid value for key {0} in section {1}'.format(key,', '.join(section_list)))
valid = False
else:
print('Section {0} failed validation'.format(', '.join(section_list)))
valid = False
if not valid:
exit(3)
I'm one of the current configobj developers. According to this unit test line, I'd expect sensors = $virtual,
to work the way you'd expect.
I'm not sure how I feel about ($virtual,)
returning a two-element list. That seems wrong. Probably worth opening an issue unless you can imagine a scenario where you actually anticipate wanting the implicit empty-string.