ANN: New configuration module released

Vinay Sajip vinay_sajip at
Wed Nov 10 10:29:39 CET 2004

Michael Foord wrote:

> ConfigObj (here we go...) my config file parser, if called with just a
> filename, parses everything in the config file and presents the
> results as a dictionary. That means you can add config file support
> with basically 1 line of code (plus the import statement). This is
> particularly useful for small admin scripts where you write the config
> files yourself - speed and simplicity over flexibility.

I agree that speed and simplicity are important, and if you can get them 
without sacrificing flexibility, even better. I looked at ConfigObj, and 
I would summarise the advantages of the config module I released over 
ConfigObj as follows. It shares the following features which you find 
desirable (from the ConfigObj documentation):

* Ease of use - dictionary like access
* Multiple (list) values for keywords
* Easy to create, modify and write files
* Human readable
* Comments are preserved
* Quoting is optional [where unambiguous]
* Powerful set of options for parsing and writing

It also has the following additional features (apologies if ConfigObj 
offers them too, I'm going by the documentation):

* There's no limit on the level of nesting of lists or mappings. One of 
my main problems with ConfigParser is the limited depth of 2 levels - 
sections and keys. This is where I found ConfigObj too limiting, too.
* Easy access to real Python objects such as sys.stderr or logging.DEBUG 
  or values from modules in the application using the config module.
* Good support for value substitution and value sharing.
* Access via attribute notation (a.b) as well as dictionary notation 
* There's no need for special quoting (like &mjf-quot; and &mjf-lf;). 
Triple-quoted and raw strings are not (yet) supported, but you can use 
single or double quotes and escape characters inside the string.
* Good integration with optparse.
* Defaults can be handled using ConfigList, which allows looking through 
a list of configurations and returns a value from the first 
configuration which defines one.
* Support for merging configurations (not an especially common use case) 
and including configurations held in separate files (this use case is 
more common).
* You can access a value through a path: cfg.a.b[3].c['d e'] is 
equivalent to cfg.getByPath("a.b[3].c['d e']"). This is useful where 
paths are constructed dynamically in the application, rather than 
hard-coded. (For example, using sys.platform in the path to get 
platform-dependent values.)
* Can easily handle remote configurations - you simply provide your own 
stream opener, e.g. urllib2.urlopen().

Conversely, there is no schema-like support in my module, which 
ConfigObj offers through configspecs. I could, of course, add it later 
if I felt it necessary. The reason I don't provide schemas is that I 
haven't felt it necessary for application configuration, though of 
course if makes perfect sense to use them in data-exchange applications 
(for which XML is often better, anyway). By not providing a schema, the 
main thing users have to deal with is missing values or values which are 
of the wrong type. To my mind, roughly the same amount of work is 
required to deal with this as with handling exceptions thrown by a 
schema validation layer; especially as a schema cannot always catch 
semantic errors in the data.

Best Regards,

Vinay Sajip

More information about the Python-list mailing list