Merge lp:~cjwatson/lazr.restful/sorted-entry-representation into lp:lazr.restful

Proposed by Colin Watson
Status: Merged
Merged at revision: 298
Proposed branch: lp:~cjwatson/lazr.restful/sorted-entry-representation
Merge into: lp:lazr.restful
Prerequisite: lp:~cjwatson/lazr.restful/stable-dict-etag
Diff against target: 186 lines (+35/-30)
7 files modified
NEWS.rst (+2/-0)
src/lazr/restful/_resource.py (+2/-1)
src/lazr/restful/docs/multiversion.rst (+11/-10)
src/lazr/restful/example/base/tests/root.txt (+1/-1)
src/lazr/restful/example/multiversion/tests/introduction.txt (+13/-13)
src/lazr/restful/example/wsgi/tests/introduction.txt (+4/-4)
src/lazr/restful/testing/webservice.py (+2/-1)
To merge this branch: bzr merge lp:~cjwatson/lazr.restful/sorted-entry-representation
Reviewer Review Type Date Requested Status
Cristian Gonzalez (community) Approve
Review via email: mp+402916@code.launchpad.net

Commit message

Use a stable ordering for fields in entry representations.

Description of the change

This isn't essential for correctness, but it makes debugging easier.

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 16:43:39 +0000
3+++ NEWS.rst 2021-05-18 16:43:39 +0000
4@@ -10,6 +10,8 @@
5
6 Generate stable ETags for dict fields.
7
8+Use a stable ordering for fields in entry representations.
9+
10 1.0.2 (2021-05-14)
11 ==================
12
13
14=== modified file 'src/lazr/restful/_resource.py'
15--- src/lazr/restful/_resource.py 2021-05-18 16:43:39 +0000
16+++ src/lazr/restful/_resource.py 2021-05-18 16:43:39 +0000
17@@ -29,6 +29,7 @@
18 'WADL_SCHEMA_FILE',
19 ]
20
21+from collections import OrderedDict
22 from email.utils import formatdate
23 import copy
24 from operator import itemgetter
25@@ -1476,7 +1477,7 @@
26 The values in the dictionary may differ depending on the value
27 of media_type.
28 """
29- data = {}
30+ data = OrderedDict()
31 data['self_link'] = absoluteURL(self.context, self.request)
32 if self.adapter_utility.publish_web_link:
33 # Objects in the web service correspond to pages on some website.
34
35=== modified file 'src/lazr/restful/docs/multiversion.rst'
36--- src/lazr/restful/docs/multiversion.rst 2020-08-21 16:16:09 +0000
37+++ src/lazr/restful/docs/multiversion.rst 2021-05-18 16:43:39 +0000
38@@ -731,9 +731,10 @@
39 >>> print(absoluteURL(C1, request_beta))
40 http://api.multiversion.dev/beta/contact_list/Cleo%20Python
41
42- >>> body = simplejson.loads(resource())
43- >>> sorted(body.keys())
44- ['fax', 'http_etag', 'name', 'phone', 'resource_type_link', 'self_link']
45+ >>> from collections import OrderedDict
46+ >>> body = simplejson.loads(resource(), object_pairs_hook=OrderedDict)
47+ >>> list(body)
48+ ['self_link', 'resource_type_link', 'name', 'phone', 'fax', 'http_etag']
49 >>> print(body['name'])
50 Cleo Python
51
52@@ -826,10 +827,10 @@
53 Note that the 'fax' and 'phone' fields are now called 'fax_number' and
54 'phone_number'.
55
56- >>> body = simplejson.loads(resource())
57- >>> sorted(body.keys())
58- ['fax_number', 'http_etag', 'name', 'phone_number',
59- 'resource_type_link', 'self_link']
60+ >>> body = simplejson.loads(resource(), object_pairs_hook=OrderedDict)
61+ >>> list(body)
62+ ['self_link', 'resource_type_link', 'name', 'phone_number', 'fax_number',
63+ 'http_etag']
64 >>> print(body['name'])
65 Cleo Python
66
67@@ -945,9 +946,9 @@
68 '1.0'. The phone field is still 'phone_number', but the 'fax_number'
69 field is gone.
70
71- >>> body = simplejson.loads(resource())
72- >>> sorted(body.keys())
73- ['http_etag', 'name', 'phone_number', 'resource_type_link', 'self_link']
74+ >>> body = simplejson.loads(resource(), object_pairs_hook=OrderedDict)
75+ >>> list(body)
76+ ['self_link', 'resource_type_link', 'name', 'phone_number', 'http_etag']
77 >>> print(body['name'])
78 Cleo Python
79
80
81=== modified file 'src/lazr/restful/example/base/tests/root.txt'
82--- src/lazr/restful/example/base/tests/root.txt 2021-01-18 11:58:31 +0000
83+++ src/lazr/restful/example/base/tests/root.txt 2021-05-18 16:43:39 +0000
84@@ -88,7 +88,7 @@
85 >>> conditional_response.status
86 200
87 >>> conditional_response.jsonBody()
88- {...}
89+ OrderedDict(...)
90
91 You can specify a number of etags in If-None-Match. You'll get a new
92 representation only if *none* of them match:
93
94=== modified file 'src/lazr/restful/example/multiversion/tests/introduction.txt'
95--- src/lazr/restful/example/multiversion/tests/introduction.txt 2021-01-18 11:58:31 +0000
96+++ src/lazr/restful/example/multiversion/tests/introduction.txt 2021-05-18 16:43:39 +0000
97@@ -165,33 +165,33 @@
98 >>> def show_fields(version):
99 ... entry_body = webservice.get(
100 ... '/pairs/foo', api_version=version).jsonBody()
101- ... for key in sorted(entry_body.keys()):
102+ ... for key in entry_body:
103 ... print(key)
104
105 >>> show_fields('beta')
106+ self_link
107+ resource_type_link
108+ key
109+ value
110 a_comment
111 http_etag
112- key
113- resource_type_link
114- self_link
115- value
116
117 >>> show_fields('1.0')
118+ self_link
119+ resource_type_link
120+ key
121+ value
122 comment
123 http_etag
124- key
125- resource_type_link
126- self_link
127- value
128
129 >>> show_fields('3.0')
130+ self_link
131+ resource_type_link
132+ key
133+ value
134 comment
135 deleted
136 http_etag
137- key
138- resource_type_link
139- self_link
140- value
141
142 In the 'beta' version, attempting to delete a key-value pair will
143 result in a status code of 405 ("Method Not Available").
144
145=== modified file 'src/lazr/restful/example/wsgi/tests/introduction.txt'
146--- src/lazr/restful/example/wsgi/tests/introduction.txt 2020-09-07 09:54:10 +0000
147+++ src/lazr/restful/example/wsgi/tests/introduction.txt 2021-05-18 16:43:39 +0000
148@@ -28,13 +28,13 @@
149 You can get an entry resource.
150
151 >>> entry_resource = webservice.get("/pairs/1").jsonBody()
152- >>> for key in sorted(entry_resource.keys()):
153+ >>> for key in entry_resource:
154 ... print(key)
155- http_etag
156+ self_link
157+ resource_type_link
158 key
159- resource_type_link
160- self_link
161 value
162+ http_etag
163
164 You can get a field resource.
165
166
167=== modified file 'src/lazr/restful/testing/webservice.py'
168--- src/lazr/restful/testing/webservice.py 2021-01-21 00:15:10 +0000
169+++ src/lazr/restful/testing/webservice.py 2021-05-18 16:43:39 +0000
170@@ -21,6 +21,7 @@
171 'WebServiceTestPublication',
172 ]
173
174+from collections import OrderedDict
175 from email.utils import quote as email_quote
176 import io
177 import random
178@@ -539,7 +540,7 @@
179 """Return the body of the web service request as a JSON document."""
180 body = six.ensure_text(self.body)
181 try:
182- return simplejson.loads(body)
183+ return simplejson.loads(body, object_pairs_hook=OrderedDict)
184 except ValueError:
185 # Return a useful ValueError that displays the problematic
186 # string, instead of one that just says the string wasn't

Subscribers

People subscribed via source and target branches