Merge lp:~wallyworld/lazr.restful/dict-marshalling-default-key-value-types into lp:lazr.restful

Proposed by Ian Booth
Status: Merged
Approved by: Ian Booth
Approved revision: 202
Merged at revision: 200
Proposed branch: lp:~wallyworld/lazr.restful/dict-marshalling-default-key-value-types
Merge into: lp:lazr.restful
Diff against target: 144 lines (+41/-15)
4 files modified
src/lazr/restful/NEWS.txt (+7/-0)
src/lazr/restful/docs/webservice-marshallers.txt (+25/-8)
src/lazr/restful/marshallers.py (+8/-6)
src/lazr/restful/version.txt (+1/-1)
To merge this branch: bzr merge lp:~wallyworld/lazr.restful/dict-marshalling-default-key-value-types
Reviewer Review Type Date Requested Status
Steve Kowalik (community) code Approve
Review via email: mp+97564@code.launchpad.net

Commit message

Improve the collection field marshallers so that if the fields haven't specified key and/or value types, the default marshallers are used for the collection elements.

Description of the change

== Implementation ==

Improve the collection field marshallers so that if the fields haven't specified key and/or value types, the default marshallers are used for the collection elements. This was needed because of an error unmarshalling a return value of type Dict in Launchpad. While I was fixing this, I also added the improvement to AbstractCollectionMarshaller.

Some drive-by lint also.

== Tests ==

Add new tests to webservice-marshallers.txt

== Lint ==

Linting changed files:
  src/lazr/restful/NEWS.txt
  src/lazr/restful/marshallers.py
  src/lazr/restful/version.txt
  src/lazr/restful/docs/webservice-marshallers.txt

To post a comment you must log in.
Revision history for this message
Steve Kowalik (stevenk) wrote :

Looks broadly good, I'm a little unhappy about the amount you have repeated getMultiAdapter with similar arguments in the marshaling code -- I'm not going to block on it, but I'd like you to have a think about a cleaner way to implement your changes.

review: Approve (code)
Revision history for this message
Ian Booth (wallyworld) wrote :

> Looks broadly good, I'm a little unhappy about the amount you have repeated
> getMultiAdapter with similar arguments in the marshaling code -- I'm not going
> to block on it, but I'd like you to have a think about a cleaner way to
> implement your changes.

Yes, good point.

    self.value_marshaller = getMultiAdapter(
        (field.value_type or Field(), request), IFieldMarshaller)

