From: mso at jimpick.com (Mike Orr)
Date: Sat, 10 Apr 1999 00:47:25 GMT
Subject: ConfigParser module and alternatives (flad, flan)
References: <19990331160323.21601.00000471@ng-fi1.aol.com> <7du3ab$3ag@chronicle.concentric.net> <jtaewsfmlj.fsf@wazor.biostat.wisc.edu>
Message-ID: <xcxP2.1302$rd2.27684@news14.ispnews.com>
Content-Length: 4282
X-UID: 530                                                  

William Annis <annis at biostat.wisc.edu> wrote:
>> As one of many people whose grimy hands have touched this module---and 
>> potentially the only person known to Guido who USES it, I can only say this.

I use ConfigParser to parse the data files in a Mad Lib CGI program.
See it at http://mso.oz.net/python/madbibs/
(When I add/change a story, I run a script that parses the files,
creates the HTML, and stores the preprocessed data structures in a 
cPickle file for the CGI script.)

I'm not sure if I'll use ConfigParser for the next version.  I don't
really need the sections (multiple files work just fine, using the filename
for the section name), and I haven't found a use for the the %(other_key)s
substitutions.  On the other hand, it doesn't handle multiple values (the
same key repeated within a record), which I sometimes need.

Attached is a wrapper class for ConfigParser which supports booleans
and can also return an entire section as a dictionary (or all the sections
as nested dictionaries).  I find these make it a little more convenient.

I have a home-grown module flan.py that I use for most parsings.  It's
loosely based on Flad, but with a different approach.  Rather than
returning dictionaries, it returns a list (each record) of lists (each
field) of triples (key, value, linno).  Of course, it requires more code
in the calling program to move the records in and out of objects.  But
it allows more flexibility, because the calling program can decide
whether to allow multiple values (duplicate keys), can remember the
original order of the keys if desired, and, if there's a data error
parsing a particular field (e.g., a certain number must be between 1 and
100), it can put the file's line number in the exception string.
[I'd like to figure out how to print the original line with the caret
indicating the position of the error, a la SyntaxError, but haven't
succeeded yet.]  Flan doesn't handle sections or %(other_key)s
substitutions, but it does know how to write files (without comments
at this point).  It's a bit too long to post, but I can send it to
anybody who's interested.

################### BEGIN ConfigParser2.py ######################
"""ConfigParser2.py -- wrapper for ConfigParser with additional features.

Differences from the original ConfigParser class:

* The *getboolean* method accepts symbolic words as well as '1' or '0'.
Anything beginning with 't' or 'y' means '1' (true/yes).  Anything
beginning with 'f' or 'n' is accepted as '0' (false/no).  Case is insignificant.

* New method *options_dict*(section) returns a copy of the dictionary
corresponding to that direction WITH THE DEFAULTS ADDED TO IT.

* New method *sections_dict*() returns a dictionary containing each section,
with the default section under the key 'DEFAULT'.  The other sections do NOT
contain copies of the entries from the default section.

These methods do not resolve %(key)s interpolations: you must do that yourself.

Testing status: Tested getboolean, options_dict, sections_dict 23-JAN-1999.
Module written by Mike Orr, mso at jimpick.com, 23-JAN-1999.  Public domain.
"""
import ConfigParser;  _cp = ConfigParser;  del ConfigParser
import string

class ConfigParser(_cp.ConfigParser):
	def getboolean(self, section, option):
		v = self.get(section, option)
		val = string.strip(v)
		val = string.lower(v[0:1])
		if   val in ('1', 't', 'y'):
			return 1
		elif val in ('0', 'f', 'n'):
			return 0
		raise ValueError, 'Not a boolean: %s' % v

	def options_dict(self, section):
		ret = self._ConfigParser__defaults.copy()
		if section == _cp.DEFAULTSECT:
			return ret
		try:
			section_dict = self._ConfigParser__sections[section]
		except KeyError:
			raise _cp.NoSectionError(section)
		ret.update(section_dict)
		return ret

	def sections_dict(self):
		ret = { 'DEFAULT': self._ConfigParser__defaults.copy() }
		ret.update(self._ConfigParser__sections)
		return ret
########### END ConfigParser2.py #####################################

> -- 
> William Annis - System Administrator - Biomedical Computing Group
> (608) 263 8625     annis at biostat.wisc.edu    PGP ID:1024/FBF64031
> Mi parolas Esperanton - La Internacia Lingvo    www.esperanto.org

Saludon, William.  Ankaux mi parolas Esperanton.

-- 
-Mike Orr, mso at jimpick.com




