[fix-compat] Support older use case for Opt type

In I7cf94a1b2cbbfe67282e8a157548caff825d2811, we we moved
type formatting from generator to type, however we still have
some older code/libraries that were using a Opt with a type
set to a string. We need to support them until we find and
fix all use cases. So we explicitly check if format_defaults
is present and call it if it is. If format_defaults is
not present we call the older code from the change id
mentioned above.

Closes-Bug: #1522637
Change-Id: I298e75afbd43bd35aba93c38129008789ed39146
This commit is contained in:
Davanum Srinivas 2015-12-03 13:41:38 -05:00
parent 5df50c0f8b
commit 5490a28a13
2 changed files with 64 additions and 1 deletions

View File

@ -27,6 +27,7 @@ import logging
import operator
import sys
import textwrap
import warnings
import pkg_resources
import six
@ -60,6 +61,47 @@ def register_cli_opts(conf):
conf.register_cli_opts(_generator_opts)
def _format_defaults(opt):
"Return a list of formatted default values."
if isinstance(opt, cfg.MultiStrOpt):
if opt.sample_default is not None:
defaults = opt.sample_default
elif not opt.default:
defaults = ['']
else:
defaults = opt.default
else:
if opt.sample_default is not None:
default_str = str(opt.sample_default)
elif opt.default is None:
default_str = '<None>'
elif (isinstance(opt, cfg.StrOpt) or
isinstance(opt, cfg.IPOpt)):
default_str = opt.default
elif isinstance(opt, cfg.BoolOpt):
default_str = str(opt.default).lower()
elif isinstance(opt, (cfg.IntOpt, cfg.FloatOpt,
cfg.PortOpt)):
default_str = str(opt.default)
elif isinstance(opt, cfg.ListOpt):
default_str = ','.join(opt.default)
elif isinstance(opt, cfg.DictOpt):
sorted_items = sorted(opt.default.items(),
key=operator.itemgetter(0))
default_str = ','.join(['%s:%s' % i for i in sorted_items])
else:
LOG.warning('Unknown option type: %s', repr(opt))
default_str = str(opt.default)
defaults = [default_str]
results = []
for default_str in defaults:
if default_str.strip() != default_str:
default_str = '"%s"' % default_str
results.append(default_str)
return results
class _OptFormatter(object):
"""Format configuration option descriptions to a file."""
@ -153,7 +195,14 @@ class _OptFormatter(object):
'# This option is deprecated for removal.\n'
'# Its value may be silently ignored in the future.\n')
defaults = opt.type.format_defaults(opt.default, opt.sample_default)
if hasattr(opt.type, 'format_defaults'):
defaults = opt.type.format_defaults(opt.default,
opt.sample_default)
else:
msg = ('Option %s should have a type derived from '
'types.ConfigType instead of %s' % (opt.name, opt.type))
warnings.warn(msg)
defaults = _format_defaults(opt)
for default_str in defaults:
if default_str:
default_str = ' ' + default_str

View File

@ -137,6 +137,9 @@ class GeneratorTestCase(base.BaseTestCase):
default=['1', '2', '3'],
sample_default=['5', '6'],
help='multiple strings'),
'custom_type': cfg.Opt('custom_type',
help='custom help',
type=type('string')),
'custom_type_name': cfg.Opt('custom_opt_type',
type=types.Integer(type_name='port'
' number'),
@ -604,6 +607,17 @@ class GeneratorTestCase(base.BaseTestCase):
# this is a port (port number)
#custom_opt_type = 5511
''')),
('custom_type',
dict(opts=[('test', [(None, [opts['custom_type']])])],
expected='''[DEFAULT]
#
# From test
#
# custom help (unknown value)
#custom_type = <None>
''')),
]