Merge lp:~cjwatson/lazr.restful/etag-json into lp:lazr.restful

Proposed by Colin Watson
Status: Merged
Merged at revision: 299
Proposed branch: lp:~cjwatson/lazr.restful/etag-json
Merge into: lp:lazr.restful
Prerequisite: lp:~cjwatson/lazr.restful/sorted-entry-representation
Diff against target: 72 lines (+20/-14)
3 files modified
NEWS.rst (+3/-0)
src/lazr/restful/_resource.py (+1/-14)
src/lazr/restful/tests/test_etag.py (+16/-0)
To merge this branch: bzr merge lp:~cjwatson/lazr.restful/etag-json
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+402920@code.launchpad.net

Commit message

Encode non-text/bytes field values for ETags using JSON.

Description of the change

Otherwise e.g. lists of strings were encoded as `[u'foo', u'bar']` on Python 2 but `['foo', 'bar']` on Python 3, causing ETag mismatches.

To post a comment you must log in.
Revision history for this message
Cristian Gonzalez (cristiangsp) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS.rst'
2--- NEWS.rst 2021-05-18 17:01:08 +0000
3+++ NEWS.rst 2021-05-18 17:01:08 +0000
4@@ -12,6 +12,9 @@
5
6 Use a stable ordering for fields in entry representations.
7
8+Stabilize ETags of entries containing collections of strings between Python
9+2 and 3 (bug 1928474).
10+
11 1.0.2 (2021-05-14)
12 ==================
13
14
15=== modified file 'src/lazr/restful/_resource.py'
16--- src/lazr/restful/_resource.py 2021-05-18 17:01:08 +0000
17+++ src/lazr/restful/_resource.py 2021-05-18 17:01:08 +0000
18@@ -160,20 +160,7 @@
19 elif isinstance(value, bytes):
20 return value.decode("utf-8")
21 else:
22- return six.text_type(value)
23-
24-
25-def encode_value(value):
26- """Return a UTF-8 string corresponding to `value`.
27-
28- Non-unicode strings are assumed to be UTF-8 already.
29- """
30- if isinstance(value, six.text_type):
31- return value.encode("utf-8")
32- elif isinstance(value, bytes):
33- return value
34- else:
35- return bytes(value)
36+ return simplejson.dumps(value)
37
38
39 def _default_html_renderer(value):
40
41=== modified file 'src/lazr/restful/tests/test_etag.py'
42--- src/lazr/restful/tests/test_etag.py 2021-01-20 23:45:18 +0000
43+++ src/lazr/restful/tests/test_etag.py 2021-05-18 17:01:08 +0000
44@@ -5,6 +5,7 @@
45
46 __metaclass__ = type
47
48+from collections import OrderedDict
49 import unittest
50
51 from zope.component import provideUtility
52@@ -80,6 +81,21 @@
53 [b'first-not-writable\x00second-not-writable',
54 b'first-writable\x00second-writable'])
55
56+ def test_collection_fields(self):
57+ # Field values that are something other than text or bytes are
58+ # encoded using JSON.
59+ field_details = [
60+ ('list_field',
61+ {'writable': False,
62+ 'value': ['first', 'second']}),
63+ ('dict_field',
64+ {'writable': False,
65+ 'value': OrderedDict((('first', 'one'), ('second', 'two')))}),
66+ ]
67+ self.assertEqual(
68+ make_entry_etag_cores(field_details),
69+ [b'["first", "second"]\0{"first": "one", "second": "two"}', b''])
70+
71
72 class TestHTTPResourceETags(unittest.TestCase):
73

Subscribers

People subscribed via source and target branches