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
=== modified file 'NEWS.rst'
--- NEWS.rst 2021-05-18 16:43:39 +0000
+++ NEWS.rst 2021-05-18 16:43:39 +0000
@@ -10,6 +10,8 @@
1010
11Generate stable ETags for dict fields.11Generate stable ETags for dict fields.
1212
13Use a stable ordering for fields in entry representations.
14
131.0.2 (2021-05-14)151.0.2 (2021-05-14)
14==================16==================
1517
1618
=== modified file 'src/lazr/restful/_resource.py'
--- src/lazr/restful/_resource.py 2021-05-18 16:43:39 +0000
+++ src/lazr/restful/_resource.py 2021-05-18 16:43:39 +0000
@@ -29,6 +29,7 @@
29 'WADL_SCHEMA_FILE',29 'WADL_SCHEMA_FILE',
30 ]30 ]
3131
32from collections import OrderedDict
32from email.utils import formatdate33from email.utils import formatdate
33import copy34import copy
34from operator import itemgetter35from operator import itemgetter
@@ -1476,7 +1477,7 @@
1476 The values in the dictionary may differ depending on the value1477 The values in the dictionary may differ depending on the value
1477 of media_type.1478 of media_type.
1478 """1479 """
1479 data = {}1480 data = OrderedDict()
1480 data['self_link'] = absoluteURL(self.context, self.request)1481 data['self_link'] = absoluteURL(self.context, self.request)
1481 if self.adapter_utility.publish_web_link:1482 if self.adapter_utility.publish_web_link:
1482 # Objects in the web service correspond to pages on some website.1483 # Objects in the web service correspond to pages on some website.
14831484
=== modified file 'src/lazr/restful/docs/multiversion.rst'
--- src/lazr/restful/docs/multiversion.rst 2020-08-21 16:16:09 +0000
+++ src/lazr/restful/docs/multiversion.rst 2021-05-18 16:43:39 +0000
@@ -731,9 +731,10 @@
731 >>> print(absoluteURL(C1, request_beta))731 >>> print(absoluteURL(C1, request_beta))
732 http://api.multiversion.dev/beta/contact_list/Cleo%20Python732 http://api.multiversion.dev/beta/contact_list/Cleo%20Python
733733
734 >>> body = simplejson.loads(resource())734 >>> from collections import OrderedDict
735 >>> sorted(body.keys())735 >>> body = simplejson.loads(resource(), object_pairs_hook=OrderedDict)
736 ['fax', 'http_etag', 'name', 'phone', 'resource_type_link', 'self_link']736 >>> list(body)
737 ['self_link', 'resource_type_link', 'name', 'phone', 'fax', 'http_etag']
737 >>> print(body['name'])738 >>> print(body['name'])
738 Cleo Python739 Cleo Python
739740
@@ -826,10 +827,10 @@
826Note that the 'fax' and 'phone' fields are now called 'fax_number' and827Note that the 'fax' and 'phone' fields are now called 'fax_number' and
827'phone_number'.828'phone_number'.
828829
829 >>> body = simplejson.loads(resource())830 >>> body = simplejson.loads(resource(), object_pairs_hook=OrderedDict)
830 >>> sorted(body.keys())831 >>> list(body)
831 ['fax_number', 'http_etag', 'name', 'phone_number',832 ['self_link', 'resource_type_link', 'name', 'phone_number', 'fax_number',
832 'resource_type_link', 'self_link']833 'http_etag']
833 >>> print(body['name'])834 >>> print(body['name'])
834 Cleo Python835 Cleo Python
835836
@@ -945,9 +946,9 @@
945'1.0'. The phone field is still 'phone_number', but the 'fax_number'946'1.0'. The phone field is still 'phone_number', but the 'fax_number'
946field is gone.947field is gone.
947948
948 >>> body = simplejson.loads(resource())949 >>> body = simplejson.loads(resource(), object_pairs_hook=OrderedDict)
949 >>> sorted(body.keys())950 >>> list(body)
950 ['http_etag', 'name', 'phone_number', 'resource_type_link', 'self_link']951 ['self_link', 'resource_type_link', 'name', 'phone_number', 'http_etag']
951 >>> print(body['name'])952 >>> print(body['name'])
952 Cleo Python953 Cleo Python
953954
954955
=== modified file 'src/lazr/restful/example/base/tests/root.txt'
--- src/lazr/restful/example/base/tests/root.txt 2021-01-18 11:58:31 +0000
+++ src/lazr/restful/example/base/tests/root.txt 2021-05-18 16:43:39 +0000
@@ -88,7 +88,7 @@
88 >>> conditional_response.status88 >>> conditional_response.status
89 20089 200
90 >>> conditional_response.jsonBody()90 >>> conditional_response.jsonBody()
91 {...}91 OrderedDict(...)
9292
93You can specify a number of etags in If-None-Match. You'll get a new93You can specify a number of etags in If-None-Match. You'll get a new
94representation only if *none* of them match:94representation only if *none* of them match:
9595
=== modified file 'src/lazr/restful/example/multiversion/tests/introduction.txt'
--- src/lazr/restful/example/multiversion/tests/introduction.txt 2021-01-18 11:58:31 +0000
+++ src/lazr/restful/example/multiversion/tests/introduction.txt 2021-05-18 16:43:39 +0000
@@ -165,33 +165,33 @@
165 >>> def show_fields(version):165 >>> def show_fields(version):
166 ... entry_body = webservice.get(166 ... entry_body = webservice.get(
167 ... '/pairs/foo', api_version=version).jsonBody()167 ... '/pairs/foo', api_version=version).jsonBody()
168 ... for key in sorted(entry_body.keys()):168 ... for key in entry_body:
169 ... print(key)169 ... print(key)
170170
171 >>> show_fields('beta')171 >>> show_fields('beta')
172 self_link
173 resource_type_link
174 key
175 value
172 a_comment176 a_comment
173 http_etag177 http_etag
174 key
175 resource_type_link
176 self_link
177 value
178178
179 >>> show_fields('1.0')179 >>> show_fields('1.0')
180 self_link
181 resource_type_link
182 key
183 value
180 comment184 comment
181 http_etag185 http_etag
182 key
183 resource_type_link
184 self_link
185 value
186186
187 >>> show_fields('3.0')187 >>> show_fields('3.0')
188 self_link
189 resource_type_link
190 key
191 value
188 comment192 comment
189 deleted193 deleted
190 http_etag194 http_etag
191 key
192 resource_type_link
193 self_link
194 value
195195
196In the 'beta' version, attempting to delete a key-value pair will196In the 'beta' version, attempting to delete a key-value pair will
197result in a status code of 405 ("Method Not Available").197result in a status code of 405 ("Method Not Available").
198198
=== modified file 'src/lazr/restful/example/wsgi/tests/introduction.txt'
--- src/lazr/restful/example/wsgi/tests/introduction.txt 2020-09-07 09:54:10 +0000
+++ src/lazr/restful/example/wsgi/tests/introduction.txt 2021-05-18 16:43:39 +0000
@@ -28,13 +28,13 @@
28You can get an entry resource.28You can get an entry resource.
2929
30 >>> entry_resource = webservice.get("/pairs/1").jsonBody()30 >>> entry_resource = webservice.get("/pairs/1").jsonBody()
31 >>> for key in sorted(entry_resource.keys()):31 >>> for key in entry_resource:
32 ... print(key)32 ... print(key)
33 http_etag33 self_link
34 resource_type_link
34 key35 key
35 resource_type_link
36 self_link
37 value36 value
37 http_etag
3838
39You can get a field resource.39You can get a field resource.
4040
4141
=== modified file 'src/lazr/restful/testing/webservice.py'
--- src/lazr/restful/testing/webservice.py 2021-01-21 00:15:10 +0000
+++ src/lazr/restful/testing/webservice.py 2021-05-18 16:43:39 +0000
@@ -21,6 +21,7 @@
21 'WebServiceTestPublication',21 'WebServiceTestPublication',
22 ]22 ]
2323
24from collections import OrderedDict
24from email.utils import quote as email_quote25from email.utils import quote as email_quote
25import io26import io
26import random27import random
@@ -539,7 +540,7 @@
539 """Return the body of the web service request as a JSON document."""540 """Return the body of the web service request as a JSON document."""
540 body = six.ensure_text(self.body)541 body = six.ensure_text(self.body)
541 try:542 try:
542 return simplejson.loads(body)543 return simplejson.loads(body, object_pairs_hook=OrderedDict)
543 except ValueError:544 except ValueError:
544 # Return a useful ValueError that displays the problematic545 # Return a useful ValueError that displays the problematic
545 # string, instead of one that just says the string wasn't546 # string, instead of one that just says the string wasn't

Subscribers

People subscribed via source and target branches