Search code examples
pythonpython-3.6configparser

Usage of ConfigParser.setdefault()


I am trying to set default values on an instance of configparser.ConfigParser after its instantiation. While inspecting the instance I found the method ConfigParser.setdefault():

Help on method setdefault in module collections.abc:

setdefault(key, default=None) method of configparser.ConfigParser instance
    D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D

While this is not very helpful at all, the official documentation does not even mention this public method.

So I started just to try-and-error:

>>> cp.setdefault('asd', 'foo')
<Section: asd>
>>> cp['asd']
<Section: asd>
>>> cp['asd']['foo']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/configparser.py", line 1233, in __getitem__
    raise KeyError(key)
KeyError: 'foo'
>>> cp['foo']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/configparser.py", line 959, in __getitem__
    raise KeyError(key)
KeyError: 'foo'
>>> cp.setdefault('asd', {'foo': 'bar'})
<Section: asd>
>>> cp['asd']
<Section: asd>
>>> cp['asd']['foo']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/configparser.py", line 1233, in __getitem__
    raise KeyError(key)
KeyError: 'foo'
>>> cp['foo']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/configparser.py", line 959, in __getitem__
    raise KeyError(key)
KeyError: 'foo'
>>> 

But I could not figure out how to initialize a default section 'asd' with a default key 'foo' with value 'bar'.

So my questions are:

  1. What is the method ConfigParser.setdefault() for?
  2. How can I set defaults on my ConfigParser's instance after its initialization?

Update
After some further investigation it turned out that ConfigParser.setdefault() is inherited from _collections_abc.MutableMapping.


Solution

  • ConfigParser.setdefault has nothing to do with setting the ConfigParser's defaults. If you want to set defaults, use the DEFAULT section, which provides defaults for other sections:

    cp['DEFAULT']['key'] = 'value'
    

    or if you configured a different default_section, use whatever you configured.

    As described in the docs,

    configparser objects behave as close to actual dictionaries as possible. The mapping interface is complete and adheres to the MutableMapping ABC. However, there are a few differences that should be taken into account:

    [list of differences, none of which involve setdefault]

    setdefault is one of the operations specified by MutableMapping. cp.setdefault('asd', 'foo') attempts to set cp['asd'] = 'foo' if there is no entry for cp['asd'], then returns cp['asd'].

    In a ConfigParser, an entry for cp['asd'] would be an 'asd' section, and it is not legal to set cp['asd'] = 'foo'. It is legal to set cp['asd'] to a mapping, but you already had a cp['asd'] section, so your cp.setdefault('asd', {'foo': 'bar'}) call didn't do anything either.