views:

31

answers:

3

I'd like to use both parse time and runtime interpolation for values of a configobj configuration file. The easiest way to do simple string interpolation in Python is "%(foo)s" % somedict. Unfortunately configobj uses the same interpolation mechanism and I have not yet found a way to escape it. Ideally my value would look like:

othervar = foo
someconfigobjkey = %(othervar)s %%(runtimevar)s

However configobj tries (and fails) to replace the second variable. Another way to answer this question is to provide a different (configobj) way to do both parse time and runtime interpolation.

+1  A: 

New version of the answer:

You could use "".format() (Python 2.6 or above) or string.Template (Python 2.4 or above) for the runtime interpolation -- both of which would eliminate the conflict.

(The old version assumed the use of the standard ConfigParser module, hence the comments.)

Sven Marnach
As I stated in my initial question I use configobj and not ConfigParser. Maybe I assumed this module to be known too far anyway it can be found at http://www.voidspace.org.uk/python/configobj.html.
Helmut
Sorry, I did not know that module and did not recognize it as a module name in your post either. Any reason not to just use the standard ConfigParser module? If this would do for you as well, the problem would also be solved :)
Sven Marnach
In corporate development choice of tools is not always given.
Helmut
Maybe you could use string.Template or "".format() instead of % substitution for the tuntime interpolation -- this would eliminate the conflict.
Sven Marnach
Your last proposal makes up a full new answer, that works as well as `interpolation="template"`.
Helmut
+1  A: 

Yes, unfortunately configobj does not follow normal standard Python formatting rules, so %%, which would otherwise be the correct way to escape a percent sign, fails. Seems like a bit of a design flaw to me.

The only way I can think of to have a literal %(foo)s sequence in a configobj value would be to ensure part of that sequence is itself generated by a replacement:

>>> import configobj
>>> c= configobject.ConfigObj()
>>> c['foo']= 'bar'
>>> c['pc']= '%'
>>> c['v']= '%(foo)s %(pc)s(foo)s'
>>> c['v']
'bar %(foo)s'
bobince
A: 

Digging deeper in the documentation I found a solution that fits better than the one proposed by bobince: Use a different interpolation engine, such as interpolation="template". It has two advantages.

  1. Does not interfere with % signs.
  2. Supports escaping. ($$ gets interpolated to $.)

The example would look like:

othervar = foo
someconfigobjkey = $othervar %(runtimevar)s
Helmut