Hello community,
here is the log from the commit of package python-oslo.config for
openSUSE:Factory checked in at 2018-01-17 21:56:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-oslo.config (Old)
and /work/SRC/openSUSE:Factory/.python-oslo.config.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-oslo.config"
Wed Jan 17 21:56:27 2018 rev:25 rq:565766 version:5.2.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-oslo.config/python-oslo.config.changes
2018-01-10 23:35:59.205718376 +0100
+++
/work/SRC/openSUSE:Factory/.python-oslo.config.new/python-oslo.config.changes
2018-01-17 21:56:32.396193449 +0100
@@ -1,0 +2,11 @@
+Mon Jan 15 11:50:59 UTC 2018 - [email protected]
+
+- update to version 5.2.0
+ - Clean up enforce_type related test method's name
+ - Remove -U from pip install
+ - Provide descriptions for choices
+ - Fix the invalid links for doc file in oslo.config
+ - Avoid tox_install.sh for constraints support
+ - sphinxext: Don't sometimes emit trailing newlines
+
+-------------------------------------------------------------------
Old:
----
oslo.config-5.1.0.tar.gz
New:
----
oslo.config-5.2.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-oslo.config.spec ++++++
--- /var/tmp/diff_new_pack.2rtRCf/_old 2018-01-17 21:56:33.064162204 +0100
+++ /var/tmp/diff_new_pack.2rtRCf/_new 2018-01-17 21:56:33.092160894 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-oslo.config
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,13 +17,13 @@
Name: python-oslo.config
-Version: 5.1.0
+Version: 5.2.0
Release: 0
Summary: OpenStack common configuration library
License: Apache-2.0
Group: Development/Languages/Python
Url: https://launchpad.net/oslo.config
-Source0:
https://files.pythonhosted.org/packages/source/o/oslo.config/oslo.config-5.1.0.tar.gz
+Source0:
https://files.pythonhosted.org/packages/source/o/oslo.config/oslo.config-5.2.0.tar.gz
BuildRequires: openstack-macros
BuildRequires: python-devel
BuildRequires: python2-PyYAML >= 3.10
@@ -94,7 +94,7 @@
Documentation for the oslo-config library.
%prep
-%autosetup -p1 -n oslo.config-5.1.0
+%autosetup -p1 -n oslo.config-5.2.0
%py_req_cleanup
sed -i 's/^warning-is-error.*/warning-is-error = 0/g' setup.cfg
++++++ oslo.config-5.1.0.tar.gz -> oslo.config-5.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/AUTHORS
new/oslo.config-5.2.0/AUTHORS
--- old/oslo.config-5.1.0/AUTHORS 2017-11-20 17:28:15.000000000 +0100
+++ new/oslo.config-5.2.0/AUTHORS 2018-01-08 15:15:24.000000000 +0100
@@ -164,6 +164,7 @@
lzyeval <[email protected]>
melissaml <[email protected]>
ricolin <[email protected]>
+shangxiaobj <[email protected]>
skudriashev <[email protected]>
sonu.kumar <[email protected]>
ting.wang <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/ChangeLog
new/oslo.config-5.2.0/ChangeLog
--- old/oslo.config-5.1.0/ChangeLog 2017-11-20 17:28:15.000000000 +0100
+++ new/oslo.config-5.2.0/ChangeLog 2018-01-08 15:15:24.000000000 +0100
@@ -1,6 +1,16 @@
CHANGES
=======
+5.2.0
+-----
+
+* Fix the invalid links for doc file in oslo.config
+* sphinxext: Don't sometimes emit trailing newlines
+* Provide descriptions for choices
+* Remove -U from pip install
+* Avoid tox\_install.sh for constraints support
+* Clean up enforce\_type related test method's name
+
5.1.0
-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/PKG-INFO
new/oslo.config-5.2.0/PKG-INFO
--- old/oslo.config-5.1.0/PKG-INFO 2017-11-20 17:28:16.000000000 +0100
+++ new/oslo.config-5.2.0/PKG-INFO 2018-01-08 15:15:24.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: oslo.config
-Version: 5.1.0
+Version: 5.2.0
Summary: Oslo Configuration API
Home-page: https://docs.openstack.org/oslo.config/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/oslo.config-5.1.0/doc/source/reference/styleguide.rst
new/oslo.config-5.2.0/doc/source/reference/styleguide.rst
--- old/oslo.config-5.1.0/doc/source/reference/styleguide.rst 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/doc/source/reference/styleguide.rst 2018-01-08
15:12:21.000000000 +0100
@@ -9,7 +9,7 @@
configuration files, such as ``etc/cinder/cinder.conf`` in the
cinder repository. They are also displayed in the `OpenStack
Configuration Reference
-<http://docs.openstack.org/draft/config-reference/index.html>`_.
+<https://docs.openstack.org/oslo.config/latest/reference/index.html>`_.
Examples::
@@ -29,7 +29,7 @@
2. Only use single spaces, no double spaces.
-3. Properly capitalize words. If in doubt check the `OpenStack Glossary
<http://docs.openstack.org/user-guide/common/glossary.html>`_.
+3. Properly capitalize words. If in doubt check the `OpenStack Glossary
<https://docs.openstack.org/oslo.config/latest/reference/styleguide.html#style-guide>`_.
4. End each segment with a period and write complete sentences if
possible. Examples::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo.config.egg-info/PKG-INFO
new/oslo.config-5.2.0/oslo.config.egg-info/PKG-INFO
--- old/oslo.config-5.1.0/oslo.config.egg-info/PKG-INFO 2017-11-20
17:28:15.000000000 +0100
+++ new/oslo.config-5.2.0/oslo.config.egg-info/PKG-INFO 2018-01-08
15:15:24.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: oslo.config
-Version: 5.1.0
+Version: 5.2.0
Summary: Oslo Configuration API
Home-page: https://docs.openstack.org/oslo.config/latest/
Author: OpenStack
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo.config.egg-info/SOURCES.txt
new/oslo.config-5.2.0/oslo.config.egg-info/SOURCES.txt
--- old/oslo.config-5.1.0/oslo.config.egg-info/SOURCES.txt 2017-11-20
17:28:16.000000000 +0100
+++ new/oslo.config-5.2.0/oslo.config.egg-info/SOURCES.txt 2018-01-08
15:15:24.000000000 +0100
@@ -82,6 +82,7 @@
releasenotes/notes/add-reno-71dc832ce29b962f.yaml
releasenotes/notes/machine-readable-sample-config-e8f8ba43ababcf99.yaml
releasenotes/notes/show-deprecated-reason-361a8eb31e05c97e.yaml
+releasenotes/notes/support-choice-descriptions-8b2d0c14fbd16b2a.yaml
releasenotes/source/conf.py
releasenotes/source/index.rst
releasenotes/source/liberty.rst
@@ -91,5 +92,4 @@
releasenotes/source/pike.rst
releasenotes/source/unreleased.rst
releasenotes/source/_static/.placeholder
-releasenotes/source/_templates/.placeholder
-tools/tox_install.sh
\ No newline at end of file
+releasenotes/source/_templates/.placeholder
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo.config.egg-info/pbr.json
new/oslo.config-5.2.0/oslo.config.egg-info/pbr.json
--- old/oslo.config-5.1.0/oslo.config.egg-info/pbr.json 2017-11-20
17:28:15.000000000 +0100
+++ new/oslo.config-5.2.0/oslo.config.egg-info/pbr.json 2018-01-08
15:15:24.000000000 +0100
@@ -1 +1 @@
-{"git_version": "eb6ff02", "is_release": true}
\ No newline at end of file
+{"git_version": "5578616", "is_release": true}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/cfg.py
new/oslo.config-5.2.0/oslo_config/cfg.py
--- old/oslo.config-5.1.0/oslo_config/cfg.py 2017-11-20 17:25:42.000000000
+0100
+++ new/oslo.config-5.2.0/oslo_config/cfg.py 2018-01-08 15:12:21.000000000
+0100
@@ -1225,7 +1225,8 @@
Option with ``type`` :class:`oslo_config.types.String`
:param name: the option's name
- :param choices: Optional sequence of valid values.
+ :param choices: Optional sequence of either valid values or tuples of valid
+ values with descriptions.
:param quotes: If True and string is enclosed with single or double
quotes, will strip those quotes.
:param regex: Optional regular expression (string or compiled
@@ -1248,6 +1249,10 @@
.. versionchanged:: 2.7
Added *max_length* parameter
+
+ .. versionchanged:: 5.2
+ The *choices* parameter will now accept a sequence of tuples, where each
+ tuple is of form (*choice*, *description*)
"""
def __init__(self, name, choices=None, quotes=None,
@@ -1275,10 +1280,11 @@
if getattr(self.type, 'choices', None):
choices_text = ', '.join([self._get_choice_text(choice)
for choice in self.type.choices])
- if kwargs['help'] is not None:
- kwargs['help'] += (' Allowed values: %s\n' % choices_text)
- else:
- kwargs['help'] = (' Allowed values: %s\n' % choices_text)
+ if kwargs['help'] is None:
+ kwargs['help'] = ''
+
+ kwargs['help'].rstrip('\n')
+ kwargs['help'] += '\n Allowed values: %s\n' % choices_text
return kwargs
@@ -1448,7 +1454,8 @@
:param name: the option's name
:param min: minimum value the port can take
:param max: maximum value the port can take
- :param choices: Optional sequence of valid values.
+ :param choices: Optional sequence of either valid values or tuples of valid
+ values with descriptions.
:param \*\*kwargs: arbitrary keyword arguments passed to :class:`Opt`
.. versionadded:: 2.6
@@ -1458,6 +1465,9 @@
Allow port number with 0.
.. versionchanged:: 3.16
Added *min* and *max* parameters.
+ .. versionchanged:: 5.2
+ The *choices* parameter will now accept a sequence of tuples, where each
+ tuple is of form (*choice*, *description*)
"""
def __init__(self, name, min=None, max=None, choices=None, **kwargs):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/generator.py
new/oslo.config-5.2.0/oslo_config/generator.py
--- old/oslo.config-5.1.0/oslo_config/generator.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/generator.py 2018-01-08
15:12:21.000000000 +0100
@@ -66,14 +66,18 @@
'longer help text for Sphinx documents.'),
cfg.StrOpt(
'format',
- help='Desired format for the output. "ini" is the only one which can '
- 'be used directly with oslo.config. "json" and "yaml" are '
- 'intended for third-party tools that want to write config files '
- 'based on the sample config data. "rst" can be used to dump '
- 'the text given to sphinx when building documentation using '
- 'the sphinx extension, for debugging.',
+ help='Desired format for the output.',
default='ini',
- choices=['ini', 'json', 'yaml', 'rst'],
+ choices=[
+ ('ini', 'The only format that can be used directly with '
+ 'oslo.config.'),
+ ('json', 'Intended for third-party tools that want to write '
+ 'config files based on the sample config data.'),
+ ('yaml', 'Same as json'),
+ ('rst', 'Can be used to dump the text given to Sphinx when '
+ 'building documentation using the Sphinx extension. '
+ 'Useful for debugging,')
+ ],
dest='format_'),
]
@@ -257,9 +261,12 @@
lines.append('# Maximum value: %d\n' % opt.type.max)
if getattr(opt.type, 'choices', None):
- choices_text = ', '.join([self._get_choice_text(choice)
- for choice in opt.type.choices])
- lines.append('# Allowed values: %s\n' % choices_text)
+ lines.append('# Possible values:\n')
+ for choice in opt.type.choices:
+ help_text = '%s - %s' % (
+ self._get_choice_text(choice),
+ opt.type.choices[choice] or '<No description provided>')
+ lines.extend(self._format_help(help_text))
try:
if opt.mutable:
@@ -581,9 +588,14 @@
entry = {key: value for key, value in opt.__dict__.items()
if not key.startswith('_')}
entry['namespace'] = namespace
- # In some types, choices is explicitly set to None. Force it to [] so it
- # is always an iterable type.
- entry['choices'] = getattr(entry['type'], 'choices', []) or []
+ # Where present, we store choices as an OrderedDict. The default repr for
+ # this is not very machine readable, thus, it is switched to a list of
+ # tuples here. In addition, in some types, choices is explicitly set to
+ # None. Force these cases to [] so it is always an iterable type.
+ if getattr(entry['type'], 'choices', None):
+ entry['choices'] = list(entry['type'].choices.items())
+ else:
+ entry['choices'] = []
entry['min'] = getattr(entry['type'], 'min', None)
entry['max'] = getattr(entry['type'], 'max', None)
entry['type'] = _format_type_name(entry['type'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/sphinxext.py
new/oslo.config-5.2.0/oslo_config/sphinxext.py
--- old/oslo.config-5.1.0/oslo_config/sphinxext.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/sphinxext.py 2018-01-08
15:12:21.000000000 +0100
@@ -49,7 +49,6 @@
yield ' - * %s' % row[0]
for r in row[1:]:
yield ' * %s' % r
- yield ''
def _indent(text, n=2):
@@ -152,7 +151,6 @@
'by the majority of users, and might have a significant', 6)
yield _indent(
'effect on stability and/or performance.', 6)
- yield ''
try:
help_text = opt.help % {'default': 'the value above'}
@@ -162,10 +160,23 @@
# invalid formatting characters
help_text = opt.help
if help_text:
+ yield ''
yield _indent(help_text)
+
+ # We don't bother outputting this if not using new-style choices with
+ # inline descriptions
+ if getattr(opt.type, 'choices', None) and not all(
+ x is None for x in opt.type.choices.values()):
yield ''
+ yield _indent('.. rubric:: Possible values')
+ for choice in opt.type.choices:
+ yield ''
+ yield _indent(_get_choice_text(choice))
+ yield _indent(_indent(
+ opt.type.choices[choice] or '<No description provided>'))
if opt.deprecated_opts:
+ yield ''
for line in _list_table(
['Group', 'Name'],
((d.group or group_name,
@@ -173,7 +184,9 @@
for d in opt.deprecated_opts),
title='Deprecated Variations'):
yield _indent(line)
+
if opt.deprecated_for_removal:
+ yield ''
yield _indent('.. warning::')
if opt.deprecated_since:
yield _indent(' This option is deprecated for removal '
@@ -182,10 +195,9 @@
yield _indent(' This option is deprecated for removal.')
yield _indent(' Its value may be silently ignored ')
yield _indent(' in the future.')
- yield ''
if opt.deprecated_reason:
+ yield ''
yield _indent(' :Reason: ' + opt.deprecated_reason)
- yield ''
yield ''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/tests/test_cfg.py
new/oslo.config-5.2.0/oslo_config/tests/test_cfg.py
--- old/oslo.config-5.1.0/oslo_config/tests/test_cfg.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/tests/test_cfg.py 2018-01-08
15:11:54.000000000 +0100
@@ -3237,16 +3237,7 @@
self.assertRaises(ValueError,
self.conf.set_default, 'oo', 'c', 'f')
- def test_enforce_type_default_override(self):
- self.conf.register_opt(cfg.StrOpt('foo', default='foo'))
- self.conf([])
- self.assertEqual('foo', self.conf.foo)
- self.conf.set_default('foo', 'bar')
- self.assertEqual('bar', self.conf.foo)
- self.conf.clear_default('foo')
- self.assertEqual('foo', self.conf.foo)
-
- def test_enforce_type_wrong_type_default(self):
+ def test_wrong_type_default_override(self):
self.conf.register_opt(cfg.IntOpt('foo', default=1))
self.conf([])
self.assertEqual(1, self.conf.foo)
@@ -3322,7 +3313,7 @@
self.conf.clear_override('foo')
self.assertIsNone(self.conf.foo)
- def test_enforce_type_str_override(self):
+ def test__str_override(self):
self.conf.register_opt(cfg.StrOpt('foo'))
self.conf.set_override('foo', True)
self.conf([])
@@ -3330,7 +3321,7 @@
self.conf.clear_override('foo')
self.assertIsNone(self.conf.foo)
- def test_enforce_type_wrong_type_override(self):
+ def test__wrong_type_override(self):
self.conf.register_opt(cfg.IntOpt('foo'))
self.assertRaises(ValueError, self.conf.set_override,
'foo', "not_really_a_int")
@@ -3349,7 +3340,7 @@
self.assertRaises(ValueError,
self.conf.set_override, 'oo', 'c', 'f')
- def test_enforce_type_bool_override(self):
+ def test_bool_override(self):
self.conf.register_opt(cfg.BoolOpt('foo'))
self.conf.set_override('foo', 'True')
self.conf([])
@@ -3357,7 +3348,7 @@
self.conf.clear_override('foo')
self.assertIsNone(self.conf.foo)
- def test_enforce_type_int_override_with_None(self):
+ def test_int_override_with_None(self):
self.conf.register_opt(cfg.IntOpt('foo'))
self.conf.set_override('foo', None)
self.conf([])
@@ -3365,7 +3356,7 @@
self.conf.clear_override('foo')
self.assertIsNone(self.conf.foo)
- def test_enforce_type_str_override_with_None(self):
+ def test_str_override_with_None(self):
self.conf.register_opt(cfg.StrOpt('foo'))
self.conf.set_override('foo', None)
self.conf([])
@@ -3373,7 +3364,7 @@
self.conf.clear_override('foo')
self.assertIsNone(self.conf.foo)
- def test_enforce_type_List_override(self):
+ def test_List_override(self):
self.conf.register_opt(cfg.ListOpt('foo'))
self.conf.set_override('foo', ['aa', 'bb'])
self.conf([])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/tests/test_fixture.py
new/oslo.config-5.2.0/oslo_config/tests/test_fixture.py
--- old/oslo.config-5.1.0/oslo_config/tests/test_fixture.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/tests/test_fixture.py 2018-01-08
15:11:54.000000000 +0100
@@ -42,7 +42,7 @@
self.assertEqual('changed_value',
f.conf.get('testing_option'))
- def test_overridden_value_with_enforce_type(self):
+ def test_overridden_value_with_wrong_type(self):
f = self._make_fixture()
self.assertEqual(5, f.conf.get('test2'))
self.assertEqual('a', f.conf.get('test3'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/oslo.config-5.1.0/oslo_config/tests/test_generator.py
new/oslo.config-5.2.0/oslo_config/tests/test_generator.py
--- old/oslo.config-5.1.0/oslo_config/tests/test_generator.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/tests/test_generator.py 2018-01-08
15:12:21.000000000 +0100
@@ -431,7 +431,12 @@
#
# a string with choices (string value)
-# Allowed values: <None>, '', a, b, c
+# Possible values:
+# <None> - <No description provided>
+# '' - <No description provided>
+# a - <No description provided>
+# b - <No description provided>
+# c - <No description provided>
#choices_opt = a
''')),
('deprecated opt without deprecated group',
@@ -1219,7 +1224,13 @@
'help': '',
'standard_opts': ['choices_opt'],
'opts': [{'advanced': False,
- 'choices': (None, '', 'a', 'b', 'c'),
+ 'choices': [
+ (None, None),
+ ('', None),
+ ('a', None),
+ ('b', None),
+ ('c', None)
+ ],
'default': 'a',
'deprecated_for_removal': False,
'deprecated_opts': [],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/oslo.config-5.1.0/oslo_config/tests/test_sphinxext.py
new/oslo.config-5.2.0/oslo_config/tests/test_sphinxext.py
--- old/oslo.config-5.1.0/oslo_config/tests/test_sphinxext.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/tests/test_sphinxext.py 2018-01-08
15:12:21.000000000 +0100
@@ -42,7 +42,6 @@
:Default: ``<None>``
this appears in the default group
-
''').lstrip(), results)
def test_with_default_value(self):
@@ -66,7 +65,6 @@
:Default: ``this is the default``
this appears in the default group
-
''').lstrip(), results)
def test_with_min(self):
@@ -88,7 +86,6 @@
:Type: integer
:Default: ``<None>``
:Minimum Value: 1
-
''').lstrip(), results)
def test_with_min_0(self):
@@ -110,7 +107,6 @@
:Type: integer
:Default: ``<None>``
:Minimum Value: 0
-
''').lstrip(), results)
def test_with_max(self):
@@ -132,7 +128,6 @@
:Type: integer
:Default: ``<None>``
:Maximum Value: 1
-
''').lstrip(), results)
def test_with_max_0(self):
@@ -154,7 +149,6 @@
:Type: integer
:Default: ``<None>``
:Maximum Value: 0
-
''').lstrip(), results)
def test_with_choices(self):
@@ -176,7 +170,50 @@
:Type: string
:Default: ``<None>``
:Valid Values: a, b, c, <None>, ''
+ ''').lstrip(), results)
+ def test_with_choices_with_descriptions(self):
+ results = '\n'.join(list(sphinxext._format_group(
+ app=mock.Mock(),
+ namespace=None,
+ group_name=None,
+ group_obj=None,
+ opt_list=[
+ cfg.StrOpt(
+ 'opt_name',
+ choices=[
+ ('a', 'a is the best'),
+ ('b', 'Actually, may-b I am better'),
+ ('c', 'c, I am clearly the greatest'),
+ (None, 'I am having none of this'),
+ ('', '')]),
+ ],
+ )))
+ self.assertEqual(textwrap.dedent('''
+ .. oslo.config:group:: DEFAULT
+
+ .. oslo.config:option:: opt_name
+
+ :Type: string
+ :Default: ``<None>``
+ :Valid Values: a, b, c, <None>, ''
+
+ .. rubric:: Possible values
+
+ a
+ a is the best
+
+ b
+ Actually, may-b I am better
+
+ c
+ c, I am clearly the greatest
+
+ <None>
+ I am having none of this
+
+ ''
+ <No description provided>
''').lstrip(), results)
def test_group_obj_without_help(self):
@@ -195,7 +232,6 @@
:Type: string
:Default: ``<None>``
-
''').lstrip(), results)
def test_group_obj_with_help(self):
@@ -216,7 +252,6 @@
:Type: string
:Default: ``<None>``
-
''').lstrip(), results)
def test_deprecated_opts_without_deprecated_group(self):
@@ -246,7 +281,6 @@
* Name
- * DEFAULT
* deprecated_name
-
''').lstrip(), results)
def test_deprecated_opts_with_deprecated_group(self):
@@ -277,7 +311,6 @@
* Name
- * deprecated_group
* deprecated_name
-
''').lstrip(), results)
def test_deprecated_for_removal(self):
@@ -317,7 +350,6 @@
:Type: integer
:Default: ``<None>``
:Mutable: This option can be changed without restarting.
-
''').lstrip(), results)
def test_not_mutable(self):
@@ -338,7 +370,6 @@
:Type: integer
:Default: ``<None>``
-
''').lstrip(), results)
def test_advanced(self):
@@ -362,7 +393,6 @@
:Advanced Option: Intended for advanced users and not used
by the majority of users, and might have a significant
effect on stability and/or performance.
-
''').lstrip(), results)
def test_not_advanced(self):
@@ -383,7 +413,6 @@
:Type: string
:Default: ``<None>``
-
''').lstrip(), results)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/tests/test_types.py
new/oslo.config-5.2.0/oslo_config/tests/test_types.py
--- old/oslo.config-5.1.0/oslo_config/tests/test_types.py 2017-11-20
17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/oslo_config/tests/test_types.py 2018-01-08
15:12:21.000000000 +0100
@@ -67,6 +67,11 @@
self.type_instance = types.String(choices=('foo', 'bar'))
self.assertConvertedValue('foo', 'foo')
+ def test_listed_value_dict(self):
+ self.type_instance = types.String(choices=[
+ ('foo', 'ab'), ('bar', 'xy')])
+ self.assertConvertedValue('foo', 'foo')
+
def test_unlisted_value(self):
self.type_instance = types.String(choices=['foo', 'bar'])
self.assertInvalid('baz')
@@ -98,7 +103,11 @@
def test_repr_with_choices_tuple(self):
t = types.String(choices=('foo', 'bar'))
- self.assertEqual('String(choices=(\'foo\', \'bar\'))', repr(t))
+ self.assertEqual('String(choices=[\'foo\', \'bar\'])', repr(t))
+
+ def test_repr_with_choices_dict(self):
+ t = types.String(choices=[('foo', 'ab'), ('bar', 'xy')])
+ self.assertEqual('String(choices=[\'foo\', \'bar\'])', repr(t))
def test_equal(self):
self.assertTrue(types.String() == types.String())
@@ -108,9 +117,8 @@
t2 = types.String(choices=['foo', 'bar'])
t3 = types.String(choices=('foo', 'bar'))
t4 = types.String(choices=['bar', 'foo'])
- self.assertTrue(t1 == t2)
- self.assertTrue(t1 == t3)
- self.assertTrue(t1 == t4)
+ t5 = types.String(choices=[('foo', 'ab'), ('bar', 'xy')])
+ self.assertTrue(t1 == t2 == t3 == t4 == t5)
def test_not_equal_with_different_choices(self):
t1 = types.String(choices=['foo', 'bar'])
@@ -282,7 +290,11 @@
def test_repr_with_choices_tuple(self):
t = types.Integer(choices=(80, 457))
- self.assertEqual('Integer(choices=(80, 457))', repr(t))
+ self.assertEqual('Integer(choices=[80, 457])', repr(t))
+
+ def test_repr_with_choices_dict(self):
+ t = types.Integer(choices=[(80, 'ab'), (457, 'xy')])
+ self.assertEqual('Integer(choices=[80, 457])', repr(t))
def test_equal(self):
self.assertTrue(types.Integer() == types.Integer())
@@ -302,8 +314,8 @@
t1 = types.Integer(choices=[80, 457])
t2 = types.Integer(choices=[457, 80])
t3 = types.Integer(choices=(457, 80))
- self.assertTrue(t1 == t2)
- self.assertTrue(t1 == t3)
+ t4 = types.Integer(choices=[(80, 'ab'), (457, 'xy')])
+ self.assertTrue(t1 == t2 == t3 == t4)
def test_not_equal(self):
self.assertFalse(types.Integer(min=123) == types.Integer(min=456))
@@ -369,21 +381,24 @@
self.assertRaises(ValueError, t, 201)
self.assertRaises(ValueError, t, -457)
- def test_with_choices_list(self):
- t = types.Integer(choices=[80, 457])
+ def _test_with_choices(self, t):
self.assertRaises(ValueError, t, 1)
self.assertRaises(ValueError, t, 200)
self.assertRaises(ValueError, t, -457)
t(80)
t(457)
+ def test_with_choices_list(self):
+ t = types.Integer(choices=[80, 457])
+ self._test_with_choices(t)
+
def test_with_choices_tuple(self):
t = types.Integer(choices=(80, 457))
- self.assertRaises(ValueError, t, 1)
- self.assertRaises(ValueError, t, 200)
- self.assertRaises(ValueError, t, -457)
- t(80)
- t(457)
+ self._test_with_choices(t)
+
+ def test_with_choices_dict(self):
+ t = types.Integer(choices=[(80, 'ab'), (457, 'xy')])
+ self._test_with_choices(t)
class FloatTypeTests(TypeTestHelper, unittest.TestCase):
@@ -865,16 +880,29 @@
def test_repr_with_choices_tuple(self):
t = types.Port(choices=(80, 457))
- self.assertEqual('Port(choices=(80, 457))', repr(t))
+ self.assertEqual('Port(choices=[80, 457])', repr(t))
- def test_choices(self):
- t = types.Port(choices=[80, 457])
+ def _test_with_choices(self, t):
self.assertRaises(ValueError, t, 1)
self.assertRaises(ValueError, t, 200)
+ self.assertRaises(ValueError, t, -457)
t(80)
t(457)
+ def test_with_choices_list(self):
+ t = types.Port(choices=[80, 457])
+ self._test_with_choices(t)
+
+ def test_with_choices_tuple(self):
+ t = types.Port(choices=(80, 457))
+ self._test_with_choices(t)
+
+ def test_with_choices_dict(self):
+ t = types.Port(choices=[(80, 'ab'), (457, 'xy')])
+ self._test_with_choices(t)
+
def test_invalid_choices(self):
+ """Check for choices that are specifically invalid for ports."""
self.assertRaises(ValueError, types.Port, choices=[-1, 457])
self.assertRaises(ValueError, types.Port, choices=[1, 2, 3, 65536])
@@ -896,8 +924,8 @@
t1 = types.Port(choices=[80, 457])
t2 = types.Port(choices=[457, 80])
t3 = types.Port(choices=(457, 80))
- self.assertTrue(t1 == t2)
- self.assertTrue(t1 == t3)
+ t4 = types.Port(choices=[(457, 'ab'), (80, 'xy')])
+ self.assertTrue(t1 == t2 == t3 == t4)
def test_not_equal(self):
self.assertFalse(types.Port(min=123) == types.Port(min=456))
@@ -973,19 +1001,3 @@
t = types.Port(max=0)
self.assertRaises(ValueError, t, 1)
t(0)
-
- def test_with_choices_list(self):
- t = types.Port(choices=[80, 457])
- self.assertRaises(ValueError, t, 1)
- self.assertRaises(ValueError, t, 200)
- self.assertRaises(ValueError, t, -457)
- t(80)
- t(457)
-
- def test_with_choices_tuple(self):
- t = types.Port(choices=(80, 457))
- self.assertRaises(ValueError, t, 1)
- self.assertRaises(ValueError, t, 200)
- self.assertRaises(ValueError, t, -457)
- t(80)
- t(457)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/oslo_config/types.py
new/oslo.config-5.2.0/oslo_config/types.py
--- old/oslo.config-5.1.0/oslo_config/types.py 2017-11-20 17:25:42.000000000
+0100
+++ new/oslo.config-5.2.0/oslo_config/types.py 2018-01-08 15:12:21.000000000
+0100
@@ -19,6 +19,7 @@
.. versionadded:: 1.3
"""
+import collections
import operator
import re
import warnings
@@ -68,8 +69,8 @@
String values do not get transformed and are returned as str objects.
- :param choices: Optional sequence of valid values. Mutually
- exclusive with 'regex'.
+ :param choices: Optional sequence of either valid values or tuples of valid
+ values with descriptions. Mutually exclusive with 'regex'.
:param quotes: If True and string is enclosed with single or double
quotes, will strip those quotes. Will signal error if
string have quote at the beginning and no quote at
@@ -96,6 +97,10 @@
.. versionchanged:: 2.7
Added *max_length* parameter.
Added *type_name* parameter.
+
+ .. versionchanged:: 5.2
+ The *choices* parameter will now accept a sequence of tuples, where each
+ tuple is of form (*choice*, *description*)
"""
def __init__(self, choices=None, quotes=False, regex=None,
@@ -109,10 +114,17 @@
self.quotes = quotes
self.max_length = max_length or 0
- self.choices = choices
+ if choices is not None:
+ if not all(isinstance(choice, tuple) for choice in choices):
+ choices = [(choice, None) for choice in choices]
+
+ self.choices = collections.OrderedDict(choices)
+ else:
+ self.choices = None
+
self.lower_case_choices = None
if self.choices is not None and self.ignore_case:
- self.lower_case_choices = [c.lower() for c in choices]
+ self.lower_case_choices = [c.lower() for c in self.choices]
self.regex = regex
if self.regex is not None:
@@ -146,7 +158,7 @@
# Check for case insensitive
processed_value, choices = ((value.lower(), self.lower_case_choices)
if self.ignore_case else
- (value, self.choices))
+ (value, self.choices.keys()))
if processed_value in choices:
return value
@@ -158,7 +170,7 @@
def __repr__(self):
details = []
if self.choices is not None:
- details.append("choices={!r}".format(self.choices))
+ details.append("choices={!r}".format(list(self.choices.keys())))
if self.regex:
details.append("regex=%r" % self.regex.pattern)
if details:
@@ -168,11 +180,12 @@
def __eq__(self, other):
return (
(self.__class__ == other.__class__) and
- (set(self.choices) == set(other.choices) if
- self.choices and other.choices else
- self.choices == other.choices) and
(self.quotes == other.quotes) and
- (self.regex == other.regex)
+ (self.regex == other.regex) and
+ (set([x for x in self.choices or []]) ==
+ set([x for x in other.choices or []]) if
+ self.choices and other.choices else
+ self.choices == other.choices)
)
def _formatter(self, value):
@@ -252,9 +265,14 @@
:param type_name: Type name to be used in the sample config file.
:param min: Optional check that value is greater than or equal to min.
:param max: Optional check that value is less than or equal to max.
- :param choices: Optional sequence of valid values.
+ :param choices: Optional sequence of either valid values or tuples of valid
+ values with descriptions.
.. versionadded:: 3.14
+
+ .. versionchanged:: 5.2
+ The *choices* parameter will now accept a sequence of tuples, where each
+ tuple is of form (*choice*, *description*)
"""
def __init__(self, num_type, type_name,
@@ -263,15 +281,24 @@
if min is not None and max is not None and max < min:
raise ValueError('Max value is less than min value')
- invalid_choices = [c for c in choices or []
+
+ if choices is not None:
+ if not all(isinstance(choice, tuple) for choice in choices):
+ choices = [(choice, None) for choice in choices]
+
+ self.choices = collections.OrderedDict(choices)
+ else:
+ self.choices = None
+
+ invalid_choices = [c for c in self.choices or []
if (min is not None and min > c)
or (max is not None and max < c)]
if invalid_choices:
raise ValueError("Choices %s are out of bounds [%s..%s]"
% (invalid_choices, min, max))
+
self.min = min
self.max = max
- self.choices = choices
self.num_type = num_type
def __call__(self, value):
@@ -297,7 +324,7 @@
def __repr__(self):
props = []
if self.choices is not None:
- props.append("choices={!r}".format(self.choices))
+ props.append("choices={!r}".format(list(self.choices.keys())))
else:
if self.min is not None:
props.append('min=%g' % self.min)
@@ -313,7 +340,8 @@
(self.__class__ == other.__class__) and
(self.min == other.min) and
(self.max == other.max) and
- (set(self.choices) == set(other.choices) if
+ (set([x for x in self.choices or []]) ==
+ set([x for x in other.choices or []]) if
self.choices and other.choices else
self.choices == other.choices)
)
@@ -332,7 +360,8 @@
:param min: Optional check that value is greater than or equal to min.
:param max: Optional check that value is less than or equal to max.
:param type_name: Type name to be used in the sample config file.
- :param choices: Optional sequence of valid values.
+ :param choices: Optional sequence of either valid values or tuples of valid
+ values with descriptions.
.. versionchanged:: 2.4
The class now honors zero for *min* and *max* parameters.
@@ -346,6 +375,10 @@
.. versionchanged:: 3.16
*choices* is no longer mutually exclusive with *min*/*max*. If those are
supplied, all choices are verified to be within the range.
+
+ .. versionchanged:: 5.2
+ The *choices* parameter will now accept a sequence of tuples, where each
+ tuple is of form (*choice*, *description*)
"""
def __init__(self, min=None, max=None, type_name='integer value',
@@ -385,9 +418,14 @@
:param min: Optional check that value is greater than or equal to min.
:param max: Optional check that value is less than or equal to max.
:param type_name: Type name to be used in the sample config file.
- :param choices: Optional sequence of valid values.
+ :param choices: Optional sequence of either valid values or tuples of valid
+ values with descriptions.
.. versionadded:: 3.16
+
+ .. versionchanged:: 5.2
+ The *choices* parameter will now accept a sequence of tuples, where each
+ tuple is of form (*choice*, *description*)
"""
PORT_MIN = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/oslo.config-5.1.0/releasenotes/notes/support-choice-descriptions-8b2d0c14fbd16b2a.yaml
new/oslo.config-5.2.0/releasenotes/notes/support-choice-descriptions-8b2d0c14fbd16b2a.yaml
---
old/oslo.config-5.1.0/releasenotes/notes/support-choice-descriptions-8b2d0c14fbd16b2a.yaml
1970-01-01 01:00:00.000000000 +0100
+++
new/oslo.config-5.2.0/releasenotes/notes/support-choice-descriptions-8b2d0c14fbd16b2a.yaml
2018-01-08 15:12:21.000000000 +0100
@@ -0,0 +1,14 @@
+---
+features:
+ - |
+ String, Number, Integer, Float and Port now support value-description
+ tuples in the interable provided for the *choice* parameter. Support for
+ value-only definitions is retained.
+ - |
+ StringOpt and PortOpt now support a value-description tuples in the
+ iterable provided for the *choice* parameter. Support for value-only
+ definitions is retained.
+ - |
+ *oslo-config-generator* and the Sphinx extension will now output
+ descriptions for option choices where provided. This will impact tooling
+ that relies on the *yaml* and *json* output of the former.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/tools/tox_install.sh
new/oslo.config-5.2.0/tools/tox_install.sh
--- old/oslo.config-5.1.0/tools/tox_install.sh 2017-11-20 17:25:42.000000000
+0100
+++ new/oslo.config-5.2.0/tools/tox_install.sh 1970-01-01 01:00:00.000000000
+0100
@@ -1,30 +0,0 @@
-#!/usr/bin/env bash
-
-# Client constraint file contains this client version pin that is in conflict
-# with installing the client from source. We should remove the version pin in
-# the constraints file before applying it for from-source installation.
-
-CONSTRAINTS_FILE="$1"
-shift 1
-
-set -e
-
-# NOTE(tonyb): Place this in the tox enviroment's log dir so it will get
-# published to logs.openstack.org for easy debugging.
-localfile="$VIRTUAL_ENV/log/upper-constraints.txt"
-
-if [[ "$CONSTRAINTS_FILE" != http* ]]; then
- CONSTRAINTS_FILE="file://$CONSTRAINTS_FILE"
-fi
-# NOTE(tonyb): need to add curl to bindep.txt if the project supports bindep
-curl "$CONSTRAINTS_FILE" --insecure --progress-bar --output "$localfile"
-
-pip install -c"$localfile" openstack-requirements
-
-# This is the main purpose of the script: Allow local installation of
-# the current repo. It is listed in constraints file and thus any
-# install will be constrained and we need to unconstrain it.
-edit-constraints "$localfile" -- "$CLIENT_NAME"
-
-pip install -c"$localfile" -U "$@"
-exit $?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/oslo.config-5.1.0/tox.ini
new/oslo.config-5.2.0/tox.ini
--- old/oslo.config-5.1.0/tox.ini 2017-11-20 17:25:42.000000000 +0100
+++ new/oslo.config-5.2.0/tox.ini 2018-01-08 15:11:54.000000000 +0100
@@ -4,12 +4,11 @@
envlist = py35,py27,pep8
[testenv]
-setenv =
- VIRTUAL_ENV={envdir}
- BRANCH_NAME=master
- CLIENT_NAME=oslo.config
-install_command = {toxinidir}/tools/tox_install.sh
{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
{opts} {packages}
-deps = -r{toxinidir}/test-requirements.txt
+install_command = pip install {opts} {packages}
+deps =
+
-c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -r{toxinidir}/test-requirements.txt
+ -r{toxinidir}/requirements.txt
commands =
python setup.py test --coverage --coverage-package-name=oslo_config
--slowest --testr-args='{posargs}'
coverage report --show-missing
@@ -32,7 +31,6 @@
commands = python setup.py build_sphinx
[testenv:bandit]
-deps = -r{toxinidir}/test-requirements.txt
commands = bandit -r oslo_config -x tests -n5
[flake8]