From a671f9a1e2211480c9434b5170915d45d0f33e3d Mon Sep 17 00:00:00 2001 From: "ChangBo Guo(gcb)" Date: Tue, 8 Mar 2016 14:56:42 +0800 Subject: [PATCH] Disallow config option name as same as attribute of ConfigOpts If user use config option name(in 'DEFAULT' group) is same with ConfigOpts's internal attribute like 'project', CONF.project returns attribute value instead of option value without any error. That means internal attribute override user's config option in 'DEFAULT' group. The attribute list is: project, prog, version, usage, and default_config_files. This commit disallows illegal name in 'DEFAULT' group before registering it. Closes-Bug: #1550859 Change-Id: I5531092d4899e565176ed3a31821decb35ddfdc9 --- oslo_config/cfg.py | 10 ++++++++++ oslo_config/tests/test_cfg.py | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/oslo_config/cfg.py b/oslo_config/cfg.py index 70085fbc..da31203f 100644 --- a/oslo_config/cfg.py +++ b/oslo_config/cfg.py @@ -2031,6 +2031,8 @@ class ConfigOpts(collections.Mapping): :oslo.config:option:`config_dir` options. """ + disallow_names = ('project', 'prog', 'version', + 'usage', 'default_config_files') def __init__(self): """Construct a ConfigOpts object.""" @@ -2249,6 +2251,14 @@ class ConfigOpts(collections.Mapping): self._add_cli_opt(opt, group) return group._register_opt(opt, cli) + # NOTE(gcb) We can't use some names which are same with attributes of + # Opts in default group. They includes project, prog, version, usage + # and default_config_files. + if group is None: + if opt.name in self.disallow_names: + raise ValueError('Name %s was reserved for oslo.config.' + % opt.name) + if cli: self._add_cli_opt(opt, None) diff --git a/oslo_config/tests/test_cfg.py b/oslo_config/tests/test_cfg.py index 9a838e37..e96e757b 100644 --- a/oslo_config/tests/test_cfg.py +++ b/oslo_config/tests/test_cfg.py @@ -2170,6 +2170,14 @@ class ReRegisterOptTestCase(BaseTestCase): self.assertFalse(self.conf.register_opt(opt, group='blaa')) +class RegisterOptNameTestCase(BaseTestCase): + + def test_register_opt_with_disallow_name(self): + for name in cfg.ConfigOpts.disallow_names: + opt = cfg.StrOpt(name) + self.assertRaises(ValueError, self.conf.register_opt, opt) + + class TemplateSubstitutionTestCase(BaseTestCase): def _prep_test_str_sub(self, foo_default=None, bar_default=None):