Skip to content

Commit dd20c01

Browse files
authored
Merge pull request #4 from petahz/dicts-and-sets-args-order
Dicts and sets args order
2 parents ee47351 + c10eed1 commit dd20c01

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

.travis.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
language: python
22
python:
3-
- 2.7
43
- 3.4
54
env:
6-
- DJANGO_VERSION=1.5.12
7-
- DJANGO_VERSION=1.6.10
8-
- DJANGO_VERSION=1.7.7
5+
- DJANGO_VERSION=1.8.17
96
install:
107
# Install django/nose
118
- pip install Django==$DJANGO_VERSION
129
- pip install django-nose
1310
# Install cache helper
1411
- pip install -e .
12+
- pip install pylibmc
1513
script:
1614
- python test_project/manage.py test

cache_helper/utils.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,31 @@ def _plumb_collections(input_item):
120120
# this if statement. That's why we do `not isinstance(current_item, str)` check as well.
121121
if hasattr(current_item, '__iter__') and not isinstance(current_item, str):
122122
return_list.append(',')
123+
124+
# Dictionaries and sets are unordered and can be of various data types
125+
# We use the sha256 hash on keys and sort to be deterministic
123126
if isinstance(current_item, dict):
127+
hashed_list = []
128+
129+
for k, v in current_item.items():
130+
hashed_list.append((sha256(str(k).encode('utf-8')).hexdigest(), v))
131+
132+
hashed_list = sorted(hashed_list, key=lambda t: t[0])
124133
remains.append(current_iterator)
125-
remains.append([(k,v) for k, v in current_item.items()].__iter__())
134+
remains.append(hashed_list.__iter__())
135+
126136
level -= 1
127137
break
138+
elif isinstance(current_item, set):
139+
hashed_list = []
140+
141+
for item in current_item:
142+
hashed_list.append(sha256(str(item).encode('utf-8')).hexdigest())
143+
144+
hashed_list = sorted(hashed_list)
145+
remains.append(current_iterator)
146+
remains.append(hashed_list.__iter__())
147+
break
128148
else:
129149
remains.append(current_iterator)
130150
remains.append(current_item.__iter__())

test_project/tests.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,10 @@ def test_keys_are_truncated_beyond_250_chars(self):
123123
except Exception:
124124
self.fail('Keys are not being correctly truncated.')
125125

126+
from hashlib import sha256
126127

127128
class KeyCreationTestCase(TestCase):
129+
128130
def setUp(self):
129131
self.apple = Fruit('Apple')
130132
self.cherry = Fruit('Cherry')
@@ -141,7 +143,23 @@ def test_args_kwargs_properly_convert_to_string(self):
141143

142144
def test_dict_args_properly_convert_to_string(self):
143145
same_cherry = self.apple.take_then_give_back({1: self.cherry})
144-
self.assertTrue('tests.Fruit.take_then_give_back:42;mynameisapple,,,1,mynameischerry;' in cache)
146+
hashed_key = sha256(str(1).encode('utf-8')).hexdigest()
147+
self.assertTrue('tests.Fruit.take_then_give_back:42;mynameisapple,,,{0},mynameischerry;'.format(hashed_key) in cache)
148+
149+
def test_dict_args_keep_the_same_order_when_convert_to_string(self):
150+
dict_arg = {1: self.cherry, 'string': 'ay carambe'}
151+
same_multi_dict = self.apple.take_then_give_back(dict_arg)
152+
153+
self.assertTrue('tests.Fruit.take_then_give_back:42;mynameisapple,,,'
154+
'473287f8298dba7163a897908958f7c0eae733e25d2e027992ea2edc9bed2fa8,aycarambe,,'
155+
'6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b,mynameischerry;' in cache)
156+
157+
def test_set_args_properly_maintain_order_and_convert_to_string(self):
158+
same_set = self.apple.take_then_give_back({1,'vegetable', self.cherry})
159+
self.assertTrue('tests.Fruit.take_then_give_back:42;mynameisapple,,'
160+
'4715b734085d8d9c9981d91c6d5cff398c75caf44074851baa94f2de24fba4d7,'
161+
'6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b,'
162+
'f8201a5264b6b89b4d92c5bc46aa2e5c3e9610e8fc9ef200df1a39c7f10e7af6;' in cache)
145163

146164
def test_list_args_properly_convert_to_string(self):
147165
same_cherry = self.apple.take_then_give_back([self.cherry])

0 commit comments

Comments
 (0)