cfg: support interpolation of config option from other groups
This patch adds support for config variable interpolation with values coming form… other groups than the current/default one! Change-Id: Iddd21aa2da71fe332868049d4b94b75b562b61cd
This commit is contained in:
parent
8d3c275352
commit
a5afcc22aa
@ -240,12 +240,10 @@ Option values may reference other values using PEP 292 string substitution::
|
||||
|
||||
Interpolation can be avoided by using `$$`.
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Interpolation using the values of options in groups is not yet
|
||||
supported. The interpolated option must be in the DEFAULT group
|
||||
(i.e., ``"$state_path"`` works but ``"$database.state_path"`` does
|
||||
not).
|
||||
You can use `.` to delimit option from other groups, e.g.
|
||||
${mygroup.myoption}.
|
||||
|
||||
Special Handling Instructions
|
||||
-----------------------------
|
||||
@ -2320,13 +2318,16 @@ class ConfigOpts(collections.Mapping):
|
||||
# a bit more natural for users
|
||||
if '\$' in value:
|
||||
value = value.replace('\$', '$$')
|
||||
tmpl = string.Template(value)
|
||||
tmpl = self.Template(value)
|
||||
ret = tmpl.safe_substitute(
|
||||
self.StrSubWrapper(self, group=group, namespace=namespace))
|
||||
return ret
|
||||
else:
|
||||
return value
|
||||
|
||||
class Template(string.Template):
|
||||
idpattern = r'[_a-z][\._a-z0-9]*'
|
||||
|
||||
def _convert_value(self, value, opt):
|
||||
"""Perform value type conversion.
|
||||
|
||||
@ -2591,10 +2592,16 @@ class ConfigOpts(collections.Mapping):
|
||||
|
||||
:param key: an opt name
|
||||
:returns: an opt value
|
||||
:raises: TemplateSubstitutionError if attribute is a group
|
||||
"""
|
||||
try:
|
||||
value = self.conf._get(key, group=self.group,
|
||||
group_name, option = key.split(".", 1)
|
||||
except ValueError:
|
||||
group = self.group
|
||||
option = key
|
||||
else:
|
||||
group = OptGroup(name=group_name)
|
||||
try:
|
||||
value = self.conf._get(option, group=group,
|
||||
namespace=self.namespace)
|
||||
except NoSuchOptError:
|
||||
value = self.conf._get(key, namespace=self.namespace)
|
||||
|
@ -2824,11 +2824,18 @@ class SadPathTestCase(BaseTestCase):
|
||||
|
||||
self.conf([])
|
||||
|
||||
self.assertFalse(hasattr(self.conf, 'bar'))
|
||||
self.assertRaises(
|
||||
AttributeError, getattr, self.conf, 'bar')
|
||||
self.assertRaises(
|
||||
cfg.TemplateSubstitutionError, self.conf._get, 'bar')
|
||||
self.assertTrue(hasattr(self.conf, 'bar'))
|
||||
self.assertEqual("blaa", self.conf.bar)
|
||||
|
||||
def test_str_sub_from_group_with_brace(self):
|
||||
self.conf.register_group(cfg.OptGroup('f'))
|
||||
self.conf.register_cli_opt(cfg.StrOpt('oo', default='blaa'), group='f')
|
||||
self.conf.register_cli_opt(cfg.StrOpt('bar', default='${f.oo}'))
|
||||
|
||||
self.conf([])
|
||||
|
||||
self.assertTrue(hasattr(self.conf, 'bar'))
|
||||
self.assertEqual("blaa", self.conf.bar)
|
||||
|
||||
def test_set_default_unknown_attr(self):
|
||||
self.conf([])
|
||||
|
@ -2800,11 +2800,8 @@ class SadPathTestCase(BaseTestCase):
|
||||
|
||||
self.conf([])
|
||||
|
||||
self.assertFalse(hasattr(self.conf, 'bar'))
|
||||
self.assertRaises(
|
||||
AttributeError, getattr, self.conf, 'bar')
|
||||
self.assertRaises(
|
||||
cfg.TemplateSubstitutionError, self.conf._get, 'bar')
|
||||
self.assertTrue(hasattr(self.conf, 'bar'))
|
||||
self.assertEqual("blaa", self.conf.bar)
|
||||
|
||||
def test_set_default_unknown_attr(self):
|
||||
self.conf([])
|
||||
|
Loading…
x
Reference in New Issue
Block a user