portable INI-file read/write extension for Python - any interest?

Warren Postma embed at geocities.com
Wed Feb 7 15:52:24 EST 2001


I happened to need a fast way to read and modify lot of ini files, and I
happened to not be on Windows, and so I adapted an existing a set of native
C routines to do INI files that I had lying around since the good old MS-DOS
days. (Thank you Charlie Beerman, wherever you are.)  I decided to gussy
them up, and wrap them up nicely for Python.  They are thread safe so if
you're writing an app that's half C and half Python, it's ideal, since you
wouldn't want to use two different buffered INI file libraries, one for your
C applications and another for your Python app (imagine the "cache
conflicts" you'd run into).

Now, for anyone already using Windows only, the win32api module has a simple
way to do this in native python, but then, it's not as fast.  Also, I might
write a 100% python version, so I can use the same ini file API when I want
to use Python on a platform where no C compiler is available.  I use INI
files a lot. Can you tell?

Here's a little code sample that I believe illustrates a "friendlier"
approach to INI files, more Python-esque that win32api:

import ini
filename='c:\\winnt\\system.ini'
for sec in ini.sections(filename):
    print '['+sec+']'
    for key,value in ini.getsection(filename,sec):
        print key,'=',value

I have compiled and tested it and have a pyd file for Windows available. It
is admittedly already superceded by win32api module's functions
"GetProfileVal",
and "SetProfileVal" however ugly those functions are ugly bare win32
wrappers. Also, I'm still not quite sure how to list all sections in a file,
given only the win32api module.

The only notable thing about my wrapper, and the INI functions I used are
that they only use stdio.h and string.h, and is portable anywhere you've got
a C compiler.

Anybody interested in it? I'll be putting it up at starship, once I get it
compiled on Linux, but I just thought someone else might have a use for it.

Here are some details on the API:

------------------------ ini.flush ------------------------
flush()
   -> Writes current INI file from memory to disk.
      Happens automatically when you read the next INI file.
  Example
     ini.flush()



------------------------ ini.get ------------------------
get(filename,section,item,default=None)
   -> Returns value, typically a string, unless an integer
      default value is provided.  If no default is specified,
      and no value is found, then None is returned.

  Sample "MYFILE.INI":
    [mainsection]
    item1=This is a string.
    item2=3

  Example:
    x = ini.get('myfile.ini', 'mainsection', 'item1')
    #x == 'This is a string.'
    x = ini.get('myfile.ini', 'mainsection', 'item2', -1)
    #x ==  3
    x = ini.get('myfile.ini', 'mainsection', 'item3' )
    #x ==   None

----------------------- ini.getsection ------------------------
getsection(filename,section)
   -> Returns entire section of an INI file as a list of
      (name,value) tuples

  Sample "MYFILE.INI":
    [mainsection]
    item1=This is a string.
    item2=3

  Example:
    pprint.pprint ( ini.getsection('myfile.ini', 'mainsection') )
    [ ('item1','This is a string'),
      ('item2','3') ]

----------------------- ini.sections ------------------------
sections(filename)
   -> Returns list of sections in the INI file as a list of
      strings.

  Sample "MYFILE.INI":
    [mainsection]
    item=X
    [anothersection]
    item=Y

  Example:
    print `ini.sections('myfile.ini')`
    [ 'mainsection', 'anothersection' ]

-----------------------  ini.set ------------------------

set(filename,section,item,value)
   -> Sets an ini file value in memory. Returns None.
      Raises exceptions on failure.
   -> if value is None, the item is DELETED from the ini file
   -> 'value' must be convertable to string via str(value)
   -> You must call ini.flush() to write all the changes at once,
      or changes will not be flushed until a different INI
      file is read.
  Example
     ini.set('myfile.ini', 'newsection', 'item3', 999 )

----------------------- (end) -----------------------


Will send a pre-release-zip of this to you on request. Will release and
announce once I compile Linux binaries. There's no use calling it portable
when I haven't written a gcc makefile yet! :-)


Warren Postma





More information about the Python-list mailing list