Support schema types with non-str value

Change I75da1e9309e0f7ef8839dea3ec9c99c58edc5d63 introduced some
properties' types which are not string. This broke the `schema_args`
utility since lists are not hashable and there was no support for such
type values.

This patch fixes this issue with a very glance specific strategy in
which this values are assumed to have a `null` type and another type -
string, integer, etc. The fix ignores `null` options and it takes the
first non-null type as the valid one.

The patch adds support for enum types that accept `None`

Closes-bug: #1401032
Change-Id: I250e8912aca262a56c54ac59bb24f917e5d8cfce
This commit is contained in:
Flavio Percoco
2014-12-10 10:47:40 +01:00
parent 9829d7b6b9
commit 3989cd202d
2 changed files with 62 additions and 2 deletions

View File

@@ -81,6 +81,17 @@ def schema_args(schema_getter, omit=None):
kwargs = {}
type_str = property.get('type', 'string')
if isinstance(type_str, list):
# NOTE(flaper87): This means the server has
# returned something like `['null', 'string']`,
# therfore we use the first non-`null` type as
# the valid type.
for t in type_str:
if t != 'null':
type_str = t
break
if type_str == 'array':
items = property.get('items')
kwargs['type'] = typemap.get(items.get('type'))
@@ -97,8 +108,13 @@ def schema_args(schema_getter, omit=None):
if 'enum' in property:
if len(description):
description += " "
description += ("Valid values: " +
', '.join(property.get('enum')))
# NOTE(flaper87): Make sure all values are `str/unicode`
# for the `join` to succeed. Enum types can also be `None`
# therfore, join's call would fail without the following
# list comprehension
vals = [six.text_type(val) for val in property.get('enum')]
description += ('Valid values: ' + ', '.join(vals))
kwargs['help'] = description
func.__dict__.setdefault('arguments',

View File

@@ -117,3 +117,47 @@ class TestUtils(testtools.TestCase):
ret = utils.exception_to_str(FakeException('\xa5 error message'))
self.assertEqual("Caught '%(exception)s' exception." %
{'exception': 'FakeException'}, ret)
def test_schema_args_with_list_types(self):
# NOTE(flaper87): Regression for bug
# https://bugs.launchpad.net/python-glanceclient/+bug/1401032
def schema_getter(_type='string', enum=False):
prop = {
'type': ['null', _type],
'description': 'Test schema (READ-ONLY)',
}
if enum:
prop['enum'] = [None, 'opt-1', 'opt-2']
def actual_getter():
return {
'additionalProperties': False,
'required': ['name'],
'name': 'test_schema',
'properties': {
'test': prop,
}
}
return actual_getter
def dummy_func():
pass
decorated = utils.schema_args(schema_getter())(dummy_func)
arg, opts = decorated.__dict__['arguments'][0]
self.assertIn('--test', arg)
self.assertEqual(str, opts['type'])
decorated = utils.schema_args(schema_getter('integer'))(dummy_func)
arg, opts = decorated.__dict__['arguments'][0]
self.assertIn('--test', arg)
self.assertEqual(int, opts['type'])
decorated = utils.schema_args(schema_getter(enum=True))(dummy_func)
arg, opts = decorated.__dict__['arguments'][0]
self.assertIn('--test', arg)
self.assertEqual(str, opts['type'])
self.assertIn('None, opt-1, opt-2', opts['help'])