Merge lp:~billy-olsen/charm-helpers/lp1698343 into lp:charm-helpers

Proposed by Billy Olsen
Status: Merged
Merged at revision: 757
Proposed branch: lp:~billy-olsen/charm-helpers/lp1698343
Merge into: lp:charm-helpers
Diff against target: 112 lines (+56/-6)
2 files modified
charmhelpers/contrib/openstack/utils.py (+27/-6)
tests/contrib/openstack/test_os_utils.py (+29/-0)
To merge this branch: bzr merge lp:~billy-olsen/charm-helpers/lp1698343
Reviewer Review Type Date Requested Status
Jorge Niedbalski (community) Approve
Review via email: mp+326495@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jorge Niedbalski (niedbalski) wrote :

LGTM, I did some minor modifications to make lint pass/extended docstrings.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/contrib/openstack/utils.py'
2--- charmhelpers/contrib/openstack/utils.py 2017-06-22 14:57:18 +0000
3+++ charmhelpers/contrib/openstack/utils.py 2017-06-29 03:51:49 +0000
4@@ -1863,6 +1863,29 @@
5 return wrap
6
7
8+def ordered(orderme):
9+ """Converts the provided dictionary into a collections.OrderedDict.
10+
11+ The items in the returned OrderedDict will be inserted based on the
12+ natural sort order of the keys. Nested dictionaries will also be sorted
13+ in order to ensure fully predictable ordering.
14+
15+ :param orderme: the dict to order
16+ :return: collections.OrderedDict
17+ """
18+ if not isinstance(orderme, dict):
19+ raise ValueError('argument must be a dict type')
20+
21+ result = OrderedDict()
22+ for k, v in sorted(six.iteritems(orderme), key=lambda x: x[0]):
23+ if isinstance(v, dict):
24+ result[k] = ordered(v)
25+ else:
26+ result[k] = v
27+
28+ return result
29+
30+
31 def config_flags_parser(config_flags):
32 """Parses config flags string into dict.
33
34@@ -1874,15 +1897,13 @@
35 example, a string in the format of 'key1=value1, key2=value2' will
36 return a dict of:
37
38- {'key1': 'value1',
39- 'key2': 'value2'}.
40+ {'key1': 'value1', 'key2': 'value2'}.
41
42 2. A string in the above format, but supporting a comma-delimited list
43 of values for the same key. For example, a string in the format of
44 'key1=value1, key2=value3,value4,value5' will return a dict of:
45
46- {'key1', 'value1',
47- 'key2', 'value2,value3,value4'}
48+ {'key1': 'value1', 'key2': 'value2,value3,value4'}
49
50 3. A string containing a colon character (:) prior to an equal
51 character (=) will be treated as yaml and parsed as such. This can be
52@@ -1902,7 +1923,7 @@
53 equals = config_flags.find('=')
54 if colon > 0:
55 if colon < equals or equals < 0:
56- return yaml.safe_load(config_flags)
57+ return ordered(yaml.safe_load(config_flags))
58
59 if config_flags.find('==') >= 0:
60 juju_log("config_flags is not in expected format (key=value)",
61@@ -1915,7 +1936,7 @@
62 # split on '='.
63 split = config_flags.strip(' =').split('=')
64 limit = len(split)
65- flags = {}
66+ flags = OrderedDict()
67 for i in range(0, limit - 1):
68 current = split[i]
69 next = split[i + 1]
70
71=== modified file 'tests/contrib/openstack/test_os_utils.py'
72--- tests/contrib/openstack/test_os_utils.py 2017-06-22 14:57:18 +0000
73+++ tests/contrib/openstack/test_os_utils.py 2017-06-29 03:51:49 +0000
74@@ -1,5 +1,7 @@
75+import collections
76 import json
77 import mock
78+import six
79 import unittest
80 import six
81
82@@ -222,3 +224,30 @@
83 modified_policy.update(item_to_update)
84 mock_open().write.assert_called_with(
85 json.dumps(modified_policy, indent=4))
86+
87+ def test_ordered(self):
88+ data = {'one': 1, 'two': 2, 'three': 3}
89+ expected = [('one', 1), ('three', 3), ('two', 2)]
90+ self.assertSequenceEqual(expected,
91+ [x for x in utils.ordered(data).items()])
92+
93+ data = {
94+ 'one': 1,
95+ 'two': 2,
96+ 'three': {
97+ 'uno': 1,
98+ 'dos': 2,
99+ 'tres': 3
100+ }
101+ }
102+ expected = collections.OrderedDict()
103+ expected['one'] = 1
104+ nested = collections.OrderedDict()
105+ nested['dos'] = 2
106+ nested['tres'] = 3
107+ nested['uno'] = 1
108+ expected['three'] = nested
109+ expected['two'] = 2
110+ self.assertEqual(expected, utils.ordered(data))
111+
112+ self.assertRaises(ValueError, utils.ordered, "foo")

Subscribers

People subscribed via source and target branches