Sort parameters on the URL to allow caching.

Python randomizes dict item order with a random seed, which changes every
time Python/Blender is run. As a result, Pillar GET parameters on the URL
would change, making them uncachable. Sorting the parameters solves this.
This commit is contained in:
2016-03-18 16:37:16 +01:00
parent 1ec234716a
commit 886e3c7eaf
2 changed files with 16 additions and 5 deletions

View File

@@ -51,15 +51,15 @@ def join_url_params(url, params):
def convert_to_string(param):
if isinstance(param, dict):
return json.dumps(param)
return json.dumps(param, sort_keys=True)
if isinstance(param, text_type):
return param.encode('utf-8')
return param
jsonified_params = {
key: convert_to_string(param)
for key, param in params.items()
}
# Pass as (key, value) pairs, so that the sorted order is maintained.
jsonified_params = [
(key, convert_to_string(params[key]))
for key in sorted(params.keys())]
return url + "?" + urlencode(jsonified_params)

View File

@@ -42,6 +42,17 @@ class PillarUtilsTests(unittest.TestCase):
self.assertEqual('url?dict=' + quote_plus(r'{"food": "\u0e1c\u0e31\u0e14\u0e44\u0e17\u0e22"}'),
utils.join_url_params('url', {'dict': {'food': 'ผัดไทย'}}))
def test_join_url_params_sorting(self):
# Different sorting than in the tests before, and using multiple keys per dict so
# that sorting is actually relevant.
self.assertEqual('url?after=haha+actually+before' +
'&dict=' + quote_plus(r'{"drinks": "water", "food": "\u0e1c\u0e31\u0e14\u0e44\u0e17\u0e22"}') +
'&last=yeah%2C+last',
utils.join_url_params('url', {'dict': {'food': 'ผัดไทย', 'drinks': 'water'},
'after': 'haha actually before',
'last': 'yeah, last'}))
def test_merge_dict(self):
self.assertEqual({1: 2, 'foo': 'bar', 'foo1': 'bar2'},
utils.merge_dict({"foo": "bar"}, {1: 2}, {"foo1": "bar2"}))