is much nicer.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/lazr/restful/NEWS.txt'
2--- src/lazr/restful/NEWS.txt 2012-03-13 02:03:47 +0000
3+++ src/lazr/restful/NEWS.txt 2012-03-15 03:35:20 +0000
4@@ -2,6 +2,13 @@
5 NEWS for lazr.restful
6 =====================
7
8+0.19.6 (2012-03-15)
9+===================
10+
11+Fixed bug 955668: make marshallers work correctly for collection fields
12+(Set, List, Dict) where the key and/or value types have not been specified.
13+In such cases, the default marshaller is used for the collection elements.
14+
15 0.19.5 (2012-03-13)
16 ===================
17
18
19=== modified file 'src/lazr/restful/docs/webservice-marshallers.txt'
20--- src/lazr/restful/docs/webservice-marshallers.txt 2012-03-13 23:47:22 +0000
21+++ src/lazr/restful/docs/webservice-marshallers.txt 2012-03-15 03:35:20 +0000
22@@ -701,7 +701,8 @@
23 collection marshaller will take care of marshalling to the proper
24 collection type, and of marshalling the individual items using the
25 marshaller for its value_type. Dictionaries may specify separate
26-marshallers for their keys and values.
27+marshallers for their keys and values. If no key and/or value marshallers
28+are specified, the default SimpleFieldMarshaller is used.
29
30 >>> from zope.schema import Dict, List, Tuple, Set
31 >>> list_of_strings_field = List(value_type=Text())
32@@ -709,17 +710,27 @@
33 >>> tuple_of_ints_field = Tuple(value_type=Int())
34 >>> list_of_choices_field = List(
35 ... value_type=Choice(vocabulary=Cuisine))
36+ >>> simple_list_field = List()
37 >>> set_of_choices_field = Set(
38 ... value_type=Choice(vocabulary=Cuisine)).bind(None)
39 >>> dict_of_choices_field = Dict(
40 ... key_type=Text(),
41 ... value_type=Choice(vocabulary=Cuisine))
42+ >>> simple_dict_field = Dict()
43
44 >>> list_marshaller = getMultiAdapter(
45 ... (list_of_strings_field, request), IFieldMarshaller)
46 >>> verifyObject(IFieldMarshaller, list_marshaller)
47 True
48
49+ >>> simple_list_marshaller = getMultiAdapter(
50+ ... (simple_list_field, request), IFieldMarshaller)
51+ >>> verifyObject(IFieldMarshaller, simple_list_marshaller)
52+ True
53+ >>> verifyObject(
54+ ... IFieldMarshaller, simple_list_marshaller.value_marshaller)
55+ True
56+
57 >>> tuple_marshaller = getMultiAdapter(
58 ... (tuple_of_ints_field, request), IFieldMarshaller)
59 >>> verifyObject(IFieldMarshaller, tuple_marshaller)
60@@ -739,13 +750,19 @@
61 ... (dict_of_choices_field, request), IFieldMarshaller)
62 >>> verifyObject(IFieldMarshaller, dict_marshaller)
63 True
64- >>> dict_key_marshaller = getMultiAdapter(
65- ... (dict_of_choices_field.key_type, request), IFieldMarshaller)
66- >>> verifyObject(IFieldMarshaller, dict_key_marshaller)
67- True
68- >>> dict_value_marshaller = getMultiAdapter(
69- ... (dict_of_choices_field.value_type, request), IFieldMarshaller)
70- >>> verifyObject(IFieldMarshaller, dict_value_marshaller)
71+ >>> verifyObject(IFieldMarshaller, dict_marshaller.key_marshaller)
72+ True
73+ >>> verifyObject(IFieldMarshaller, dict_marshaller.value_marshaller)
74+ True
75+
76+ >>> simple_dict_marshaller = getMultiAdapter(
77+ ... (simple_dict_field, request), IFieldMarshaller)
78+ >>> verifyObject(IFieldMarshaller, simple_dict_marshaller)
79+ True
80+ >>> verifyObject(IFieldMarshaller, simple_dict_marshaller.key_marshaller)
81+ True
82+ >>> verifyObject(
83+ ... IFieldMarshaller, simple_dict_marshaller.value_marshaller)
84 True
85
86 For sequences, the only JSON representation for the collection itself is a
87
88=== modified file 'src/lazr/restful/marshallers.py'
89--- src/lazr/restful/marshallers.py 2012-03-13 23:47:22 +0000
90+++ src/lazr/restful/marshallers.py 2012-03-15 03:35:20 +0000
91@@ -39,6 +39,7 @@
92 )
93 from zope.interface import implements
94 from zope.publisher.interfaces import NotFound
95+from zope.schema import Field
96 from zope.security.proxy import removeSecurityProxy
97 from zope.traversing.browser import absoluteURL
98
99@@ -403,7 +404,7 @@
100 super(AbstractCollectionFieldMarshaller, self).__init__(
101 field, request)
102 self.value_marshaller = getMultiAdapter(
103- (field.value_type, request), IFieldMarshaller)
104+ (field.value_type or Field(), request), IFieldMarshaller)
105
106 def _marshall_from_json_data(self, value):
107 """See `SimpleFieldMarshaller`.
108@@ -475,14 +476,15 @@
109 """See `SimpleFieldMarshaller`.
110
111 This also looks for the appropriate marshaller for key_type and
112- value_type.
113+ value_type. If key_type or value_type are not specified, the default
114+ field marshaller is used.
115 """
116 super(DictFieldMarshaller, self).__init__(
117 field, request)
118 self.key_marshaller = getMultiAdapter(
119- (field.key_type, request), IFieldMarshaller)
120+ (field.key_type or Field(), request), IFieldMarshaller)
121 self.value_marshaller = getMultiAdapter(
122- (field.value_type, request), IFieldMarshaller)
123+ (field.value_type or Field(), request), IFieldMarshaller)
124
125 def _marshall_from_request(self, value):
126 """See `IFieldMarshaller`.
127@@ -492,8 +494,8 @@
128
129 When coming in via HTML request parameters, the dict is sent as a list
130 of comma separated "key,value" strings.
131- If the value isn't a list or dict, transform it into a one-element list.
132- That allows web client to submit one-element list of strings
133+ If the value isn't a list or dict, transform it into a one-element
134+ list. That allows web client to submit one-element list of strings
135 without having to JSON-encode it.
136 """
137 if not isinstance(value, list) and not isinstance(value, dict):
138
139=== modified file 'src/lazr/restful/version.txt'
140--- src/lazr/restful/version.txt 2012-03-13 02:03:47 +0000
141+++ src/lazr/restful/version.txt 2012-03-15 03:35:20 +0000
142@@ -1,1 +1,1 @@
143-0.19.5
144+0.19.6

Subscribers

People subscribed via source and target branches