Config generator fails with lazy messages

Entry points from modules loaded from projects may have help text
that is i18n lazy enabled, which causes a failure because
gettextutils.Message (a subclass of six.text_type) explicitly
does not support concatenation.  Change from using concatenation
to using format (%) to allow six.text_type to do the right thing.

Change-Id: Ie60c569ae6fe227e16eef4a3281cf042732addc3
Closes-Bug: #1280826
This commit is contained in:
James Carey 2014-02-16 16:23:48 +00:00
parent c0d357bbb8
commit e839886cc1
4 changed files with 85 additions and 1 deletions

View File

@ -247,7 +247,8 @@ def _print_opt(opt):
except (ValueError, AttributeError) as err:
sys.stderr.write("%s\n" % str(err))
sys.exit(1)
opt_help += ' (' + OPT_TYPES[opt_type] + ')'
opt_help = u'%s (%s)' % (opt_help,
OPT_TYPES[opt_type])
print('#', "\n# ".join(textwrap.wrap(opt_help, WORDWRAP_WIDTH)))
if opt.deprecated_opts:
for deprecated_opt in opt.deprecated_opts:

View File

@ -0,0 +1,27 @@
# Copyright 2014 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack.common import gettextutils
from oslo.config import cfg
CONF = cfg.CONF
# Note that this is using the Message class directly instead of using
# gettextutils.enable_lazy() because this isolates the use of
# the Message class to this one instance instead of turning it on
# for all subsequent tests
opt = cfg.StrOpt('i18n', default="i18n",
help=gettextutils.Message('helpful message'))
CONF.register_opt(opt, group='i18n')

View File

@ -0,0 +1,23 @@
# Copyright 2014 IBM Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo.config import cfg
CONF = cfg.CONF
# Use a unicode value that causes an exception if str() is used
opt = cfg.StrOpt('unicode_opt', default="unicode_default",
help=u'helpful message with unicode char: \xE7\x94\xB5')
CONF.register_opt(opt, group='unicode_group')

View File

@ -30,6 +30,10 @@ class GeneratorTestcase(test.BaseTestCase):
"tests/testmods/bar_foo_opt.py",
"tests/testmods/fblaa_opt"]
conffiles_i18n = ["tests/testmods/i18n_opt"]
conffiles_unicode = ["tests/testmods/unicode_opt"]
def setUp(self):
super(GeneratorTestcase, self).setUp()
self.groups = []
@ -63,3 +67,32 @@ class GeneratorTestcase(test.BaseTestCase):
self.assertIn('#baa=<None>\n', lines)
self.assertIn('#foo=<None>\n', lines)
self.assertIn('#fblaa=fblaa\n', lines)
def test_i18n(self):
stdout = self.useFixture(fixtures.StringStream('confstdout')).stream
self.useFixture(mockpatch.Patch('sys.stdout', new=stdout))
generator.generate(self.conffiles_i18n)
stdout.flush()
stdout.seek(0)
lines = stdout.readlines()
# Test we have group in the output
self.assertIn('[i18n]\n', lines)
# Test we have opt in the output
self.assertIn('#i18n=i18n\n', lines)
# Test we have help in the output
self.assertIn('# helpful message (string value)\n', lines)
def test_unicode(self):
stdout = self.useFixture(fixtures.StringStream('confstdout')).stream
self.useFixture(mockpatch.Patch('sys.stdout', new=stdout))
generator.generate(self.conffiles_unicode)
stdout.flush()
stdout.seek(0)
lines = stdout.readlines()
# Test we have group in the output
self.assertIn('[unicode_group]\n', lines)
# Test we have opt in the output
self.assertIn('#unicode_opt=unicode_default\n', lines)
# Test we have help in the output
self.assertIn(u'# helpful message with unicode char:'
u' \xE7\x94\xB5 (string value)\n', lines)