ConfigParser shootout, preliminary entry

David Wilson dw at botanicus.net
Sat Oct 23 11:06:49 EDT 2004


On Sat, Oct 23, 2004 at 10:46:24AM -0400, Peter Hansen wrote:

> Ah, there's the conflict.  For the simpler stuff I'm picturing, I
> don't have a *separate* parser which serves solely to read the file
> and return the information therein in a form that requires a different
> object to preserve and provide later access to it.  I bundle those
> babies together so, in my mind and despite seeing the name and reading
> your various comments repeatedly, it wasn't clear to me that we were
> implicitly (?) leaving out all other issues of configuration, leaving
> only the tiny parsing bit.
> 
> My apologies for misunderstanding your point.

No problem. ;)


For your first statement, IMHO the attribute access pattern isn't all
that useful anyway, unless you are explicitly working in strings. Here's
a wee example:

    self._listen_port = 12345
    ....

    try:
        self._listen_port = int(config.general.listen_port)
    except ValueError, e:
        raise Error("listen port is invalid")

    if self._listen_port <= 1024 or self._listen_port > 65535:
        raise Error("listen port is not in valid range")

    ....

Assuming your config object doesn't contain a bug and throws ValueError
itself by accident, here is a small snippet that catches all possible
errors for reading some TCP/UDP port number while specifying a default.

Loot at the same again, this time without using attribute access:

    self._listen_port = 12345
    ....


    for key, value in self._conf.items('general'):
        if key == 'listen port': # no need for ugly underscore
            try:
                value = int(value)
            except ValueError, e:
                raise Error("listen port is invalid")

            if value <= 1024 or value > 65535:
                    raise Error("listen port is not in valid range")
            self._listen_port = value
        elif key == ....


What can we say about the above?

    - The try block is much more specific (no magic code underneath).
    - Application initialisation does not begin until your config read /
      validate phase has completed.
    - It naturally pushes you into grouping code belonging to the same
      category (ie. conf.items('general')).

Regardless of your config system, for the above reasons I would not use
attribute style config representation anyway and prefer an explicit
load/validate/parse phase. Otherwise, lazy reading of the values leads
to deep ugly unreadable tracebacks in remote parts of your application.

I think this is swaying a little off-topic, but my 2c anyway. :)



David.

-- 
Making the simple complicated is commonplace;  making the complicated
simple, awesomely simple, that's creativity.
    -- Charles Mingus (1922-1979), Musician and composer



More information about the Python-list mailing list