Search code examples
pythonkeyword-argumentconfigobj

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?


Solution

  • 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)