From 7883171eca469ab0314369d11c1e401e284ec66e Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Fri, 3 Mar 2017 15:10:31 +1100 Subject: [PATCH] Use unicode match for name_or_id The name_or_id field might be a unicode string. Make sure we don't run into problems comparing it by converting all comparison objects. This is a follow-on to Id89bbf6306adebe96c1db417a4b8b5ae51023af0 based on/as an alternative to I546b1fbd3375861173f411a7cfdb9e1baa5e6250 Closes-Bug: 1668849 Change-Id: I4e7fa49bd8525148961f02b0e0d7b567145a68b6 Co-Authored-By: Liu Qing --- shade/_utils.py | 29 +++++++++++++++++++++++++---- shade/tests/unit/test__utils.py | 17 +++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/shade/_utils.py b/shade/_utils.py index cbb9b7a13..38467785c 100644 --- a/shade/_utils.py +++ b/shade/_utils.py @@ -75,6 +75,25 @@ def _iterate_timeout(timeout, message, wait=2): raise exc.OpenStackCloudTimeout(message) +def _make_unicode(input): + """Turn an input into unicode unconditionally + + :param input: + A unicode, string or other object + """ + try: + if isinstance(input, unicode): + return input + if isinstance(input, str): + return input.decode('utf-8') + else: + # int, for example + return unicode(input) + except NameError: + # python3! + return str(input) + + def _filter_list(data, name_or_id, filters): """Filter a list by name/ID and arbitrary meta data. @@ -98,12 +117,14 @@ def _filter_list(data, name_or_id, filters): A string containing a jmespath expression for further filtering. """ if name_or_id: + # name_or_id might already be unicode + name_or_id = _make_unicode(name_or_id) identifier_matches = [] for e in data: - e_id = e.get('id', None) - e_name = e.get('name', None) - if ((e_id and str(e_id) == str(name_or_id)) or - (e_name and str(e_name) == str(name_or_id))): + e_id = _make_unicode(e.get('id', None)) + e_name = _make_unicode(e.get('name', None)) + if ((e_id and e_id == name_or_id) or + (e_name and e_name == name_or_id)): identifier_matches.append(e) data = identifier_matches diff --git a/shade/tests/unit/test__utils.py b/shade/tests/unit/test__utils.py index 6e611d73b..4b178e2fb 100644 --- a/shade/tests/unit/test__utils.py +++ b/shade/tests/unit/test__utils.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -47,6 +49,21 @@ class TestUtils(base.TestCase): ret = _utils._filter_list(data, 'pluto[2017-01-10]', None) self.assertEqual([el2], ret) + def test__filter_list_unicode(self): + el1 = dict(id=100, name=u'中文', last='duck', + other=dict(category='duck', financial=dict(status='poor'))) + el2 = dict(id=200, name=u'中文', last='trump', + other=dict(category='human', financial=dict(status='rich'))) + el3 = dict(id=300, name='donald', last='ronald mac', + other=dict(category='clown', financial=dict(status='rich'))) + data = [el1, el2, el3] + ret = _utils._filter_list( + data, u'中文', + {'other': { + 'financial': {'status': 'rich'} + }}) + self.assertEqual([el2], ret) + def test__filter_list_filter(self): el1 = dict(id=100, name='donald', other='duck') el2 = dict(id=200, name='donald', other='trump')