From 195add500bac78637f94a008feee986b7800968d Mon Sep 17 00:00:00 2001 From: Abijitha Nadagouda Date: Fri, 2 Feb 2018 10:26:23 +0530 Subject: [PATCH] Removes unicode 'u' response from "glance image-tag-update" "glance image-tag-update" command returns unicoded response for lists. Therefore it requires print_list method from util class to handle such case. Added unicode_key_value_to_string() method to remove extra 'u' from lists and dictionaries. This fix is inspired from cinderclient's implementation. Change-Id: I16a04e8d34f7629f72fe389456001ca1db9335ea Closes-bug: #1534046 --- glanceclient/common/utils.py | 31 +++++++++++++++++++++++ glanceclient/tests/unit/test_utils.py | 36 +++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py index d194e65b..487a711c 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -177,6 +177,12 @@ def pretty_choice_list(l): def print_list(objs, fields, formatters=None, field_settings=None): + '''Prints a list of objects. + + @param objs: Objects to print + @param fields: Fields on each object to be printed + @param formatters: Custom field formatters + ''' formatters = formatters or {} field_settings = field_settings or {} pt = prettytable.PrettyTable([f for f in fields], caching=False) @@ -196,11 +202,36 @@ def print_list(objs, fields, formatters=None, field_settings=None): field_name = field.lower().replace(' ', '_') data = getattr(o, field_name, None) or '' row.append(data) + count = 0 + # Converts unicode values in list to string + for part in row: + count = count + 1 + if isinstance(part, list): + part = unicode_key_value_to_string(part) + row[count - 1] = part pt.add_row(row) print(encodeutils.safe_decode(pt.get_string())) +def _encode(src): + """remove extra 'u' in PY2.""" + if six.PY2 and isinstance(src, unicode): + return src.encode('utf-8') + return src + + +def unicode_key_value_to_string(src): + """Recursively converts dictionary keys to strings.""" + if isinstance(src, dict): + return dict((_encode(k), + _encode(unicode_key_value_to_string(v))) + for k, v in src.items()) + if isinstance(src, list): + return [unicode_key_value_to_string(l) for l in src] + return _encode(src) + + def print_dict(d, max_column_width=80): pt = prettytable.PrettyTable(['Property', 'Value'], caching=False) pt.align = 'l' diff --git a/glanceclient/tests/unit/test_utils.py b/glanceclient/tests/unit/test_utils.py index cd87e215..a63ee803 100644 --- a/glanceclient/tests/unit/test_utils.py +++ b/glanceclient/tests/unit/test_utils.py @@ -115,6 +115,42 @@ class TestUtils(testtools.TestCase): ''', output_dict.getvalue()) + def test_print_list_with_list_no_unicode(self): + class Struct(object): + def __init__(self, **entries): + self.__dict__.update(entries) + + # test for removing 'u' from lists in print_list output + columns = ['ID', 'Tags'] + images = [Struct(**{'id': 'b8e1c57e-907a-4239-aed8-0df8e54b8d2d', + 'tags': [u'Name1', u'Tag_123', u'veeeery long']})] + saved_stdout = sys.stdout + try: + sys.stdout = output_list = six.StringIO() + utils.print_list(images, columns) + + finally: + sys.stdout = saved_stdout + + self.assertEqual('''\ ++--------------------------------------+--------------------------------------+ +| ID | Tags | ++--------------------------------------+--------------------------------------+ +| b8e1c57e-907a-4239-aed8-0df8e54b8d2d | ['Name1', 'Tag_123', 'veeeery long'] | ++--------------------------------------+--------------------------------------+ +''', + output_list.getvalue()) + + def test_unicode_key_value_to_string(self): + src = {u'key': u'\u70fd\u7231\u5a77'} + expected = {'key': '\xe7\x83\xbd\xe7\x88\xb1\xe5\xa9\xb7'} + if six.PY2: + self.assertEqual(expected, utils.unicode_key_value_to_string(src)) + else: + # u'xxxx' in PY3 is str, we will not get extra 'u' from cli + # output in PY3 + self.assertEqual(src, utils.unicode_key_value_to_string(src)) + def test_schema_args_with_list_types(self): # NOTE(flaper87): Regression for bug # https://bugs.launchpad.net/python-glanceclient/+bug/1401032