ConfigObj in Bazaar

emoticon:envelope A couple (or so) of pieces of ConfigObj related news.

I've just discovered that ConfigObj is in bazaar 0.6 (the Python distributed VCS). It's used to read bazaar.conf and branches.conf.

This is a high profile project - so it's nice to see ConfigObj being used.

http://bazaar-ng.org/bzr/bzr.dev/NEWS

ConfigObj continues to be pretty popular - ConfigObj and pythonutils (which contains ConfigObj) get at least ten downloads a day via voidspace [1]. Based on my own habits I use about one in thirty of the interesting code/projects that I download. That means a new user every three days.

I've also just received and squashed a bug report. There was a bug in the walk section method - if you use walk to change member names. It's now fixed. Smile

It's highlighted a nice use-case for walk, which I wasn't sure if anyone would use at all. You can create a template config file with placeholders in names and values. When you need to create a new config file (E.g. to add a new user to an application) you can use walk to replace the placeholders with appropriate values in member names, section names, and values.

# We use 'XXXX' as a placeholder
# config is our template config file
config = '''
XXXXkey1 = XXXXvalue1
XXXXkey2 = XXXXvalue2
XXXXkey3 = XXXXvalue3
[XXXXsection1]
XXXXkey1 = XXXXvalue1
XXXXkey2 = XXXXvalue2
XXXXkey3 = XXXXvalue3
[XXXXsection2]
XXXXkey1 = XXXXvalue1
XXXXkey2 = XXXXvalue2
XXXXkey3 = XXXXvalue3
    [[XXXXsection1]]
    XXXXkey1 = XXXXvalue1
    XXXXkey2 = XXXXvalue2
    XXXXkey3 = XXXXvalue3
'''
.splitlines()
    #
    # create a config object
    # normally we'd read from a file to do this
cfg = ConfigObj(config)
#
# this is our function that does replacement
# in the config file
def transform(section, key):
    val = section[key]
    # change the member name
    newkey = key.replace('XXXX', 'CLIENT1')
    section.rename(key, newkey)
    if isinstance(val, (tuple, list, dict)):
        pass
    else:
        # change the value - only if it isn't
        # a section (dict) or a list value
        val = val.replace('XXXX', 'CLIENT1')
        section[newkey] = val
#
cfg.walk(transform, call_on_sections=True)
print cfg
{'CLIENT1key1': 'CLIENT1value1', 'CLIENT1key2': 'CLIENT1value2',
'CLIENT1key3': 'CLIENT1value3',
'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1',
    'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'},
'CLIENT1section2': {'CLIENT1key1': 'CLIENT1value1',
    'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3',
    'CLIENT1section1': {'CLIENT1key1': 'CLIENT1value1',
        'CLIENT1key2': 'CLIENT1value2', 'CLIENT1key3': 'CLIENT1value3'}}}
# all the occurences of 'XXXX' have been changed

(Thanks to M. Gehling for the bug report).

I've added an istrue section method. This will fetch string values as booleans. The following are interpreted as True (not case sensitive) :

true, yes, on, 1

The following are False :

false, no, off, 0

Anything else raises a ValueError.

We have also finally [2] resolved the issue with list_values=False. This is when ConfigObj doesn't parse values as list values. Previously when unquoting it could do the wrong thing. The quoting and unquoting was also causing a user some problems.

I've settled on a behaviour which solves both problems in one go. There is now a note in the docs which explains it :

The list_values attribute [and option] is True or False. If set to False then values are not parsed for list values. In addition single line values are not unquoted.

This allows you to do your own parsing of values. It exists primarily to support the reading of the configspec - but has other use cases.

For example you could use the LineParser from listquote to read values for nested lists.

Single line values aren't quoted when writing - but multiline values are handled as normal.

Caution!

Because values aren't quoted when writing, leading or trailing whitespace can be
lost.

This behaviour was changed in version 4.0.1.

Prior to this, single line values might have been quoted; even with list_values=False. This means that files written by ConfigObj could now be incompatible - and need the quotes removing by hand.

These changes are in the ConfigObj 4.0.1 release.


[1]Plus more from PyPi, sourceforge, gentoo-portage, etc. Very Happy
[2]Well I hope finally, so long as no-one objects to the change. Neutral

Posted by Fuzzyman on 2005-11-05 23:36:14.
Categories: Python
Visit the Voidspace Techie Blog to read this entry and more.