Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConfigParser Duplicate keys in python

Tags:

python

I am trying to extract duplicate values of options from a section using configparser. I have searched and tried with the solution provided here. With this, I am able to extract the values of the duplicate keys of a option section. But when I try to extract the name:value pair using the function configparser.items(), I do not get any value.

[server]
unix-user = ivmgr
root = 1
root = 2
root = 3

class MultiOrderedDict(OrderedDict):
    def __setitem__(self, key, value):
        if isinstance(value, list) and key in self:
            self[key].extend(value)
        else:
            super(OrderedDict, self).__setitem__(key, value)

config = ConfigParser.RawConfigParser(dict_type=MultiOrderedDict)
config.read(['1.conf'])
print config.get("server",  "unix-user")
print config.get("server",  "root")
['ivmgr']
['1', '2', '3']
>>> print config.items("server")
[]

I want to be able to extract the name:value pair either as a dict or tuples e.g { 'root':'1', 'root':'2', 'root':'3' }. I am using python 2.7. I know I can just create a dict or list of sets using root as the keys for all, but I may be having more number of duplicate keys inside the same section and I want a pythonic way of doing this.

Thank you.

like image 734
chingkhuba Avatar asked Oct 22 '25 14:10

chingkhuba


2 Answers

In Python 3.6.0, the dict type provides keys method can make the method sections working as normal. Currently I don't know why the redefinition is required here. The MultiOrderedDict looks like:

class MultiOrderedDict(OrderedDict):
    def __setitem__(self, key, value):
        if isinstance(value, list) and key in self:
            self[key].extend(value)
        else:
            super(OrderedDict, self).__setitem__(key, value)
    def keys(self):
        return super(OrderedDict, self).keys()
like image 52
robin Avatar answered Oct 24 '25 04:10

robin


Getting results in dictionary is not possible because of that your key is always 'root' and it is going to replace the previous value. You can use a simple trick instead of forcing to change the default functionality of ConfigParser:

results = [('root', v) for v in config.get("server",  "root")]

However, maybe it is better to change the settings. I do not know why you did not set a tuple as a value to 'root' in your settings file:

[server]
unix-user = ivmgr
root = (1, 2, 3)

This is working for me.

import ConfigParser
class M(dict):
    def __setitem__(self, key, value):
        if key in self:
            items = self[key]
            new = value[0]
            if new not in items:
                items.append(new)
        else:
            super(M, self).__setitem__(key, value)
cp = ConfigParser.ConfigParser(dict_type=M)
cp.read('x.settings')
print cp.get('server', 'root')
results = [('root', v) for v in cp.get("server",  "root")]
print results
like image 43
Abi M.Sangarab Avatar answered Oct 24 '25 05:10

Abi M.Sangarab