Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't **kwargs interpolate with python ConfigObj?

I'm using ConfigObj in python with Template-style interpolation. Unwrapping my config dictionary via ** doesn't seem to do interpolation. Is this a feature or a bug? Any nice workarounds?

$ cat my.conf
foo = /test
bar = $foo/directory

>>> import configobj
>>> config = configobj.ConfigObj('my.conf', interpolation='Template')
>>> config['bar']
'/test/directory'
>>> '{bar}'.format(**config)
'$foo/directory'

I'd expect the second line to be /test/directory. Why doesn't interpolation work with **kwargs?

like image 399
Jake Biesinger Avatar asked Jul 03 '12 15:07

Jake Biesinger


2 Answers

When unpacking the keyword argument, then a new object is created: of type dict. This dictionary contains the the raw-values of the configuration (no interpolation)

Demonstration:

>>> id(config)
31143152
>>> def showKeywordArgs(**kwargs):
...     print(kwargs, type(kwargs), id(kwargs))
...
>>> showKeywordArgs(**config)
({'foo': '/test', 'bar': '$foo/directory'}, <type 'dict'>, 35738944)

To resolve your problem you could create an expanded version of your configuration like this:

>>> expandedConfig = {k: config[k] for k in config}
>>> '{bar}'.format(**expandedConfig)
'/test/directory'

Another more elegant way is to simply avoid unpacking: This can be achieved by using the function string.Formatter.vformat:

import string
fmt = string.Formatter()
fmt.vformat("{bar}", None, config)
like image 145
gecco Avatar answered Nov 08 '22 09:11

gecco


I have had a similar problem.

A workaround is to use configobj's function ".dict()". This works because configobj returns a real dictionary, which Python knows how to unpack.

Your example becomes:

>>> import configobj
>>> config = configobj.ConfigObj('my.conf', interpolation='Template')
>>> config['bar']
'/test/directory'
>>> '{bar}'.format(**config.dict())
'/test/directory'
like image 2
TomK Avatar answered Nov 08 '22 09:11

TomK