ConfigParser: buggy or just a mess?

M

Martin Maney

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>
 
D

David Goodger

Martin said:
> 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.]

If you can write it better, doc patches are welcome!
> <transcript from interactive session>
> Python 2.2.1 (#1, Sep 7 2002, 14:34:30)

Before complaining, check the latest version to see if the bug has
already been fixed:

Python 2.3 (#2, Jul 30 2003, 11:45:28)
[GCC 3.1 20020420 (prerelease)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from ConfigParser import ConfigParser
>>> cp = ConfigParser()
>>> cp.readfp(open('conf'))
>>> cp.options('test') ['a', 'b']
>>> cp.has_option('test', 'a') True
>>> cp.has_option('test', 'b')
True

Here's my "conf" file (next time, please include your data too):

[test]
a = 1

[DEFAULT]
b = 2
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top