'configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: '%s %s'

I am trying to read from ini file and replace it with os environment variables.

My ini file:

[svc1]
host=%(TEST_IP)s
port=%(TEST_PORT)s
database=test_db
user=test
connect_timeout=3

My python file:

from configparser import ConfigParser
import os

print(os.environ['TEST_IP'])
print(os.environ['TEST_PORT'])
parser = ConfigParser(os.environ)
parser.read('test.ini')
print(parser.items('svc1'))

Output:

192.168.1.1
8080
Traceback (most recent call last):
  File "test.py", line 8, in <module>
    print(parser.items('svc1'))
  File "/usr/lib/python3.8/configparser.py", line 859, in items
    return [(option, value_getter(option)) for option in orig_keys]
  File "/usr/lib/python3.8/configparser.py", line 859, in <listcomp>
    return [(option, value_getter(option)) for option in orig_keys]
  File "/usr/lib/python3.8/configparser.py", line 855, in <lambda>
    value_getter = lambda option: self._interpolation.before_get(self,
  File "/usr/lib/python3.8/configparser.py", line 395, in before_get
    self._interpolate_some(parser, option, L, value, section, defaults, 1)
  File "/usr/lib/python3.8/configparser.py", line 442, in _interpolate_some
    raise InterpolationSyntaxError(
configparser.InterpolationSyntaxError: '%' must be followed by '%' or '(', found: '%s %s'

What am I doing wrong here?

My python version: Python 3.8.10



Solution 1:[1]

Python treats the % character differently, when part of the contents of a string can cause this issue.

As per the helpful Python error message (see traceback) rather than escape it, just double it within your original string to %%

A useful way to obfuscate plain text passwords from prying eyes!

FYI configparser.py also does not like the # standard comment character

or empty values so I use = []

As mentioned here:

https://github.com/mobeigi/fb2cal/issues/37

https://github.com/flakshack/pyPerfmon/issues/1

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 social