How to ConfigParse a file keeping multiple values for identical keys?
The accepted answer breaks config.sections()
, it returns always an empty list (tested with Python 3.5.3). Replacing super(OrderedDict, self).__setitem__(key, value)
by super().__setitem__(key, value)
fixes this, but now config.get(section, key)
returns a concatenated string, no longer a list of strings.
My solution is:
class ConfigParserMultiValues(collections.OrderedDict):
def __setitem__(self, key, value):
if key in self and isinstance(value, list):
self[key].extend(value)
else:
super().__setitem__(key, value)
@staticmethod
def getlist(value):
return value.split(os.linesep)
config = configparser.ConfigParser(strict=False, empty_lines_in_values=False, dict_type=ConfigParserMultiValues, converters={"list": ConfigParserMultiValues.getlist})
...
values = config.getlist("Section", "key") # => ["value1", "value2"]
The config INI file accepts duplicate keys:
[Section]
key = value1
key = value2
After a small modification, I was able to achieve what you want:
class MultiOrderedDict(OrderedDict):
def __setitem__(self, key, value):
if isinstance(value, list) and key in self:
self[key].extend(value)
else:
super(MultiOrderedDict, self).__setitem__(key, value)
# super().__setitem__(key, value) in Python 3
config = ConfigParser.RawConfigParser(dict_type=MultiOrderedDict)
config.read(['a.txt'])
print config.get("test", "foo")
print config.get("test", "xxx")
Outputs:
['value1', 'value2']
['yyy']
in python 3.8 you need to also add strict=False
:
class MultiOrderedDict(OrderedDict):
def __setitem__(self, key, value):
if isinstance(value, list) and key in self:
self[key].extend(value)
else:
super().__setitem__(key, value)
config = ConfigParser.RawConfigParser(dict_type=MultiOrderedDict, strict=False)
config.read(['a.txt'])
print config.get("test", "foo")
print config.get("test", "xxx")