diff options
author | grabner <pjg.github@ubergrabner.net> | 2016-12-14 11:44:40 -0500 |
---|---|---|
committer | grabner <pjg.github@ubergrabner.net> | 2016-12-14 11:44:40 -0500 |
commit | cfcc9cefcdd74670e2871a869d0eceb364d89366 (patch) | |
tree | bc2f0f6741e0476fe599cda02d8fbbc39d385b4a | |
parent | 0bbdcee2745a7dc7208063e779275c49fb079545 (diff) | |
download | iniherit-cfcc9cefcdd74670e2871a869d0eceb364d89366.tar.gz |
added "%(ENV)s" interpolation support
-rw-r--r-- | iniherit/parser.py | 16 | ||||
-rw-r--r-- | iniherit/test.py | 45 |
2 files changed, 61 insertions, 0 deletions
diff --git a/iniherit/parser.py b/iniherit/parser.py index a186cfe..ed5c5be 100644 --- a/iniherit/parser.py +++ b/iniherit/parser.py @@ -8,6 +8,8 @@ import io import os.path +import warnings + import six from six.moves import configparser as CP from six.moves import urllib @@ -20,6 +22,8 @@ except ImportError: # be overridden as well... # TODO: should `ConfigParser.set()` be checked for option==INHERITTAG?... +from . import interpolation + __all__ = ( 'Loader', 'IniheritMixin', 'RawConfigParser', 'ConfigParser', 'SafeConfigParser', @@ -174,6 +178,18 @@ class IniheritMixin(object): else: _real_RawConfigParser.set(dst, dstsect, option, value) + #---------------------------------------------------------------------------- + # todo: yikes! overriding a private method!... + def _interpolate(self, section, option, rawval, vars): + return interpolation.interpolate( + self, _real_ConfigParser._interpolate, section, option, rawval, vars) + if not hasattr(_real_ConfigParser, '_interpolate'): + warnings.warn( + 'ConfigParser did not have a "_interpolate" method...' + ' iniherit may be broken on this platform', + RuntimeWarning) + + #------------------------------------------------------------------------------ # todo: i'm a little worried about the diamond inheritance here... class RawConfigParser(IniheritMixin, _real_RawConfigParser): diff --git a/iniherit/test.py b/iniherit/test.py index fddd93a..fef1bbd 100644 --- a/iniherit/test.py +++ b/iniherit/test.py @@ -213,6 +213,51 @@ class TestIniherit(unittest.TestCase): output.getvalue(), '[s3]\ns3v = b3\n\n[s2]\ns2v = o2\n\n[s1]\ns1v = b1\n\n') + #---------------------------------------------------------------------------- + def test_interpolation_env(self): + import os + from six.moves.configparser import InterpolationDepthError + from iniherit import InterpolationMissingEnvError + files = {k: textwrap.dedent(v) for k, v in { + 'config.ini' : '''\ + [section] + key1 = %(ENV:INIHERIT_TEST_EXIST)s + key2 = %(ENV:INIHERIT_TEST_EXIST:-default-value)s + key3 = %(ENV:INIHERIT_TEST_NOEXIST)s + key4 = %(ENV:INIHERIT_TEST_NOEXIST:-default-value)s + key5 = %(ENV:INIHERIT_TEST_INFLOOP)s + ''', + }.items()} + files = {k: textwrap.dedent(v) for k, v in files.items()} + parser = ConfigParser(loader=ByteLoader(files)) + parser.read('config.ini') + # note: setting envvar's *after* reading to ensure that interpolation + # occurs on-demand, i.e. lazy-eval + os.environ.pop('INIHERIT_TEST_NOEXIST', None) + os.environ['INIHERIT_TEST_EXIST'] = 'this-value' + os.environ['INIHERIT_TEST_INFLOOP'] = '%(ENV:INIHERIT_TEST_INFLOOP)s' + self.assertEqual(parser.get('section', 'key1'), 'this-value') + self.assertEqual(parser.get('section', 'key2'), 'this-value') + self.assertEqual(parser.get('section', 'key4'), 'default-value') + with self.assertRaises(InterpolationMissingEnvError) as cm: + parser.get('section', 'key3') + self.assertMultiLineEqual(str(cm.exception), textwrap.dedent('''\ + Bad value substitution: + \tsection: [section] + \toption : key3 + \tkey : INIHERIT_TEST_NOEXIST + \trawval : %(ENV:INIHERIT_TEST_NOEXIST)s + ''')) + with self.assertRaises(InterpolationDepthError) as cm: + parser.get('section', 'key5') + self.assertMultiLineEqual(str(cm.exception), textwrap.dedent('''\ + Value interpolation too deeply recursive: + \tsection: [section] + \toption : key5 + \trawval : %(ENV:INIHERIT_TEST_INFLOOP)s + ''')) + + #------------------------------------------------------------------------------ # end of $Id$ # $ChangeLog$ |