From 5490a28a1398f10a3d346fef23374a972f90c40f Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 3 Dec 2015 13:41:38 -0500 Subject: [PATCH] [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 --- oslo_config/generator.py | 51 ++++++++++++++++++++++++++++- oslo_config/tests/test_generator.py | 14 ++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/oslo_config/generator.py b/oslo_config/generator.py index fa4240df..6443af86 100644 --- a/oslo_config/generator.py +++ b/oslo_config/generator.py @@ -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 = '' + 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 diff --git a/oslo_config/tests/test_generator.py b/oslo_config/tests/test_generator.py index 4c4466f5..f2875eaf 100644 --- a/oslo_config/tests/test_generator.py +++ b/oslo_config/tests/test_generator.py @@ -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 = ''')), ]