Search code examples
pythonvalidationconfigobj

ConfigObj and single element lists


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)

Solution

  • 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.