ConfigParser: buggy or just a mess?

Martin Maney maney at pobox.com
Fri Oct 24 15:29:40 EDT 2003


Summary: with batteries like these, get a longer extension cord?

[most of this was written before I came across the brief explanation on
the wiki, which did more to explain ConfigParser than everything in the
official documentation, while inspiring the executive summary above.]

<transcript from interactive session>
Python 2.2.1 (#1, Sep  7 2002, 14:34:30) 
[GCC 2.95.4 20011002 (Debian prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ConfigParser import ConfigParser
>>> cp = ConfigParser()
>>> cp.readfp(open('room118-machines'))
>>> cp.options('C 1')
['mac', 'type', 'prefix']
>>> cp.get('C 1','type')
'workstation'
>>> cp.defaults()
{'prefix': 'lab118', 'type': 'workstation'}
>>> cp.has_option('C 1','type')
0
>>> cp.get('C 1','type')
'workstation'
>>> cp.has_option('LAYOUT','type')
0
>>> cp.get('LAYOUT','type')
'workstation'
</transcript>

In all cases has_option is, strictly speaking, correct: neither 'C 1'
nor 'LAYOUT' sections have a type option defined.  I had been expecting
the DEFAULT options to appear as if present, based on memory and a spot
of seeing what it actually did (1); it was later, in incorporating a
ConfigParser into a larger context that I discovered this
onconsistency.  On rereading, I can't say that the documentation helps
to clear this up: it neither requires nor, I think, prohibits either
get() or has_option()'s view of the section.

[oops, I forgot to mention options(), which seems to share get's
inclusive view of the section.]

<never mind>
So before I waste any more time guessing, does anyone know what
ConfigParser is *supposed* to be doing with respect to options defined
in the DEFAULT section but not in [some] data sections?  The docs only
seem to require that the defaults be available for use in
interpolations, and don't (that I can see) offer any guidance as to
which of has_option/get is "right".  Or are they in fact supposed to be
inconsistent - I can see a half-witted plan to that, where has_option()
reports what actually appeared int he file but get() lies by adding
defaults to save one from needing to pick those up manually.  If that's
the intent then it really ought to be spelled out.
</never mind>

It turns out that I can work around this quirky behavior quite easily,
at least for the part of the project I'm working on now.  But as I've
learned more about ConfigParser, I've become less and less inclined to
want to rely on it (this code ought to be useful for many years when
it's done, so the cost of working around whatever ConfigParse does in
the next version I want to run it on is... probably not large, but it
feels like those broken windows the XP guys talk about).


(1) a quick test in the interctive shell is great, but when the docs
and code are as quirky as in this case, it's more like a waste of time. 
I've now spent more time trying to divine what ConfigParser is supposed
to do than I expect it would have taken to define and implement a more
task-specific parser; and now I find the quite apt descripition in the
wiki which warns us off from using ConfigParser in any but throwaway
code since "... the implementation has been changed in almost every
Python release ..."  Pity, it would be a very handy facility if it
didn't promise to be more of a maintenance headache.  <sigh>

-- 
Trouble rather the tiger in his lair than the sage among his books.
For to you kingdoms and their armies are things mighty and enduring,
but to him they are but toys of the moment,
to be overturned with the flick of a finger. --  Gordon Dickson




More information about the Python-list mailing list