Persuading ConfigParser to give me the section elements in the same order as the file
Matimus
mccredie at gmail.com
Wed Sep 10 19:26:37 EDT 2008
On Sep 10, 1:52 pm, geoffbache <geoff.ba... at jeppesen.com> wrote:
> Hi all,
>
> I recently needed to parse a file that was perfect for ConfigParser
> apart from one thing: the elements in the sections, although
> definitions, could in some cases clash with each other and therefore
> it was important to be able to retrieve them in the same order as they
> appeared in the file.
>
> Unfortunately ConfigParser uses ordinary dictionaries for the section
> elements and they are therefore returned in an arbitrary order.
>
> The only solution I found was to copy ConfigParser.py and replace all
> the dictionaries with "sequential dictionaries"
> which are exactly like dictionaries except that elements are returned
> in the order they were inserted. (seehttp://home.arcor.de/wolfgang.grafen/Python/Modules/seqdict/Seqdict.html)
>
> I wonder if there was a better way? For example, is there any hook
> that could modify what is created by the statement
>
> x = {}
>
> I tried setting
>
> __builtins__.dict = ndict.seqdict
>
> But that didn't seem to have any effect on the above statement.
>
> As a secondary question, I find sequential dictionaries to be an
> essential part of programming in Python and I use them all the time. I
> wondered a bit if there were any plans or proposals to include them as
> part of the Python library?
>
> Regards,
> Geoff Bache
Have a look at this: http://www.python.org/dev/peps/pep-0372/
Looking at the config parser module, it looks like there are only a
couple of places where {} is used. I would create a mixin class to
replace the offending methods. That should work because it looks like
you only have to replace "__init__" and "add_section". So...
class OrderedConfigParserMixin:
def __init__(self, defaults=None):
self._sections = ndict.seqdict()
self._defaults = ndict.seqdict()
if defaults:
for key, value in defaults.items():
self._defaults[self.optionxform(key)] = value
def add_section(self, section):
"""Create a new section in the configuration.
Raise DuplicateSectionError if a section by the specified name
already exists.
"""
if section in self._sections:
raise DuplicateSectionError(section)
self._sections[section] = ndict.seqdict()
# Then you can use this to create your own ordered config parsers.
Note that
# multiple inheritance in python uses a breadth first search. If you
want
# the methods on your mixin to get called instead of the methods on
the
# original class you must include the mixin first.
from ConfigParser import RawConfigParser, ConfigParser,
SafeConfigParser
class OrderedRawConfigParser(OrderedConfigParserMixin,
RawConfigParser):
pass
class OrderedConfigParser(OrderedConfigParserMixin, ConfigParser):
pass
class OrderedSafeConfigParser(OrderedConfigParserMixin,
SafeConfigParser):
pass
I don't know if this is the _best_ approach, but it is certainly much
preferred over monkey patching the built-ins module. Note that I
haven't tested any of the above code.
Matt
More information about the Python-list
mailing list