Merge ~cjwatson/lazr.restful:pyupgrade-py3 into lazr.restful:main
- Git
- lp:~cjwatson/lazr.restful
- pyupgrade-py3
- Merge into main
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | 6f588c2bd39e71694dd66d6f76a7c11a0826b2ce |
Proposed branch: | ~cjwatson/lazr.restful:pyupgrade-py3 |
Merge into: | lazr.restful:main |
Diff against target: |
3006 lines (+305/-532) 53 files modified
.pre-commit-config.yaml (+1/-1) pyproject.toml (+1/-1) src/lazr/restful/__init__.py (+0/-2) src/lazr/restful/_bytestorage.py (+0/-3) src/lazr/restful/_operation.py (+6/-12) src/lazr/restful/_resource.py (+29/-39) src/lazr/restful/debug.py (+0/-3) src/lazr/restful/declarations.py (+10/-19) src/lazr/restful/directives/__init__.py (+0/-3) src/lazr/restful/docs/conf.py (+7/-9) src/lazr/restful/error.py (+0/-3) src/lazr/restful/example/base/filemanager.py (+0/-3) src/lazr/restful/example/base/interfaces.py (+28/-33) src/lazr/restful/example/base/root.py (+10/-13) src/lazr/restful/example/base/security.py (+0/-3) src/lazr/restful/example/base/subscribers.py (+0/-3) src/lazr/restful/example/base/tests/test_integration.py (+1/-9) src/lazr/restful/example/base/traversal.py (+1/-6) src/lazr/restful/example/base_extended/comments.py (+1/-3) src/lazr/restful/example/base_extended/tests/test_integration.py (+1/-8) src/lazr/restful/example/multiversion/resources.py (+5/-9) src/lazr/restful/example/multiversion/root.py (+0/-3) src/lazr/restful/example/multiversion/tests/test_integration.py (+1/-8) src/lazr/restful/example/wsgi/resources.py (+3/-7) src/lazr/restful/example/wsgi/root.py (+0/-3) src/lazr/restful/example/wsgi/run.py (+0/-2) src/lazr/restful/example/wsgi/tests/test_integration.py (+1/-8) src/lazr/restful/fields.py (+2/-5) src/lazr/restful/frameworks/django.py (+2/-3) src/lazr/restful/interface.py (+0/-3) src/lazr/restful/interfaces/__init__.py (+0/-2) src/lazr/restful/interfaces/_fields.py (+0/-3) src/lazr/restful/interfaces/_rest.py (+39/-42) src/lazr/restful/jsoncache.py (+0/-4) src/lazr/restful/marshallers.py (+27/-45) src/lazr/restful/metazcml.py (+1/-4) src/lazr/restful/publisher.py (+4/-11) src/lazr/restful/security.py (+0/-3) src/lazr/restful/simple.py (+4/-10) src/lazr/restful/tales.py (+5/-11) src/lazr/restful/testing/event.py (+0/-4) src/lazr/restful/testing/helpers.py (+0/-2) src/lazr/restful/testing/tales.py (+0/-4) src/lazr/restful/testing/webservice.py (+14/-18) src/lazr/restful/tests/test_declarations.py (+40/-42) src/lazr/restful/tests/test_docs.py (+1/-9) src/lazr/restful/tests/test_error.py (+3/-7) src/lazr/restful/tests/test_etag.py (+6/-10) src/lazr/restful/tests/test_navigation.py (+6/-10) src/lazr/restful/tests/test_utils.py (+1/-5) src/lazr/restful/tests/test_webservice.py (+37/-46) src/lazr/restful/utils.py (+7/-10) src/lazr/restful/wsgi.py (+0/-3) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jürgen Gmach | Approve | ||
Review via email: mp+413604@code.launchpad.net |
Commit message
Apply pyupgrade --py3-plus
Description of the change
To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml | |||
2 | index 6f75344..6b363b1 100644 | |||
3 | --- a/.pre-commit-config.yaml | |||
4 | +++ b/.pre-commit-config.yaml | |||
5 | @@ -23,7 +23,7 @@ repos: | |||
6 | 23 | rev: v2.29.0 | 23 | rev: v2.29.0 |
7 | 24 | hooks: | 24 | hooks: |
8 | 25 | - id: pyupgrade | 25 | - id: pyupgrade |
10 | 26 | args: [--keep-percent-format] | 26 | args: [--keep-percent-format, --py3-plus] |
11 | 27 | - repo: https://github.com/psf/black | 27 | - repo: https://github.com/psf/black |
12 | 28 | rev: 21.10b0 | 28 | rev: 21.10b0 |
13 | 29 | hooks: | 29 | hooks: |
14 | diff --git a/pyproject.toml b/pyproject.toml | |||
15 | index 486bbe6..1f331da 100644 | |||
16 | --- a/pyproject.toml | |||
17 | +++ b/pyproject.toml | |||
18 | @@ -1,3 +1,3 @@ | |||
19 | 1 | [tool.black] | 1 | [tool.black] |
20 | 2 | line-length = 79 | 2 | line-length = 79 |
22 | 3 | target-version = ['py27'] | 3 | target-version = ['py35'] |
23 | diff --git a/src/lazr/restful/__init__.py b/src/lazr/restful/__init__.py | |||
24 | index 25235cd..c8e3f40 100644 | |||
25 | --- a/src/lazr/restful/__init__.py | |||
26 | +++ b/src/lazr/restful/__init__.py | |||
27 | @@ -17,8 +17,6 @@ | |||
28 | 17 | 17 | ||
29 | 18 | # pylint: disable-msg=W0401 | 18 | # pylint: disable-msg=W0401 |
30 | 19 | 19 | ||
31 | 20 | from __future__ import absolute_import, print_function | ||
32 | 21 | |||
33 | 22 | try: | 20 | try: |
34 | 23 | import importlib.metadata as importlib_metadata | 21 | import importlib.metadata as importlib_metadata |
35 | 24 | except ImportError: | 22 | except ImportError: |
36 | diff --git a/src/lazr/restful/_bytestorage.py b/src/lazr/restful/_bytestorage.py | |||
37 | index 7d6c6a0..b25369c 100644 | |||
38 | --- a/src/lazr/restful/_bytestorage.py | |||
39 | +++ b/src/lazr/restful/_bytestorage.py | |||
40 | @@ -16,9 +16,6 @@ | |||
41 | 16 | 16 | ||
42 | 17 | """Classes for a resource that implements a binary file repository.""" | 17 | """Classes for a resource that implements a binary file repository.""" |
43 | 18 | 18 | ||
44 | 19 | from __future__ import absolute_import, print_function | ||
45 | 20 | |||
46 | 21 | __metaclass__ = type | ||
47 | 22 | __all__ = [ | 19 | __all__ = [ |
48 | 23 | "ByteStorageResource", | 20 | "ByteStorageResource", |
49 | 24 | ] | 21 | ] |
50 | diff --git a/src/lazr/restful/_operation.py b/src/lazr/restful/_operation.py | |||
51 | index af48e48..7cab8ea 100644 | |||
52 | --- a/src/lazr/restful/_operation.py | |||
53 | +++ b/src/lazr/restful/_operation.py | |||
54 | @@ -2,10 +2,7 @@ | |||
55 | 2 | 2 | ||
56 | 3 | """Base classes for one-off HTTP operations.""" | 3 | """Base classes for one-off HTTP operations.""" |
57 | 4 | 4 | ||
58 | 5 | from __future__ import absolute_import, print_function | ||
59 | 6 | |||
60 | 7 | import simplejson | 5 | import simplejson |
61 | 8 | import six | ||
62 | 9 | 6 | ||
63 | 10 | from zope.component import getMultiAdapter, getUtility, queryMultiAdapter | 7 | from zope.component import getMultiAdapter, getUtility, queryMultiAdapter |
64 | 11 | from zope.event import notify | 8 | from zope.event import notify |
65 | @@ -40,7 +37,6 @@ from lazr.restful._resource import ( | |||
66 | 40 | ) | 37 | ) |
67 | 41 | 38 | ||
68 | 42 | 39 | ||
69 | 43 | __metaclass__ = type | ||
70 | 44 | __all__ = [ | 40 | __all__ = [ |
71 | 45 | "IObjectLink", | 41 | "IObjectLink", |
72 | 46 | "ObjectLink", | 42 | "ObjectLink", |
73 | @@ -163,9 +159,7 @@ class ResourceOperation(BatchingResourceMixin): | |||
74 | 163 | # has its response batched. | 159 | # has its response batched. |
75 | 164 | return True | 160 | return True |
76 | 165 | 161 | ||
80 | 166 | if zope_isinstance( | 162 | if zope_isinstance(result, (bytes, str, dict, set, list, tuple)): |
78 | 167 | result, (bytes, six.text_type, dict, set, list, tuple) | ||
79 | 168 | ): | ||
81 | 169 | # Ordinary Python data structures generally are not | 163 | # Ordinary Python data structures generally are not |
82 | 170 | # batched. | 164 | # batched. |
83 | 171 | return False | 165 | return False |
84 | @@ -216,14 +210,14 @@ class ResourceOperation(BatchingResourceMixin): | |||
85 | 216 | self.request.form.get(name) | 210 | self.request.form.get(name) |
86 | 217 | ) | 211 | ) |
87 | 218 | except ValueError as e: | 212 | except ValueError as e: |
89 | 219 | errors.append(u"%s: %s" % (name, e)) | 213 | errors.append("%s: %s" % (name, e)) |
90 | 220 | continue | 214 | continue |
91 | 221 | try: | 215 | try: |
92 | 222 | field.validate(value) | 216 | field.validate(value) |
93 | 223 | except RequiredMissing: | 217 | except RequiredMissing: |
95 | 224 | errors.append(u"%s: Required input is missing." % name) | 218 | errors.append("%s: Required input is missing." % name) |
96 | 225 | except ValidationError as e: | 219 | except ValidationError as e: |
98 | 226 | errors.append(u"%s: %s" % (name, e)) | 220 | errors.append("%s: %s" % (name, e)) |
99 | 227 | else: | 221 | else: |
100 | 228 | validated_values[name] = value | 222 | validated_values[name] = value |
101 | 229 | return (validated_values, errors) | 223 | return (validated_values, errors) |
102 | @@ -252,7 +246,7 @@ class IObjectLink(IField): | |||
103 | 252 | """Field containing a link to an object.""" | 246 | """Field containing a link to an object.""" |
104 | 253 | 247 | ||
105 | 254 | schema = Attribute( | 248 | schema = Attribute( |
107 | 255 | "schema", u"The Interface of the Object on the other end of the link." | 249 | "schema", "The Interface of the Object on the other end of the link." |
108 | 256 | ) | 250 | ) |
109 | 257 | 251 | ||
110 | 258 | 252 | ||
111 | @@ -265,4 +259,4 @@ class ObjectLink(Field): | |||
112 | 265 | raise WrongType | 259 | raise WrongType |
113 | 266 | 260 | ||
114 | 267 | self.schema = schema | 261 | self.schema = schema |
116 | 268 | super(ObjectLink, self).__init__(**kw) | 262 | super().__init__(**kw) |
117 | diff --git a/src/lazr/restful/_resource.py b/src/lazr/restful/_resource.py | |||
118 | index f01326d..45f717e 100644 | |||
119 | --- a/src/lazr/restful/_resource.py | |||
120 | +++ b/src/lazr/restful/_resource.py | |||
121 | @@ -2,10 +2,6 @@ | |||
122 | 2 | 2 | ||
123 | 3 | """Base classes for HTTP resources.""" | 3 | """Base classes for HTTP resources.""" |
124 | 4 | 4 | ||
125 | 5 | from __future__ import absolute_import, division, print_function | ||
126 | 6 | |||
127 | 7 | __metaclass__ = type | ||
128 | 8 | |||
129 | 9 | __all__ = [ | 5 | __all__ = [ |
130 | 10 | "BatchingResourceMixin", | 6 | "BatchingResourceMixin", |
131 | 11 | "Collection", | 7 | "Collection", |
132 | @@ -55,7 +51,6 @@ try: | |||
133 | 55 | except ImportError: | 51 | except ImportError: |
134 | 56 | from cgi import escape | 52 | from cgi import escape |
135 | 57 | 53 | ||
136 | 58 | import six | ||
137 | 59 | from zope.component import ( | 54 | from zope.component import ( |
138 | 60 | adapter, | 55 | adapter, |
139 | 61 | getAdapters, | 56 | getAdapters, |
140 | @@ -162,7 +157,7 @@ init_status_codes() | |||
141 | 162 | 157 | ||
142 | 163 | def decode_value(value): | 158 | def decode_value(value): |
143 | 164 | """Return a unicode value curresponding to `value`.""" | 159 | """Return a unicode value curresponding to `value`.""" |
145 | 165 | if isinstance(value, six.text_type): | 160 | if isinstance(value, str): |
146 | 166 | return value | 161 | return value |
147 | 167 | elif isinstance(value, bytes): | 162 | elif isinstance(value, bytes): |
148 | 168 | return value.decode("utf-8") | 163 | return value.decode("utf-8") |
149 | @@ -172,7 +167,7 @@ def decode_value(value): | |||
150 | 172 | 167 | ||
151 | 173 | def _default_html_renderer(value): | 168 | def _default_html_renderer(value): |
152 | 174 | """The default technique for rendering a value as an HTML snippet.""" | 169 | """The default technique for rendering a value as an HTML snippet.""" |
154 | 175 | return escape(six.text_type(value), quote=False) | 170 | return escape(str(value), quote=False) |
155 | 176 | 171 | ||
156 | 177 | 172 | ||
157 | 178 | @adapter(Interface, IField, IWebServiceClientRequest) | 173 | @adapter(Interface, IField, IWebServiceClientRequest) |
158 | @@ -212,7 +207,7 @@ class ResourceJSONEncoder(simplejson.encoder.JSONEncoderForHTML): | |||
159 | 212 | 207 | ||
160 | 213 | def __init__(self, *args, **kwargs): | 208 | def __init__(self, *args, **kwargs): |
161 | 214 | self.media_type = kwargs.pop("media_type", HTTPResource.JSON_TYPE) | 209 | self.media_type = kwargs.pop("media_type", HTTPResource.JSON_TYPE) |
163 | 215 | super(ResourceJSONEncoder, self).__init__(*args, **kwargs) | 210 | super().__init__(*args, **kwargs) |
164 | 216 | 211 | ||
165 | 217 | def default(self, obj): | 212 | def default(self, obj): |
166 | 218 | """Convert the given object to a simple data structure.""" | 213 | """Convert the given object to a simple data structure.""" |
167 | @@ -711,7 +706,7 @@ class CustomOperationResourceMixin: | |||
168 | 711 | # with multiple inheritance. That requires defining __init__ | 706 | # with multiple inheritance. That requires defining __init__ |
169 | 712 | # to call the next constructor in the chain, which means using | 707 | # to call the next constructor in the chain, which means using |
170 | 713 | # super() even though this class itself has no superclass. | 708 | # super() even though this class itself has no superclass. |
172 | 714 | super(CustomOperationResourceMixin, self).__init__(context, request) | 709 | super().__init__(context, request) |
173 | 715 | 710 | ||
174 | 716 | def handleCustomGET(self, operation_name): | 711 | def handleCustomGET(self, operation_name): |
175 | 717 | """Execute a custom search-type operation triggered through GET. | 712 | """Execute a custom search-type operation triggered through GET. |
176 | @@ -722,7 +717,7 @@ class CustomOperationResourceMixin: | |||
177 | 722 | :return: The result of the operation: either a string or an | 717 | :return: The result of the operation: either a string or an |
178 | 723 | object that needs to be serialized to JSON. | 718 | object that needs to be serialized to JSON. |
179 | 724 | """ | 719 | """ |
181 | 725 | if not isinstance(operation_name, six.string_types): | 720 | if not isinstance(operation_name, str): |
182 | 726 | self.request.response.setStatus(400) | 721 | self.request.response.setStatus(400) |
183 | 727 | return "Expected a single operation: %r" % (operation_name,) | 722 | return "Expected a single operation: %r" % (operation_name,) |
184 | 728 | 723 | ||
185 | @@ -750,7 +745,7 @@ class CustomOperationResourceMixin: | |||
186 | 750 | :return: The result of the operation: either a string or an | 745 | :return: The result of the operation: either a string or an |
187 | 751 | object that needs to be serialized to JSON. | 746 | object that needs to be serialized to JSON. |
188 | 752 | """ | 747 | """ |
190 | 753 | if not isinstance(operation_name, six.string_types): | 748 | if not isinstance(operation_name, str): |
191 | 754 | self.request.response.setStatus(400) | 749 | self.request.response.setStatus(400) |
192 | 755 | return "Expected a single operation: %r" % (operation_name,) | 750 | return "Expected a single operation: %r" % (operation_name,) |
193 | 756 | 751 | ||
194 | @@ -810,7 +805,7 @@ class FieldUnmarshallerMixin: | |||
195 | 810 | # with multiple inheritance. That requires defining __init__ | 805 | # with multiple inheritance. That requires defining __init__ |
196 | 811 | # to call the next constructor in the chain, which means using | 806 | # to call the next constructor in the chain, which means using |
197 | 812 | # super() even though this class itself has no superclass. | 807 | # super() even though this class itself has no superclass. |
199 | 813 | super(FieldUnmarshallerMixin, self).__init__(context, request) | 808 | super().__init__(context, request) |
200 | 814 | self._unmarshalled_field_cache = {} | 809 | self._unmarshalled_field_cache = {} |
201 | 815 | 810 | ||
202 | 816 | def _unmarshallField(self, field_name, field, detail=NORMAL_DETAIL): | 811 | def _unmarshallField(self, field_name, field, detail=NORMAL_DETAIL): |
203 | @@ -909,7 +904,7 @@ class ReadOnlyResource(HTTPResource): | |||
204 | 909 | # This class is designed to be used with mixins. That means | 904 | # This class is designed to be used with mixins. That means |
205 | 910 | # defining __init__ to call the next constructor in the chain, | 905 | # defining __init__ to call the next constructor in the chain, |
206 | 911 | # even though there's no other code in __init__. | 906 | # even though there's no other code in __init__. |
208 | 912 | super(ReadOnlyResource, self).__init__(context, request) | 907 | super().__init__(context, request) |
209 | 913 | 908 | ||
210 | 914 | def __call__(self): | 909 | def __call__(self): |
211 | 915 | """Handle a GET or (if implemented) POST request.""" | 910 | """Handle a GET or (if implemented) POST request.""" |
212 | @@ -936,7 +931,7 @@ class ReadWriteResource(HTTPResource): | |||
213 | 936 | # This class is designed to be used with mixins. That means | 931 | # This class is designed to be used with mixins. That means |
214 | 937 | # defining __init__ to call the next constructor in the chain, | 932 | # defining __init__ to call the next constructor in the chain, |
215 | 938 | # even though there's no other code in __init__. | 933 | # even though there's no other code in __init__. |
217 | 939 | super(ReadWriteResource, self).__init__(context, request) | 934 | super().__init__(context, request) |
218 | 940 | 935 | ||
219 | 941 | def __call__(self): | 936 | def __call__(self): |
220 | 942 | """Handle a GET, PUT, or PATCH request.""" | 937 | """Handle a GET, PUT, or PATCH request.""" |
221 | @@ -980,10 +975,7 @@ class ReadWriteResource(HTTPResource): | |||
222 | 980 | # hopefully handle it better. Note the careful | 975 | # hopefully handle it better. Note the careful |
223 | 981 | # reraising that ensures the original traceback is | 976 | # reraising that ensures the original traceback is |
224 | 982 | # preserved. | 977 | # preserved. |
229 | 983 | if six.PY3: | 978 | raise exception_info[1] from None |
226 | 984 | six.raise_from(exception_info[1], None) | ||
227 | 985 | else: | ||
228 | 986 | six.reraise(*exception_info) | ||
230 | 987 | finally: | 979 | finally: |
231 | 988 | del exception_info | 980 | del exception_info |
232 | 989 | 981 | ||
233 | @@ -1035,7 +1027,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
234 | 1035 | # This class is designed to be used with mixins. That means | 1027 | # This class is designed to be used with mixins. That means |
235 | 1036 | # defining __init__ to call the next constructor in the chain, | 1028 | # defining __init__ to call the next constructor in the chain, |
236 | 1037 | # even though there's no other code in __init__. | 1029 | # even though there's no other code in __init__. |
238 | 1038 | super(EntryManipulatingResource, self).__init__(context, request) | 1030 | super().__init__(context, request) |
239 | 1039 | 1031 | ||
240 | 1040 | def processAsJSONDocument(self, media_type, representation): | 1032 | def processAsJSONDocument(self, media_type, representation): |
241 | 1041 | """Process an incoming representation as a JSON document.""" | 1033 | """Process an incoming representation as a JSON document.""" |
242 | @@ -1066,7 +1058,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
243 | 1066 | # Some fields aren't part of the schema, so they're handled | 1058 | # Some fields aren't part of the schema, so they're handled |
244 | 1067 | # separately. | 1059 | # separately. |
245 | 1068 | modified_read_only_attribute = ( | 1060 | modified_read_only_attribute = ( |
247 | 1069 | u"%s: You tried to modify a " "read-only attribute." | 1061 | "%s: You tried to modify a " "read-only attribute." |
248 | 1070 | ) | 1062 | ) |
249 | 1071 | if "self_link" in changeset: | 1063 | if "self_link" in changeset: |
250 | 1072 | if changeset["self_link"] != absoluteURL( | 1064 | if changeset["self_link"] != absoluteURL( |
251 | @@ -1143,7 +1135,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
252 | 1143 | try: | 1135 | try: |
253 | 1144 | value = marshaller.marshall_from_json_data(original_value) | 1136 | value = marshaller.marshall_from_json_data(original_value) |
254 | 1145 | except (ValueError, ValidationError) as e: | 1137 | except (ValueError, ValidationError) as e: |
256 | 1146 | errors.append(u"%s: %s" % (repr_name, e)) | 1138 | errors.append("%s: %s" % (repr_name, e)) |
257 | 1147 | continue | 1139 | continue |
258 | 1148 | 1140 | ||
259 | 1149 | if ICollectionField.providedBy(field): | 1141 | if ICollectionField.providedBy(field): |
260 | @@ -1152,7 +1144,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
261 | 1152 | # current one. | 1144 | # current one. |
262 | 1153 | if value != current_value: | 1145 | if value != current_value: |
263 | 1154 | errors.append( | 1146 | errors.append( |
265 | 1155 | u"%s: You tried to modify a collection " | 1147 | "%s: You tried to modify a collection " |
266 | 1156 | "attribute." % repr_name | 1148 | "attribute." % repr_name |
267 | 1157 | ) | 1149 | ) |
268 | 1158 | continue | 1150 | continue |
269 | @@ -1170,7 +1162,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
270 | 1170 | errors.append(modified_read_only_attribute % repr_name) | 1162 | errors.append(modified_read_only_attribute % repr_name) |
271 | 1171 | else: | 1163 | else: |
272 | 1172 | errors.append( | 1164 | errors.append( |
274 | 1173 | u"%s: To modify this field you need to send a PUT " | 1165 | "%s: To modify this field you need to send a PUT " |
275 | 1174 | "request to its URI (%s)." | 1166 | "request to its URI (%s)." |
276 | 1175 | % (repr_name, current_value) | 1167 | % (repr_name, current_value) |
277 | 1176 | ) | 1168 | ) |
278 | @@ -1186,7 +1178,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
279 | 1186 | # class the way IReference fields can. | 1178 | # class the way IReference fields can. |
280 | 1187 | if value is not None and not field.schema.providedBy(value): | 1179 | if value is not None and not field.schema.providedBy(value): |
281 | 1188 | errors.append( | 1180 | errors.append( |
283 | 1189 | u"%s: Your value points to the " | 1181 | "%s: Your value points to the " |
284 | 1190 | "wrong kind of object" % repr_name | 1182 | "wrong kind of object" % repr_name |
285 | 1191 | ) | 1183 | ) |
286 | 1192 | continue | 1184 | continue |
287 | @@ -1215,22 +1207,20 @@ class EntryManipulatingResource(ReadWriteResource): | |||
288 | 1215 | # the exception; otherwise use a generic message | 1207 | # the exception; otherwise use a generic message |
289 | 1216 | # instead of whatever object the raise site | 1208 | # instead of whatever object the raise site |
290 | 1217 | # thought would be a good idea. | 1209 | # thought would be a good idea. |
294 | 1218 | if len(e.args) > 0 and isinstance( | 1210 | if len(e.args) > 0 and isinstance(e.args[0], str): |
292 | 1219 | e.args[0], six.string_types | ||
293 | 1220 | ): | ||
295 | 1221 | error = e.args[0] | 1211 | error = e.args[0] |
296 | 1222 | else: | 1212 | else: |
297 | 1223 | error = "Constraint not satisfied." | 1213 | error = "Constraint not satisfied." |
299 | 1224 | errors.append(u"%s: %s" % (repr_name, error)) | 1214 | errors.append("%s: %s" % (repr_name, error)) |
300 | 1225 | continue | 1215 | continue |
301 | 1226 | except RequiredMissing: | 1216 | except RequiredMissing: |
302 | 1227 | error = "Missing required value." | 1217 | error = "Missing required value." |
304 | 1228 | errors.append(u"%s: %s" % (repr_name, error)) | 1218 | errors.append("%s: %s" % (repr_name, error)) |
305 | 1229 | except (ValueError, ValidationError) as e: | 1219 | except (ValueError, ValidationError) as e: |
306 | 1230 | error = str(e) | 1220 | error = str(e) |
307 | 1231 | if error == "": | 1221 | if error == "": |
308 | 1232 | error = "Validation error" | 1222 | error = "Validation error" |
310 | 1233 | errors.append(u"%s: %s" % (repr_name, error)) | 1223 | errors.append("%s: %s" % (repr_name, error)) |
311 | 1234 | continue | 1224 | continue |
312 | 1235 | validated_changeset.append((field, value)) | 1225 | validated_changeset.append((field, value)) |
313 | 1236 | # If there are any fields left in the changeset, they're | 1226 | # If there are any fields left in the changeset, they're |
314 | @@ -1238,7 +1228,7 @@ class EntryManipulatingResource(ReadWriteResource): | |||
315 | 1238 | # schema. They're all errors. | 1228 | # schema. They're all errors. |
316 | 1239 | for invalid_field in changeset.keys(): | 1229 | for invalid_field in changeset.keys(): |
317 | 1240 | errors.append( | 1230 | errors.append( |
319 | 1241 | u"%s: You tried to modify a nonexistent " | 1231 | "%s: You tried to modify a nonexistent " |
320 | 1242 | "attribute." % invalid_field | 1232 | "attribute." % invalid_field |
321 | 1243 | ) | 1233 | ) |
322 | 1244 | 1234 | ||
323 | @@ -1331,7 +1321,7 @@ class EntryFieldResource(FieldUnmarshallerMixin, EntryManipulatingResource): | |||
324 | 1331 | 1321 | ||
325 | 1332 | def __init__(self, context, request): | 1322 | def __init__(self, context, request): |
326 | 1333 | """Initialize with respect to a context and request.""" | 1323 | """Initialize with respect to a context and request.""" |
328 | 1334 | super(EntryFieldResource, self).__init__(context, request) | 1324 | super().__init__(context, request) |
329 | 1335 | self.entry = self.context.entry | 1325 | self.entry = self.context.entry |
330 | 1336 | 1326 | ||
331 | 1337 | def do_GET(self): | 1327 | def do_GET(self): |
332 | @@ -1367,7 +1357,7 @@ class EntryFieldResource(FieldUnmarshallerMixin, EntryManipulatingResource): | |||
333 | 1367 | # generating the representation might itself change across | 1357 | # generating the representation might itself change across |
334 | 1368 | # versions. | 1358 | # versions. |
335 | 1369 | revno = getUtility(IWebServiceConfiguration).code_revision | 1359 | revno = getUtility(IWebServiceConfiguration).code_revision |
337 | 1370 | return [core.encode("utf-8") for core in [revno, six.text_type(value)]] | 1360 | return [core.encode("utf-8") for core in [revno, str(value)]] |
338 | 1371 | 1361 | ||
339 | 1372 | def _representation(self, media_type): | 1362 | def _representation(self, media_type): |
340 | 1373 | """Create a representation of the field value.""" | 1363 | """Create a representation of the field value.""" |
341 | @@ -1454,13 +1444,13 @@ class EntryResource( | |||
342 | 1454 | 1444 | ||
343 | 1455 | def __init__(self, context, request): | 1445 | def __init__(self, context, request): |
344 | 1456 | """Associate this resource with a specific object and request.""" | 1446 | """Associate this resource with a specific object and request.""" |
346 | 1457 | super(EntryResource, self).__init__(context, request) | 1447 | super().__init__(context, request) |
347 | 1458 | self.entry = getMultiAdapter((context, request), IEntry) | 1448 | self.entry = getMultiAdapter((context, request), IEntry) |
348 | 1459 | 1449 | ||
349 | 1460 | def handleCustomPOST(self, operation_name): | 1450 | def handleCustomPOST(self, operation_name): |
350 | 1461 | """See `CustomOperationResourceMixin`.""" | 1451 | """See `CustomOperationResourceMixin`.""" |
351 | 1462 | original_url = absoluteURL(self.entry.context, self.request) | 1452 | original_url = absoluteURL(self.entry.context, self.request) |
353 | 1463 | value = super(EntryResource, self).handleCustomPOST(operation_name) | 1453 | value = super().handleCustomPOST(operation_name) |
354 | 1464 | # We don't know what the custom operation might have done. | 1454 | # We don't know what the custom operation might have done. |
355 | 1465 | # Remove this object from the representation cache, just to be | 1455 | # Remove this object from the representation cache, just to be |
356 | 1466 | # safe. | 1456 | # safe. |
357 | @@ -1617,7 +1607,7 @@ class EntryResource( | |||
358 | 1617 | operation_name = self.request.form.pop("ws.op", None) | 1607 | operation_name = self.request.form.pop("ws.op", None) |
359 | 1618 | if operation_name is not None: | 1608 | if operation_name is not None: |
360 | 1619 | result = self.handleCustomGET(operation_name) | 1609 | result = self.handleCustomGET(operation_name) |
362 | 1620 | if isinstance(result, (bytes, six.text_type)): | 1610 | if isinstance(result, (bytes, str)): |
363 | 1621 | # The custom operation took care of everything and | 1611 | # The custom operation took care of everything and |
364 | 1622 | # just needs this string served to the client. | 1612 | # just needs this string served to the client. |
365 | 1623 | return result | 1613 | return result |
366 | @@ -1860,7 +1850,7 @@ class CollectionResource( | |||
367 | 1860 | 1850 | ||
368 | 1861 | def __init__(self, context, request): | 1851 | def __init__(self, context, request): |
369 | 1862 | """Associate this resource with a specific object and request.""" | 1852 | """Associate this resource with a specific object and request.""" |
371 | 1863 | super(CollectionResource, self).__init__(context, request) | 1853 | super().__init__(context, request) |
372 | 1864 | if ICollection.providedBy(context): | 1854 | if ICollection.providedBy(context): |
373 | 1865 | self.collection = context | 1855 | self.collection = context |
374 | 1866 | else: | 1856 | else: |
375 | @@ -1872,7 +1862,7 @@ class CollectionResource( | |||
376 | 1872 | operation_name = self.request.form.pop("ws.op", None) | 1862 | operation_name = self.request.form.pop("ws.op", None) |
377 | 1873 | if operation_name is not None: | 1863 | if operation_name is not None: |
378 | 1874 | result = self.handleCustomGET(operation_name) | 1864 | result = self.handleCustomGET(operation_name) |
380 | 1875 | if isinstance(result, (bytes, six.text_type)): | 1865 | if isinstance(result, (bytes, str)): |
381 | 1876 | # The custom operation took care of everything and | 1866 | # The custom operation took care of everything and |
382 | 1877 | # just needs this string served to the client. | 1867 | # just needs this string served to the client. |
383 | 1878 | return result | 1868 | return result |
384 | @@ -1905,7 +1895,7 @@ class CollectionResource( | |||
385 | 1905 | entries = self.collection.find() | 1895 | entries = self.collection.find() |
386 | 1906 | if request is None: | 1896 | if request is None: |
387 | 1907 | request = self.request | 1897 | request = self.request |
389 | 1908 | result = super(CollectionResource, self).batch(entries, request) | 1898 | result = super().batch(entries, request) |
390 | 1909 | result += ', "resource_type_link" : ' + simplejson.dumps(self.type_url) | 1899 | result += ', "resource_type_link" : ' + simplejson.dumps(self.type_url) |
391 | 1910 | return result | 1900 | return result |
392 | 1911 | 1901 | ||
393 | diff --git a/src/lazr/restful/debug.py b/src/lazr/restful/debug.py | |||
394 | index 0567455..ebcf526 100644 | |||
395 | --- a/src/lazr/restful/debug.py | |||
396 | +++ b/src/lazr/restful/debug.py | |||
397 | @@ -2,9 +2,6 @@ | |||
398 | 2 | 2 | ||
399 | 3 | """Module docstring goes here.""" | 3 | """Module docstring goes here.""" |
400 | 4 | 4 | ||
401 | 5 | from __future__ import absolute_import, print_function | ||
402 | 6 | |||
403 | 7 | __metaclass__ = type | ||
404 | 8 | __all__ = ["debug_proxy", "typename"] | 5 | __all__ = ["debug_proxy", "typename"] |
405 | 9 | 6 | ||
406 | 10 | 7 | ||
407 | diff --git a/src/lazr/restful/declarations.py b/src/lazr/restful/declarations.py | |||
408 | index 4c95bcd..f717592 100644 | |||
409 | --- a/src/lazr/restful/declarations.py | |||
410 | +++ b/src/lazr/restful/declarations.py | |||
411 | @@ -2,9 +2,6 @@ | |||
412 | 2 | 2 | ||
413 | 3 | """Declaration helpers to define a web service.""" | 3 | """Declaration helpers to define a web service.""" |
414 | 4 | 4 | ||
415 | 5 | from __future__ import absolute_import, print_function | ||
416 | 6 | |||
417 | 7 | __metaclass__ = type | ||
418 | 8 | __all__ = [ | 5 | __all__ = [ |
419 | 9 | "COLLECTION_TYPE", | 6 | "COLLECTION_TYPE", |
420 | 10 | "ENTRY_TYPE", | 7 | "ENTRY_TYPE", |
421 | @@ -1134,9 +1131,7 @@ class export_factory_operation(_export_operation): | |||
422 | 1134 | 1131 | ||
423 | 1135 | def annotate_method(self, method, annotations): | 1132 | def annotate_method(self, method, annotations): |
424 | 1136 | """See `_method_annotator`.""" | 1133 | """See `_method_annotator`.""" |
428 | 1137 | super(export_factory_operation, self).annotate_method( | 1134 | super().annotate_method(method, annotations) |
426 | 1138 | method, annotations | ||
427 | 1139 | ) | ||
429 | 1140 | annotations["creates"] = self.interface | 1135 | annotations["creates"] = self.interface |
430 | 1141 | annotations["params"] = self.params | 1136 | annotations["params"] = self.params |
431 | 1142 | annotations["return_type"] = ObjectLink(schema=self.interface) | 1137 | annotations["return_type"] = ObjectLink(schema=self.interface) |
432 | @@ -1147,7 +1142,7 @@ class cache_for(_method_annotator): | |||
433 | 1147 | 1142 | ||
434 | 1148 | def __init__(self, duration): | 1143 | def __init__(self, duration): |
435 | 1149 | """Specify the duration, in seconds, of the caching resource.""" | 1144 | """Specify the duration, in seconds, of the caching resource.""" |
437 | 1150 | if not isinstance(duration, six.integer_types): | 1145 | if not isinstance(duration, int): |
438 | 1151 | raise TypeError( | 1146 | raise TypeError( |
439 | 1152 | "Caching duration should be an integer type, not %s" | 1147 | "Caching duration should be an integer type, not %s" |
440 | 1153 | % duration.__class__.__name__ | 1148 | % duration.__class__.__name__ |
441 | @@ -1174,7 +1169,7 @@ class scoped(_method_annotator): | |||
442 | 1174 | 1169 | ||
443 | 1175 | def __init__(self, *scopes): | 1170 | def __init__(self, *scopes): |
444 | 1176 | for scope in scopes: | 1171 | for scope in scopes: |
446 | 1177 | if not isinstance(scope, six.string_types): | 1172 | if not isinstance(scope, str): |
447 | 1178 | raise TypeError( | 1173 | raise TypeError( |
448 | 1179 | "Scope should be a string type, not %s" | 1174 | "Scope should be a string type, not %s" |
449 | 1180 | % scope.__class__.__name__ | 1175 | % scope.__class__.__name__ |
450 | @@ -1214,9 +1209,7 @@ class export_destructor_operation(_export_operation): | |||
451 | 1214 | 1209 | ||
452 | 1215 | Every version must have a self-consistent set of annotations. | 1210 | Every version must have a self-consistent set of annotations. |
453 | 1216 | """ | 1211 | """ |
457 | 1217 | super(export_destructor_operation, self).annotate_method( | 1212 | super().annotate_method(method, annotation_stack) |
455 | 1218 | method, annotation_stack | ||
456 | 1219 | ) | ||
458 | 1220 | # The mutator method must take no arguments, not counting | 1213 | # The mutator method must take no arguments, not counting |
459 | 1221 | # arguments with values fixed by call_with(). | 1214 | # arguments with values fixed by call_with(). |
460 | 1222 | for version, annotations in annotation_stack.stack: | 1215 | for version, annotations in annotation_stack.stack: |
461 | @@ -1555,14 +1548,14 @@ class _ScopeChecker(Passthrough): | |||
462 | 1555 | if self.adaptation is not None: | 1548 | if self.adaptation is not None: |
463 | 1556 | context = self.adaptation(context) | 1549 | context = self.adaptation(context) |
464 | 1557 | _check_request(context, None) | 1550 | _check_request(context, None) |
466 | 1558 | return super(_ScopeChecker, self).__get__(inst, cls=cls) | 1551 | return super().__get__(inst, cls=cls) |
467 | 1559 | 1552 | ||
468 | 1560 | def __set__(self, inst, value): | 1553 | def __set__(self, inst, value): |
469 | 1561 | context = getattr(inst, self.contextvar) | 1554 | context = getattr(inst, self.contextvar) |
470 | 1562 | if self.adaptation is not None: | 1555 | if self.adaptation is not None: |
471 | 1563 | context = self.adaptation(context) | 1556 | context = self.adaptation(context) |
472 | 1564 | _check_request(context, None) | 1557 | _check_request(context, None) |
474 | 1565 | return super(_ScopeChecker, self).__set__(inst, value) | 1558 | return super().__set__(inst, value) |
475 | 1566 | 1559 | ||
476 | 1567 | 1560 | ||
477 | 1568 | class _AccessorWrapper: | 1561 | class _AccessorWrapper: |
478 | @@ -1615,7 +1608,7 @@ class PropertyWithAccessor(_AccessorWrapper, _ScopeChecker): | |||
479 | 1615 | def __init__( | 1608 | def __init__( |
480 | 1616 | self, name, context, accessor, accessor_annotations, adaptation | 1609 | self, name, context, accessor, accessor_annotations, adaptation |
481 | 1617 | ): | 1610 | ): |
483 | 1618 | super(PropertyWithAccessor, self).__init__(name, context, adaptation) | 1611 | super().__init__(name, context, adaptation) |
484 | 1619 | self.accessor = accessor.__name__ | 1612 | self.accessor = accessor.__name__ |
485 | 1620 | self.accessor_annotations = accessor_annotations | 1613 | self.accessor_annotations = accessor_annotations |
486 | 1621 | 1614 | ||
487 | @@ -1626,7 +1619,7 @@ class PropertyWithMutator(_MutatorWrapper, _ScopeChecker): | |||
488 | 1626 | def __init__( | 1619 | def __init__( |
489 | 1627 | self, name, context, mutator, mutator_annotations, adaptation | 1620 | self, name, context, mutator, mutator_annotations, adaptation |
490 | 1628 | ): | 1621 | ): |
492 | 1629 | super(PropertyWithMutator, self).__init__(name, context, adaptation) | 1622 | super().__init__(name, context, adaptation) |
493 | 1630 | self.mutator = mutator.__name__ | 1623 | self.mutator = mutator.__name__ |
494 | 1631 | self.mutator_annotations = mutator_annotations | 1624 | self.mutator_annotations = mutator_annotations |
495 | 1632 | 1625 | ||
496 | @@ -1646,9 +1639,7 @@ class PropertyWithAccessorAndMutator( | |||
497 | 1646 | mutator_annotations, | 1639 | mutator_annotations, |
498 | 1647 | adaptation, | 1640 | adaptation, |
499 | 1648 | ): | 1641 | ): |
503 | 1649 | super(PropertyWithAccessorAndMutator, self).__init__( | 1642 | super().__init__(name, context, adaptation) |
501 | 1650 | name, context, adaptation | ||
502 | 1651 | ) | ||
504 | 1652 | self.accessor = accessor.__name__ | 1643 | self.accessor = accessor.__name__ |
505 | 1653 | self.accessor_annotations = accessor_annotations | 1644 | self.accessor_annotations = accessor_annotations |
506 | 1654 | self.mutator = mutator.__name__ | 1645 | self.mutator = mutator.__name__ |
507 | @@ -1792,7 +1783,7 @@ class BaseFactoryResourceOperationAdapter(BaseResourceOperationAdapter): | |||
508 | 1792 | response = self.request.response | 1783 | response = self.request.response |
509 | 1793 | response.setStatus(201) | 1784 | response.setStatus(201) |
510 | 1794 | response.setHeader("Location", absoluteURL(result, self.request)) | 1785 | response.setHeader("Location", absoluteURL(result, self.request)) |
512 | 1795 | return u"" | 1786 | return "" |
513 | 1796 | 1787 | ||
514 | 1797 | 1788 | ||
515 | 1798 | def generate_operation_adapter(method, version=None): | 1789 | def generate_operation_adapter(method, version=None): |
516 | diff --git a/src/lazr/restful/directives/__init__.py b/src/lazr/restful/directives/__init__.py | |||
517 | index 4db78d1..e311f8e 100644 | |||
518 | --- a/src/lazr/restful/directives/__init__.py | |||
519 | +++ b/src/lazr/restful/directives/__init__.py | |||
520 | @@ -2,9 +2,6 @@ | |||
521 | 2 | 2 | ||
522 | 3 | """Martian directives used in lazr.restful.""" | 3 | """Martian directives used in lazr.restful.""" |
523 | 4 | 4 | ||
524 | 5 | from __future__ import absolute_import, print_function | ||
525 | 6 | |||
526 | 7 | __metaclass__ = type | ||
527 | 8 | __all__ = [ | 5 | __all__ = [ |
528 | 9 | "request_class", | 6 | "request_class", |
529 | 10 | "publication_class", | 7 | "publication_class", |
530 | diff --git a/src/lazr/restful/docs/conf.py b/src/lazr/restful/docs/conf.py | |||
531 | index bd3dea3..f1c692d 100644 | |||
532 | --- a/src/lazr/restful/docs/conf.py | |||
533 | +++ b/src/lazr/restful/docs/conf.py | |||
534 | @@ -1,5 +1,3 @@ | |||
535 | 1 | # -*- coding: utf-8 -*- | ||
536 | 2 | # | ||
537 | 3 | # lazr.restful documentation build configuration file, created by | 1 | # lazr.restful documentation build configuration file, created by |
538 | 4 | # sphinx-quickstart on Sun Nov 3 15:00:52 2019. | 2 | # sphinx-quickstart on Sun Nov 3 15:00:52 2019. |
539 | 5 | # | 3 | # |
540 | @@ -47,9 +45,9 @@ source_suffix = ".rst" | |||
541 | 47 | master_doc = "index" | 45 | master_doc = "index" |
542 | 48 | 46 | ||
543 | 49 | # General information about the project. | 47 | # General information about the project. |
547 | 50 | project = u"lazr.restful" | 48 | project = "lazr.restful" |
548 | 51 | copyright = u"2004-2019, Canonical Ltd." | 49 | copyright = "2004-2019, Canonical Ltd." |
549 | 52 | author = u"LAZR Developers <lazr-developers@lists.launchpad.net>" | 50 | author = "LAZR Developers <lazr-developers@lists.launchpad.net>" |
550 | 53 | 51 | ||
551 | 54 | # The version info for the project you're documenting, acts as replacement for | 52 | # The version info for the project you're documenting, acts as replacement for |
552 | 55 | # |version| and |release|, also used in various other places throughout the | 53 | # |version| and |release|, also used in various other places throughout the |
553 | @@ -140,8 +138,8 @@ latex_documents = [ | |||
554 | 140 | ( | 138 | ( |
555 | 141 | master_doc, | 139 | master_doc, |
556 | 142 | "lazrrestful.tex", | 140 | "lazrrestful.tex", |
559 | 143 | u"lazr.restful Documentation", | 141 | "lazr.restful Documentation", |
560 | 144 | u"LAZR Developers \\textless{}lazr-developers@lists.launchpad.net\\textgreater{}", # noqa: E501 | 142 | "LAZR Developers \\textless{}lazr-developers@lists.launchpad.net\\textgreater{}", # noqa: E501 |
561 | 145 | "manual", | 143 | "manual", |
562 | 146 | ), | 144 | ), |
563 | 147 | ] | 145 | ] |
564 | @@ -152,7 +150,7 @@ latex_documents = [ | |||
565 | 152 | # One entry per manual page. List of tuples | 150 | # One entry per manual page. List of tuples |
566 | 153 | # (source start file, name, description, authors, manual section). | 151 | # (source start file, name, description, authors, manual section). |
567 | 154 | man_pages = [ | 152 | man_pages = [ |
569 | 155 | (master_doc, "lazrrestful", u"lazr.restful Documentation", [author], 1) | 153 | (master_doc, "lazrrestful", "lazr.restful Documentation", [author], 1) |
570 | 156 | ] | 154 | ] |
571 | 157 | 155 | ||
572 | 158 | 156 | ||
573 | @@ -165,7 +163,7 @@ texinfo_documents = [ | |||
574 | 165 | ( | 163 | ( |
575 | 166 | master_doc, | 164 | master_doc, |
576 | 167 | "lazrrestful", | 165 | "lazrrestful", |
578 | 168 | u"lazr.restful Documentation", | 166 | "lazr.restful Documentation", |
579 | 169 | author, | 167 | author, |
580 | 170 | "lazrrestful", | 168 | "lazrrestful", |
581 | 171 | "One line description of project.", | 169 | "One line description of project.", |
582 | diff --git a/src/lazr/restful/error.py b/src/lazr/restful/error.py | |||
583 | index 86cef16..a2cf44b 100644 | |||
584 | --- a/src/lazr/restful/error.py | |||
585 | +++ b/src/lazr/restful/error.py | |||
586 | @@ -2,9 +2,6 @@ | |||
587 | 2 | 2 | ||
588 | 3 | """Error handling on the webservice.""" | 3 | """Error handling on the webservice.""" |
589 | 4 | 4 | ||
590 | 5 | from __future__ import absolute_import, division, print_function | ||
591 | 6 | |||
592 | 7 | __metaclass__ = type | ||
593 | 8 | __all__ = [ | 5 | __all__ = [ |
594 | 9 | "ClientErrorView", | 6 | "ClientErrorView", |
595 | 10 | "expose", | 7 | "expose", |
596 | diff --git a/src/lazr/restful/example/base/filemanager.py b/src/lazr/restful/example/base/filemanager.py | |||
597 | index fccb0fc..781bf88 100644 | |||
598 | --- a/src/lazr/restful/example/base/filemanager.py | |||
599 | +++ b/src/lazr/restful/example/base/filemanager.py | |||
600 | @@ -2,9 +2,6 @@ | |||
601 | 2 | 2 | ||
602 | 3 | """The file manager for the LAZR example web service.""" | 3 | """The file manager for the LAZR example web service.""" |
603 | 4 | 4 | ||
604 | 5 | from __future__ import absolute_import, print_function | ||
605 | 6 | |||
606 | 7 | __metaclass__ = type | ||
607 | 8 | __all__ = ["FileManager", "ManagedFileResource"] | 5 | __all__ = ["FileManager", "ManagedFileResource"] |
608 | 9 | 6 | ||
609 | 10 | import datetime | 7 | import datetime |
610 | diff --git a/src/lazr/restful/example/base/interfaces.py b/src/lazr/restful/example/base/interfaces.py | |||
611 | index b6d7d85..c315cea 100644 | |||
612 | --- a/src/lazr/restful/example/base/interfaces.py | |||
613 | +++ b/src/lazr/restful/example/base/interfaces.py | |||
614 | @@ -3,9 +3,6 @@ | |||
615 | 3 | 3 | ||
616 | 4 | """Interface objects for the LAZR example web service.""" | 4 | """Interface objects for the LAZR example web service.""" |
617 | 5 | 5 | ||
618 | 6 | from __future__ import absolute_import, print_function | ||
619 | 7 | |||
620 | 8 | __metaclass__ = type | ||
621 | 9 | __all__ = [ | 6 | __all__ = [ |
622 | 10 | "AlreadyNew", | 7 | "AlreadyNew", |
623 | 11 | "Cuisine", | 8 | "Cuisine", |
624 | @@ -65,7 +62,7 @@ class WhitespaceStrippingTextLine(TextLine): | |||
625 | 65 | """Strip whitespace before setting.""" | 62 | """Strip whitespace before setting.""" |
626 | 66 | if value is not None: | 63 | if value is not None: |
627 | 67 | value = value.strip() | 64 | value = value.strip() |
629 | 68 | super(WhitespaceStrippingTextLine, self).set(object, value) | 65 | super().set(object, value) |
630 | 69 | 66 | ||
631 | 70 | 67 | ||
632 | 71 | class Cuisine(EnumeratedType): | 68 | class Cuisine(EnumeratedType): |
633 | @@ -75,7 +72,7 @@ class Cuisine(EnumeratedType): | |||
634 | 75 | VEGETARIAN = Item("Vegetarian", "Vegetarian cooking") | 72 | VEGETARIAN = Item("Vegetarian", "Vegetarian cooking") |
635 | 76 | AMERICAN = Item("American", "Traditional American cooking") | 73 | AMERICAN = Item("American", "Traditional American cooking") |
636 | 77 | DESSERT = Item("Dessert", "Desserts") | 74 | DESSERT = Item("Dessert", "Desserts") |
638 | 78 | FRANCAISE = Item(u"Fran\xe7aise", u"Cuisine fran\xe7aise") | 75 | FRANCAISE = Item("Fran\xe7aise", "Cuisine fran\xe7aise") |
639 | 79 | 76 | ||
640 | 80 | 77 | ||
641 | 81 | class IHasGet(Interface): | 78 | class IHasGet(Interface): |
642 | @@ -89,10 +86,10 @@ class IHasGet(Interface): | |||
643 | 89 | class IDish(ILocation): | 86 | class IDish(ILocation): |
644 | 90 | """A dish, annotated for export to the web service.""" | 87 | """A dish, annotated for export to the web service.""" |
645 | 91 | 88 | ||
647 | 92 | name = exported(TextLine(title=u"Name", required=True)) | 89 | name = exported(TextLine(title="Name", required=True)) |
648 | 93 | recipes = exported( | 90 | recipes = exported( |
649 | 94 | CollectionField( | 91 | CollectionField( |
651 | 95 | title=u"Recipes in this cookbook", | 92 | title="Recipes in this cookbook", |
652 | 96 | value_type=Reference(schema=Interface), | 93 | value_type=Reference(schema=Interface), |
653 | 97 | ) | 94 | ) |
654 | 98 | ) | 95 | ) |
655 | @@ -105,17 +102,17 @@ class IDish(ILocation): | |||
656 | 105 | class IRecipe(ILocation): | 102 | class IRecipe(ILocation): |
657 | 106 | """A recipe, annotated for export to the web service.""" | 103 | """A recipe, annotated for export to the web service.""" |
658 | 107 | 104 | ||
662 | 108 | id = exported(Int(title=u"Unique ID", required=True)) | 105 | id = exported(Int(title="Unique ID", required=True)) |
663 | 109 | dish = exported(Reference(title=u"Dish", schema=IDish)) | 106 | dish = exported(Reference(title="Dish", schema=IDish)) |
664 | 110 | cookbook = exported(Reference(title=u"Cookbook", schema=Interface)) | 107 | cookbook = exported(Reference(title="Cookbook", schema=Interface)) |
665 | 111 | instructions = exported( | 108 | instructions = exported( |
667 | 112 | Text(title=u"How to prepare the recipe", required=True) | 109 | Text(title="How to prepare the recipe", required=True) |
668 | 113 | ) | 110 | ) |
669 | 114 | private = exported( | 111 | private = exported( |
671 | 115 | Bool(title=u"Whether the public can see this recipe.", default=False) | 112 | Bool(title="Whether the public can see this recipe.", default=False) |
672 | 116 | ) | 113 | ) |
673 | 117 | prepared_image = exported( | 114 | prepared_image = exported( |
675 | 118 | Bytes(0, 5000, title=u"An image of the prepared dish.", readonly=True) | 115 | Bytes(0, 5000, title="An image of the prepared dish.", readonly=True) |
676 | 119 | ) | 116 | ) |
677 | 120 | 117 | ||
678 | 121 | @export_destructor_operation() | 118 | @export_destructor_operation() |
679 | @@ -127,55 +124,53 @@ class IRecipe(ILocation): | |||
680 | 127 | class ICookbook(IHasGet, ILocation): | 124 | class ICookbook(IHasGet, ILocation): |
681 | 128 | """A cookbook, annotated for export to the web service.""" | 125 | """A cookbook, annotated for export to the web service.""" |
682 | 129 | 126 | ||
684 | 130 | name = exported(TextLine(title=u"Name", required=True)) | 127 | name = exported(TextLine(title="Name", required=True)) |
685 | 131 | copyright_date = exported( | 128 | copyright_date = exported( |
686 | 132 | Date( | 129 | Date( |
689 | 133 | title=u"Copyright Date", | 130 | title="Copyright Date", |
690 | 134 | description=u"The copyright date for this work.", | 131 | description="The copyright date for this work.", |
691 | 135 | ), | 132 | ), |
692 | 136 | readonly=True, | 133 | readonly=True, |
693 | 137 | ) | 134 | ) |
694 | 138 | description = exported( | 135 | description = exported( |
696 | 139 | WhitespaceStrippingTextLine(title=u"Description", required=False) | 136 | WhitespaceStrippingTextLine(title="Description", required=False) |
697 | 140 | ) | 137 | ) |
698 | 141 | revision_number = exported( | 138 | revision_number = exported( |
699 | 142 | Int( | 139 | Int( |
701 | 143 | title=u"A record of the number of times " | 140 | title="A record of the number of times " |
702 | 144 | "this cookbook has been modified." | 141 | "this cookbook has been modified." |
703 | 145 | ) | 142 | ) |
704 | 146 | ) | 143 | ) |
705 | 147 | confirmed = exported( | 144 | confirmed = exported( |
706 | 148 | Bool( | 145 | Bool( |
708 | 149 | title=u"Whether this information has been confirmed", default=False | 146 | title="Whether this information has been confirmed", default=False |
709 | 150 | ) | 147 | ) |
710 | 151 | ) | 148 | ) |
711 | 152 | cuisine = exported( | 149 | cuisine = exported( |
712 | 153 | Choice( | 150 | Choice( |
714 | 154 | vocabulary=Cuisine, title=u"Cuisine", required=False, default=None | 151 | vocabulary=Cuisine, title="Cuisine", required=False, default=None |
715 | 155 | ) | 152 | ) |
716 | 156 | ) | 153 | ) |
717 | 157 | last_printing = exported( | 154 | last_printing = exported( |
718 | 158 | Date( | 155 | Date( |
721 | 159 | title=u"Last printing", | 156 | title="Last printing", |
722 | 160 | description=u"The date of this work's most recent printing.", | 157 | description="The date of this work's most recent printing.", |
723 | 161 | ) | 158 | ) |
724 | 162 | ) | 159 | ) |
725 | 163 | # Don't try this at home! Float is a bad choice for a 'price' | 160 | # Don't try this at home! Float is a bad choice for a 'price' |
726 | 164 | # field because it's imprecise. Decimal is a better choice. But | 161 | # field because it's imprecise. Decimal is a better choice. But |
727 | 165 | # this is just an example and we need a Float field, so... | 162 | # this is just an example and we need a Float field, so... |
729 | 166 | price = exported(Float(title=u"Retail price of the cookbook")) | 163 | price = exported(Float(title="Retail price of the cookbook")) |
730 | 167 | recipes = exported( | 164 | recipes = exported( |
731 | 168 | CollectionField( | 165 | CollectionField( |
733 | 169 | title=u"Recipes in this cookbook", | 166 | title="Recipes in this cookbook", |
734 | 170 | value_type=Reference(schema=IRecipe), | 167 | value_type=Reference(schema=IRecipe), |
735 | 171 | ) | 168 | ) |
736 | 172 | ) | 169 | ) |
740 | 173 | cover = exported( | 170 | cover = exported(Bytes(0, 5000, title="An image of the cookbook's cover.")) |
738 | 174 | Bytes(0, 5000, title=u"An image of the cookbook's cover.") | ||
739 | 175 | ) | ||
741 | 176 | 171 | ||
742 | 177 | @operation_parameters( | 172 | @operation_parameters( |
744 | 178 | search=TextLine(title=u"String to search for in recipe name.") | 173 | search=TextLine(title="String to search for in recipe name.") |
745 | 179 | ) | 174 | ) |
746 | 180 | @operation_returns_collection_of(IRecipe) | 175 | @operation_returns_collection_of(IRecipe) |
747 | 181 | @export_read_operation() | 176 | @export_read_operation() |
748 | @@ -183,7 +178,7 @@ class ICookbook(IHasGet, ILocation): | |||
749 | 183 | """Search for recipes in this cookbook.""" | 178 | """Search for recipes in this cookbook.""" |
750 | 184 | 179 | ||
751 | 185 | @operation_parameters( | 180 | @operation_parameters( |
753 | 186 | dish=Reference(title=u"Dish to search for.", schema=IDish) | 181 | dish=Reference(title="Dish to search for.", schema=IDish) |
754 | 187 | ) | 182 | ) |
755 | 188 | @operation_returns_entry(IRecipe) | 183 | @operation_returns_entry(IRecipe) |
756 | 189 | @export_read_operation() | 184 | @export_read_operation() |
757 | @@ -197,7 +192,7 @@ class ICookbook(IHasGet, ILocation): | |||
758 | 197 | def removeRecipe(recipe): | 192 | def removeRecipe(recipe): |
759 | 198 | """Remove one of this cookbook's recipes.""" | 193 | """Remove one of this cookbook's recipes.""" |
760 | 199 | 194 | ||
762 | 200 | @operation_parameters(cover=Bytes(title=u"New cover")) | 195 | @operation_parameters(cover=Bytes(title="New cover")) |
763 | 201 | @export_write_operation() | 196 | @export_write_operation() |
764 | 202 | def replace_cover(cover): | 197 | def replace_cover(cover): |
765 | 203 | """Replace the cookbook's cover.""" | 198 | """Replace the cookbook's cover.""" |
766 | @@ -231,9 +226,9 @@ class ICookbookSet(IHasGet): | |||
767 | 231 | """Return the list of cookbooks.""" | 226 | """Return the list of cookbooks.""" |
768 | 232 | 227 | ||
769 | 233 | @operation_parameters( | 228 | @operation_parameters( |
771 | 234 | search=TextLine(title=u"String to search for in recipe name."), | 229 | search=TextLine(title="String to search for in recipe name."), |
772 | 235 | vegetarian=Bool( | 230 | vegetarian=Bool( |
774 | 236 | title=u"Whether or not to limit the search to " | 231 | title="Whether or not to limit the search to " |
775 | 237 | "vegetarian cookbooks.", | 232 | "vegetarian cookbooks.", |
776 | 238 | default=False, | 233 | default=False, |
777 | 239 | ), | 234 | ), |
778 | @@ -245,7 +240,7 @@ class ICookbookSet(IHasGet): | |||
779 | 245 | 240 | ||
780 | 246 | @operation_parameters( | 241 | @operation_parameters( |
781 | 247 | cuisine=Choice( | 242 | cuisine=Choice( |
783 | 248 | vocabulary=Cuisine, title=u"Cuisine to search for in recipe name." | 243 | vocabulary=Cuisine, title="Cuisine to search for in recipe name." |
784 | 249 | ) | 244 | ) |
785 | 250 | ) | 245 | ) |
786 | 251 | @operation_returns_collection_of(ICookbook) | 246 | @operation_returns_collection_of(ICookbook) |
787 | diff --git a/src/lazr/restful/example/base/root.py b/src/lazr/restful/example/base/root.py | |||
788 | index 424c971..85771b7 100644 | |||
789 | --- a/src/lazr/restful/example/base/root.py | |||
790 | +++ b/src/lazr/restful/example/base/root.py | |||
791 | @@ -2,9 +2,6 @@ | |||
792 | 2 | 2 | ||
793 | 3 | """Data model objects for the LAZR example web service.""" | 3 | """Data model objects for the LAZR example web service.""" |
794 | 4 | 4 | ||
795 | 5 | from __future__ import absolute_import, print_function | ||
796 | 6 | |||
797 | 7 | __metaclass__ = type | ||
798 | 8 | __all__ = [ | 5 | __all__ = [ |
799 | 9 | "Cookbook", | 6 | "Cookbook", |
800 | 10 | "CookbookServiceRootResource", | 7 | "CookbookServiceRootResource", |
801 | @@ -382,22 +379,22 @@ def year(year): | |||
802 | 382 | 379 | ||
803 | 383 | 380 | ||
804 | 384 | C1 = Cookbook( | 381 | C1 = Cookbook( |
806 | 385 | u"Mastering the Art of French Cooking", "", Cuisine.FRANCAISE, year(1961) | 382 | "Mastering the Art of French Cooking", "", Cuisine.FRANCAISE, year(1961) |
807 | 386 | ) | 383 | ) |
809 | 387 | C2 = Cookbook(u"The Joy of Cooking", "", Cuisine.GENERAL, year(1995), price=20) | 384 | C2 = Cookbook("The Joy of Cooking", "", Cuisine.GENERAL, year(1995), price=20) |
810 | 388 | C3 = Cookbook( | 385 | C3 = Cookbook( |
812 | 389 | u"James Beard's American Cookery", "", Cuisine.AMERICAN, year(1972) | 386 | "James Beard's American Cookery", "", Cuisine.AMERICAN, year(1972) |
813 | 390 | ) | 387 | ) |
818 | 391 | C4 = Cookbook(u"Everyday Greens", "", Cuisine.VEGETARIAN, year(2003)) | 388 | C4 = Cookbook("Everyday Greens", "", Cuisine.VEGETARIAN, year(2003)) |
819 | 392 | C5 = Cookbook(u"I'm Just Here For The Food", "", Cuisine.GENERAL, year(2002)) | 389 | C5 = Cookbook("I'm Just Here For The Food", "", Cuisine.GENERAL, year(2002)) |
820 | 393 | C6 = Cookbook(u"Cooking Without Recipes", "", Cuisine.GENERAL, year(1959)) | 390 | C6 = Cookbook("Cooking Without Recipes", "", Cuisine.GENERAL, year(1959)) |
821 | 394 | C7 = Cookbook(u"Construsions un repas", "", Cuisine.FRANCAISE, year(2007)) | 391 | C7 = Cookbook("Construsions un repas", "", Cuisine.FRANCAISE, year(2007)) |
822 | 395 | COOKBOOKS = [C1, C2, C3, C4, C5, C6, C7] | 392 | COOKBOOKS = [C1, C2, C3, C4, C5, C6, C7] |
823 | 396 | 393 | ||
824 | 397 | D1 = Dish("Roast chicken") | 394 | D1 = Dish("Roast chicken") |
828 | 398 | C1_D1 = Recipe(1, C1, D1, u"You can always judge...") | 395 | C1_D1 = Recipe(1, C1, D1, "You can always judge...") |
829 | 399 | C2_D1 = Recipe(2, C2, D1, u"Draw, singe, stuff, and truss...") | 396 | C2_D1 = Recipe(2, C2, D1, "Draw, singe, stuff, and truss...") |
830 | 400 | C3_D1 = Recipe(3, C3, D1, u"A perfectly roasted chicken is...") | 397 | C3_D1 = Recipe(3, C3, D1, "A perfectly roasted chicken is...") |
831 | 401 | 398 | ||
832 | 402 | D2 = Dish("Baked beans") | 399 | D2 = Dish("Baked beans") |
833 | 403 | C2_D2 = Recipe(4, C2, D2, "Preheat oven to...") | 400 | C2_D2 = Recipe(4, C2, D2, "Preheat oven to...") |
834 | diff --git a/src/lazr/restful/example/base/security.py b/src/lazr/restful/example/base/security.py | |||
835 | index bbb5165..0f33cb0 100644 | |||
836 | --- a/src/lazr/restful/example/base/security.py | |||
837 | +++ b/src/lazr/restful/example/base/security.py | |||
838 | @@ -2,9 +2,6 @@ | |||
839 | 2 | 2 | ||
840 | 3 | """A simple security policy for the LAZR example web service.""" | 3 | """A simple security policy for the LAZR example web service.""" |
841 | 4 | 4 | ||
842 | 5 | from __future__ import absolute_import, print_function | ||
843 | 6 | |||
844 | 7 | __metaclass__ = type | ||
845 | 8 | __all__ = [ | 5 | __all__ = [ |
846 | 9 | "CookbookWebServiceSecurityPolicy", | 6 | "CookbookWebServiceSecurityPolicy", |
847 | 10 | ] | 7 | ] |
848 | diff --git a/src/lazr/restful/example/base/subscribers.py b/src/lazr/restful/example/base/subscribers.py | |||
849 | index 68ff062..fa6f973 100644 | |||
850 | --- a/src/lazr/restful/example/base/subscribers.py | |||
851 | +++ b/src/lazr/restful/example/base/subscribers.py | |||
852 | @@ -2,9 +2,6 @@ | |||
853 | 2 | 2 | ||
854 | 3 | """Event listeners for the example web service.""" | 3 | """Event listeners for the example web service.""" |
855 | 4 | 4 | ||
856 | 5 | from __future__ import absolute_import, print_function | ||
857 | 6 | |||
858 | 7 | __metaclass__ = type | ||
859 | 8 | __all__ = ["update_cookbook_revision_number"] | 5 | __all__ = ["update_cookbook_revision_number"] |
860 | 9 | 6 | ||
861 | 10 | import grokcore.component | 7 | import grokcore.component |
862 | diff --git a/src/lazr/restful/example/base/tests/test_integration.py b/src/lazr/restful/example/base/tests/test_integration.py | |||
863 | index 99b987f..f0bbbb1 100644 | |||
864 | --- a/src/lazr/restful/example/base/tests/test_integration.py | |||
865 | +++ b/src/lazr/restful/example/base/tests/test_integration.py | |||
866 | @@ -2,9 +2,6 @@ | |||
867 | 2 | 2 | ||
868 | 3 | """Test harness for LAZR doctests.""" | 3 | """Test harness for LAZR doctests.""" |
869 | 4 | 4 | ||
870 | 5 | from __future__ import absolute_import, print_function | ||
871 | 6 | |||
872 | 7 | __metaclass__ = type | ||
873 | 8 | __all__ = [] | 5 | __all__ = [] |
874 | 9 | 6 | ||
875 | 10 | import os | 7 | import os |
876 | @@ -58,16 +55,11 @@ def load_tests(loader, tests, pattern): | |||
877 | 58 | for name in os.listdir(os.path.dirname(__file__)) | 55 | for name in os.listdir(os.path.dirname(__file__)) |
878 | 59 | if name.endswith(".txt") | 56 | if name.endswith(".txt") |
879 | 60 | ) | 57 | ) |
880 | 61 | globs = { | ||
881 | 62 | "absolute_import": absolute_import, | ||
882 | 63 | "print_function": print_function, | ||
883 | 64 | } | ||
884 | 65 | suite = doctest.DocFileSuite( | 58 | suite = doctest.DocFileSuite( |
885 | 66 | *doctest_files, | 59 | *doctest_files, |
886 | 67 | optionflags=DOCTEST_FLAGS, | 60 | optionflags=DOCTEST_FLAGS, |
887 | 68 | globs=globs, | ||
888 | 69 | encoding="UTF-8", | 61 | encoding="UTF-8", |
890 | 70 | checker=checker | 62 | checker=checker, |
891 | 71 | ) | 63 | ) |
892 | 72 | suite.layer = WSGILayer | 64 | suite.layer = WSGILayer |
893 | 73 | tests.addTest(suite) | 65 | tests.addTest(suite) |
894 | diff --git a/src/lazr/restful/example/base/traversal.py b/src/lazr/restful/example/base/traversal.py | |||
895 | index 4b06202..4ae07a9 100644 | |||
896 | --- a/src/lazr/restful/example/base/traversal.py | |||
897 | +++ b/src/lazr/restful/example/base/traversal.py | |||
898 | @@ -2,9 +2,6 @@ | |||
899 | 2 | 2 | ||
900 | 3 | """Traversal rules for the LAZR example web service.""" | 3 | """Traversal rules for the LAZR example web service.""" |
901 | 4 | 4 | ||
902 | 5 | from __future__ import absolute_import, print_function | ||
903 | 6 | |||
904 | 7 | __metaclass__ = type | ||
905 | 8 | __all__ = [ | 5 | __all__ = [ |
906 | 9 | "BelowRootAbsoluteURL", | 6 | "BelowRootAbsoluteURL", |
907 | 10 | "CookbookSetTraverse", | 7 | "CookbookSetTraverse", |
908 | @@ -99,6 +96,4 @@ class CookbookSetTraverse(TraverseWithGet): | |||
909 | 99 | url = absoluteURL(self.context.featured, request) + "{invalid}" | 96 | url = absoluteURL(self.context.featured, request) + "{invalid}" |
910 | 100 | return RedirectResource(url, request) | 97 | return RedirectResource(url, request) |
911 | 101 | else: | 98 | else: |
915 | 102 | return super(CookbookSetTraverse, self).publishTraverse( | 99 | return super().publishTraverse(request, name) |
913 | 103 | request, name | ||
914 | 104 | ) | ||
916 | diff --git a/src/lazr/restful/example/base_extended/comments.py b/src/lazr/restful/example/base_extended/comments.py | |||
917 | index 8db2763..5973204 100644 | |||
918 | --- a/src/lazr/restful/example/base_extended/comments.py | |||
919 | +++ b/src/lazr/restful/example/base_extended/comments.py | |||
920 | @@ -1,5 +1,3 @@ | |||
921 | 1 | from __future__ import absolute_import, print_function | ||
922 | 2 | |||
923 | 3 | from zope.component import adapter | 1 | from zope.component import adapter |
924 | 4 | from zope.interface import implementer, Interface | 2 | from zope.interface import implementer, Interface |
925 | 5 | from zope.schema import List, Text | 3 | from zope.schema import List, Text |
926 | @@ -15,7 +13,7 @@ from lazr.restful.declarations import ( | |||
927 | 15 | @exported_as_webservice_entry(contributes_to=[IRecipe]) | 13 | @exported_as_webservice_entry(contributes_to=[IRecipe]) |
928 | 16 | class IHasComments(Interface): | 14 | class IHasComments(Interface): |
929 | 17 | comments = exported( | 15 | comments = exported( |
931 | 18 | List(title=u"Comments made by users", value_type=Text()) | 16 | List(title="Comments made by users", value_type=Text()) |
932 | 19 | ) | 17 | ) |
933 | 20 | 18 | ||
934 | 21 | 19 | ||
935 | diff --git a/src/lazr/restful/example/base_extended/tests/test_integration.py b/src/lazr/restful/example/base_extended/tests/test_integration.py | |||
936 | index e5b0021..866c905 100644 | |||
937 | --- a/src/lazr/restful/example/base_extended/tests/test_integration.py | |||
938 | +++ b/src/lazr/restful/example/base_extended/tests/test_integration.py | |||
939 | @@ -2,9 +2,6 @@ | |||
940 | 2 | 2 | ||
941 | 3 | """Test harness for LAZR doctests.""" | 3 | """Test harness for LAZR doctests.""" |
942 | 4 | 4 | ||
943 | 5 | from __future__ import absolute_import, print_function | ||
944 | 6 | |||
945 | 7 | __metaclass__ = type | ||
946 | 8 | __all__ = [] | 5 | __all__ = [] |
947 | 9 | 6 | ||
948 | 10 | import os | 7 | import os |
949 | @@ -46,12 +43,8 @@ wsgi_intercept_layer(WSGILayer) | |||
950 | 46 | def load_tests(loader, tests, pattern): | 43 | def load_tests(loader, tests, pattern): |
951 | 47 | """See `zope.testing.testrunner`.""" | 44 | """See `zope.testing.testrunner`.""" |
952 | 48 | doctest_files = ["../README.txt"] | 45 | doctest_files = ["../README.txt"] |
953 | 49 | globs = { | ||
954 | 50 | "absolute_import": absolute_import, | ||
955 | 51 | "print_function": print_function, | ||
956 | 52 | } | ||
957 | 53 | suite = doctest.DocFileSuite( | 46 | suite = doctest.DocFileSuite( |
959 | 54 | *doctest_files, optionflags=DOCTEST_FLAGS, globs=globs, checker=checker | 47 | *doctest_files, optionflags=DOCTEST_FLAGS, checker=checker |
960 | 55 | ) | 48 | ) |
961 | 56 | suite.layer = WSGILayer | 49 | suite.layer = WSGILayer |
962 | 57 | tests.addTest(suite) | 50 | tests.addTest(suite) |
963 | diff --git a/src/lazr/restful/example/multiversion/resources.py b/src/lazr/restful/example/multiversion/resources.py | |||
964 | index 849d579..cf45690 100644 | |||
965 | --- a/src/lazr/restful/example/multiversion/resources.py | |||
966 | +++ b/src/lazr/restful/example/multiversion/resources.py | |||
967 | @@ -1,7 +1,3 @@ | |||
968 | 1 | from __future__ import absolute_import, print_function | ||
969 | 2 | |||
970 | 3 | __metaclass__ = type | ||
971 | 4 | |||
972 | 5 | __all__ = ["IKeyValuePair", "IPairSet", "KeyValuePair", "PairSet"] | 1 | __all__ = ["IKeyValuePair", "IPairSet", "KeyValuePair", "PairSet"] |
973 | 6 | 2 | ||
974 | 7 | from zope.interface import implementer | 3 | from zope.interface import implementer |
975 | @@ -36,14 +32,14 @@ from lazr.restful.example.wsgi.resources import ( | |||
976 | 36 | # define them separately. | 32 | # define them separately. |
977 | 37 | @exported_as_webservice_entry() | 33 | @exported_as_webservice_entry() |
978 | 38 | class IKeyValuePair(ILocation): | 34 | class IKeyValuePair(ILocation): |
981 | 39 | key = exported(Text(title=u"The key")) | 35 | key = exported(Text(title="The key")) |
982 | 40 | value = exported(Text(title=u"The value")) | 36 | value = exported(Text(title="The value")) |
983 | 41 | a_comment = exported( | 37 | a_comment = exported( |
985 | 42 | Text(title=u"A comment on this key-value pair.", readonly=True), | 38 | Text(title="A comment on this key-value pair.", readonly=True), |
986 | 43 | ("1.0", dict(exported=True, exported_as="comment")), | 39 | ("1.0", dict(exported=True, exported_as="comment")), |
987 | 44 | ) | 40 | ) |
988 | 45 | deleted = exported( | 41 | deleted = exported( |
990 | 46 | Bool(title=u"Whether this key-value pair has been " "deleted"), | 42 | Bool(title="Whether this key-value pair has been " "deleted"), |
991 | 47 | ("3.0", dict(exported=True)), | 43 | ("3.0", dict(exported=True)), |
992 | 48 | exported=False, | 44 | exported=False, |
993 | 49 | ) | 45 | ) |
994 | @@ -117,7 +113,7 @@ class PairSet(BasicPairSet): | |||
995 | 117 | @implementer(IKeyValuePair) | 113 | @implementer(IKeyValuePair) |
996 | 118 | class KeyValuePair(BasicKeyValuePair): | 114 | class KeyValuePair(BasicKeyValuePair): |
997 | 119 | def __init__(self, pairset, key, value): | 115 | def __init__(self, pairset, key, value): |
999 | 120 | super(KeyValuePair, self).__init__(pairset, key, value) | 116 | super().__init__(pairset, key, value) |
1000 | 121 | self.a_comment = "" | 117 | self.a_comment = "" |
1001 | 122 | self.deleted = False | 118 | self.deleted = False |
1002 | 123 | 119 | ||
1003 | diff --git a/src/lazr/restful/example/multiversion/root.py b/src/lazr/restful/example/multiversion/root.py | |||
1004 | index 2391d4b..c611cda 100644 | |||
1005 | --- a/src/lazr/restful/example/multiversion/root.py | |||
1006 | +++ b/src/lazr/restful/example/multiversion/root.py | |||
1007 | @@ -1,8 +1,5 @@ | |||
1008 | 1 | """The RESTful service root.""" | 1 | """The RESTful service root.""" |
1009 | 2 | 2 | ||
1010 | 3 | from __future__ import absolute_import, print_function | ||
1011 | 4 | |||
1012 | 5 | __metaclass__ = type | ||
1013 | 6 | __all__ = [ | 3 | __all__ = [ |
1014 | 7 | "BelowRootAbsoluteURL", | 4 | "BelowRootAbsoluteURL", |
1015 | 8 | "RootAbsoluteURL", | 5 | "RootAbsoluteURL", |
1016 | diff --git a/src/lazr/restful/example/multiversion/tests/test_integration.py b/src/lazr/restful/example/multiversion/tests/test_integration.py | |||
1017 | index 92772a4..ee04982 100644 | |||
1018 | --- a/src/lazr/restful/example/multiversion/tests/test_integration.py | |||
1019 | +++ b/src/lazr/restful/example/multiversion/tests/test_integration.py | |||
1020 | @@ -2,9 +2,6 @@ | |||
1021 | 2 | 2 | ||
1022 | 3 | """Test harness for doctests for lazr.restful multiversion example service.""" | 3 | """Test harness for doctests for lazr.restful multiversion example service.""" |
1023 | 4 | 4 | ||
1024 | 5 | from __future__ import absolute_import, print_function | ||
1025 | 6 | |||
1026 | 7 | __metaclass__ = type | ||
1027 | 8 | __all__ = [] | 5 | __all__ = [] |
1028 | 9 | 6 | ||
1029 | 10 | import os | 7 | import os |
1030 | @@ -59,12 +56,8 @@ def load_tests(loader, tests, pattern): | |||
1031 | 59 | for name in os.listdir(os.path.dirname(__file__)) | 56 | for name in os.listdir(os.path.dirname(__file__)) |
1032 | 60 | if name.endswith(".txt") | 57 | if name.endswith(".txt") |
1033 | 61 | ) | 58 | ) |
1034 | 62 | globs = { | ||
1035 | 63 | "absolute_import": absolute_import, | ||
1036 | 64 | "print_function": print_function, | ||
1037 | 65 | } | ||
1038 | 66 | suite = doctest.DocFileSuite( | 59 | suite = doctest.DocFileSuite( |
1040 | 67 | *doctest_files, optionflags=DOCTEST_FLAGS, globs=globs, checker=checker | 60 | *doctest_files, optionflags=DOCTEST_FLAGS, checker=checker |
1041 | 68 | ) | 61 | ) |
1042 | 69 | suite.layer = WSGILayer | 62 | suite.layer = WSGILayer |
1043 | 70 | tests.addTest(suite) | 63 | tests.addTest(suite) |
1044 | diff --git a/src/lazr/restful/example/wsgi/resources.py b/src/lazr/restful/example/wsgi/resources.py | |||
1045 | index ad42f66..1ae11fc 100644 | |||
1046 | --- a/src/lazr/restful/example/wsgi/resources.py | |||
1047 | +++ b/src/lazr/restful/example/wsgi/resources.py | |||
1048 | @@ -1,7 +1,3 @@ | |||
1049 | 1 | from __future__ import absolute_import, print_function | ||
1050 | 2 | |||
1051 | 3 | __metaclass__ = type | ||
1052 | 4 | |||
1053 | 5 | __all__ = ["IKeyValuePair", "IPairSet", "KeyValuePair", "PairSet"] | 1 | __all__ = ["IKeyValuePair", "IPairSet", "KeyValuePair", "PairSet"] |
1054 | 6 | 2 | ||
1055 | 7 | from zope.component import getUtility | 3 | from zope.component import getUtility |
1056 | @@ -21,8 +17,8 @@ from lazr.restful.simple import TraverseWithGet | |||
1057 | 21 | 17 | ||
1058 | 22 | @exported_as_webservice_entry() | 18 | @exported_as_webservice_entry() |
1059 | 23 | class IKeyValuePair(ILocation): | 19 | class IKeyValuePair(ILocation): |
1062 | 24 | key = exported(Text(title=u"The key")) | 20 | key = exported(Text(title="The key")) |
1063 | 25 | value = exported(Text(title=u"The value")) | 21 | value = exported(Text(title="The value")) |
1064 | 26 | 22 | ||
1065 | 27 | 23 | ||
1066 | 28 | @exported_as_webservice_collection(IKeyValuePair) | 24 | @exported_as_webservice_collection(IKeyValuePair) |
1067 | @@ -36,7 +32,7 @@ class IPairSet(ILocation): | |||
1068 | 36 | 32 | ||
1069 | 37 | 33 | ||
1070 | 38 | @implementer(IKeyValuePair, ILocation) | 34 | @implementer(IKeyValuePair, ILocation) |
1072 | 39 | class KeyValuePair(object): | 35 | class KeyValuePair: |
1073 | 40 | """An object representing a key-value pair""" | 36 | """An object representing a key-value pair""" |
1074 | 41 | 37 | ||
1075 | 42 | def __init__(self, set, key, value): | 38 | def __init__(self, set, key, value): |
1076 | diff --git a/src/lazr/restful/example/wsgi/root.py b/src/lazr/restful/example/wsgi/root.py | |||
1077 | index efd246d..a870d0b 100644 | |||
1078 | --- a/src/lazr/restful/example/wsgi/root.py | |||
1079 | +++ b/src/lazr/restful/example/wsgi/root.py | |||
1080 | @@ -1,8 +1,5 @@ | |||
1081 | 1 | """The RESTful service root.""" | 1 | """The RESTful service root.""" |
1082 | 2 | 2 | ||
1083 | 3 | from __future__ import absolute_import, print_function | ||
1084 | 4 | |||
1085 | 5 | __metaclass__ = type | ||
1086 | 6 | __all__ = [ | 3 | __all__ = [ |
1087 | 7 | "BelowRootAbsoluteURL", | 4 | "BelowRootAbsoluteURL", |
1088 | 8 | "RootAbsoluteURL", | 5 | "RootAbsoluteURL", |
1089 | diff --git a/src/lazr/restful/example/wsgi/run.py b/src/lazr/restful/example/wsgi/run.py | |||
1090 | index b49b188..ff0dedc 100644 | |||
1091 | --- a/src/lazr/restful/example/wsgi/run.py | |||
1092 | +++ b/src/lazr/restful/example/wsgi/run.py | |||
1093 | @@ -1,7 +1,5 @@ | |||
1094 | 1 | #!/usr/bin/python | 1 | #!/usr/bin/python |
1095 | 2 | 2 | ||
1096 | 3 | from __future__ import absolute_import, print_function | ||
1097 | 4 | |||
1098 | 5 | from lazr.restful.wsgi import WSGIApplication | 3 | from lazr.restful.wsgi import WSGIApplication |
1099 | 6 | 4 | ||
1100 | 7 | if __name__ == "__main__": | 5 | if __name__ == "__main__": |
1101 | diff --git a/src/lazr/restful/example/wsgi/tests/test_integration.py b/src/lazr/restful/example/wsgi/tests/test_integration.py | |||
1102 | index f8f5583..cc02ba7 100644 | |||
1103 | --- a/src/lazr/restful/example/wsgi/tests/test_integration.py | |||
1104 | +++ b/src/lazr/restful/example/wsgi/tests/test_integration.py | |||
1105 | @@ -2,9 +2,6 @@ | |||
1106 | 2 | 2 | ||
1107 | 3 | """Test harness for doctests for lazr.restful example WSGI service.""" | 3 | """Test harness for doctests for lazr.restful example WSGI service.""" |
1108 | 4 | 4 | ||
1109 | 5 | from __future__ import absolute_import, print_function | ||
1110 | 6 | |||
1111 | 7 | __metaclass__ = type | ||
1112 | 8 | __all__ = [] | 5 | __all__ = [] |
1113 | 9 | 6 | ||
1114 | 10 | import os | 7 | import os |
1115 | @@ -57,12 +54,8 @@ def load_tests(loader, tests, pattern): | |||
1116 | 57 | for name in os.listdir(os.path.dirname(__file__)) | 54 | for name in os.listdir(os.path.dirname(__file__)) |
1117 | 58 | if name.endswith(".txt") | 55 | if name.endswith(".txt") |
1118 | 59 | ) | 56 | ) |
1119 | 60 | globs = { | ||
1120 | 61 | "absolute_import": absolute_import, | ||
1121 | 62 | "print_function": print_function, | ||
1122 | 63 | } | ||
1123 | 64 | suite = doctest.DocFileSuite( | 57 | suite = doctest.DocFileSuite( |
1125 | 65 | *doctest_files, optionflags=DOCTEST_FLAGS, globs=globs, checker=checker | 58 | *doctest_files, optionflags=DOCTEST_FLAGS, checker=checker |
1126 | 66 | ) | 59 | ) |
1127 | 67 | suite.layer = WSGILayer | 60 | suite.layer = WSGILayer |
1128 | 68 | tests.addTest(suite) | 61 | tests.addTest(suite) |
1129 | diff --git a/src/lazr/restful/fields.py b/src/lazr/restful/fields.py | |||
1130 | index a9e9756..4699769 100644 | |||
1131 | --- a/src/lazr/restful/fields.py | |||
1132 | +++ b/src/lazr/restful/fields.py | |||
1133 | @@ -2,9 +2,6 @@ | |||
1134 | 2 | 2 | ||
1135 | 3 | """LAZR zope.schema.IField implementation.""" | 3 | """LAZR zope.schema.IField implementation.""" |
1136 | 4 | 4 | ||
1137 | 5 | from __future__ import absolute_import, print_function | ||
1138 | 6 | |||
1139 | 7 | __metaclass__ = type | ||
1140 | 8 | __all__ = [ | 5 | __all__ = [ |
1141 | 9 | "CollectionField", | 6 | "CollectionField", |
1142 | 10 | "Reference", | 7 | "Reference", |
1143 | @@ -39,7 +36,7 @@ class CollectionField(AbstractCollection): | |||
1144 | 39 | are managed through a dedicated API. | 36 | are managed through a dedicated API. |
1145 | 40 | """ | 37 | """ |
1146 | 41 | kwargs.setdefault("readonly", True) | 38 | kwargs.setdefault("readonly", True) |
1148 | 42 | super(CollectionField, self).__init__(*args, **kwargs) | 39 | super().__init__(*args, **kwargs) |
1149 | 43 | 40 | ||
1150 | 44 | 41 | ||
1151 | 45 | @implementer(IReference) | 42 | @implementer(IReference) |
1152 | @@ -75,4 +72,4 @@ class ReferenceChoice(Choice): | |||
1153 | 75 | """ | 72 | """ |
1154 | 76 | schema = kwargs.pop("schema", IObject) | 73 | schema = kwargs.pop("schema", IObject) |
1155 | 77 | self.schema = schema | 74 | self.schema = schema |
1157 | 78 | super(ReferenceChoice, self).__init__(*args, **kwargs) | 75 | super().__init__(*args, **kwargs) |
1158 | diff --git a/src/lazr/restful/frameworks/django.py b/src/lazr/restful/frameworks/django.py | |||
1159 | index a1d09c2..a7ae447 100644 | |||
1160 | --- a/src/lazr/restful/frameworks/django.py | |||
1161 | +++ b/src/lazr/restful/frameworks/django.py | |||
1162 | @@ -2,7 +2,6 @@ | |||
1163 | 2 | 2 | ||
1164 | 3 | """Helpers for publishing Django model objects in lazr.restful services.""" | 3 | """Helpers for publishing Django model objects in lazr.restful services.""" |
1165 | 4 | 4 | ||
1166 | 5 | __metaclass__ = type | ||
1167 | 6 | __all__ = [ | 5 | __all__ = [ |
1168 | 7 | "DjangoLocation", | 6 | "DjangoLocation", |
1169 | 8 | "DjangoWebServiceConfiguration", | 7 | "DjangoWebServiceConfiguration", |
1170 | @@ -102,7 +101,7 @@ class DjangoAbsoluteURL(AbsoluteURL): | |||
1171 | 102 | 101 | ||
1172 | 103 | 102 | ||
1173 | 104 | @implementer(ILocation) | 103 | @implementer(ILocation) |
1175 | 105 | class DjangoLocation(object): | 104 | class DjangoLocation: |
1176 | 106 | """Adapts Django model objects to ILocation. | 105 | """Adapts Django model objects to ILocation. |
1177 | 107 | 106 | ||
1178 | 108 | See `IDjangoLocation` for why Django model objects can't implement | 107 | See `IDjangoLocation` for why Django model objects can't implement |
1179 | @@ -125,7 +124,7 @@ grokcore.component.global_adapter(DjangoLocation, IDjangoLocation, ILocation) | |||
1180 | 125 | 124 | ||
1181 | 126 | 125 | ||
1182 | 127 | @implementer(IFiniteSequence) | 126 | @implementer(IFiniteSequence) |
1184 | 128 | class ManagerSequencer(object): | 127 | class ManagerSequencer: |
1185 | 129 | """Makes a Django manager object usable with lazr.batchnavigator. | 128 | """Makes a Django manager object usable with lazr.batchnavigator. |
1186 | 130 | 129 | ||
1187 | 131 | IFiniteSequence requires that we implement __len__, and either | 130 | IFiniteSequence requires that we implement __len__, and either |
1188 | diff --git a/src/lazr/restful/interface.py b/src/lazr/restful/interface.py | |||
1189 | index a69cf98..e63dcf1 100644 | |||
1190 | --- a/src/lazr/restful/interface.py | |||
1191 | +++ b/src/lazr/restful/interface.py | |||
1192 | @@ -2,9 +2,6 @@ | |||
1193 | 2 | 2 | ||
1194 | 3 | """Helpers for working with Zope interface.""" | 3 | """Helpers for working with Zope interface.""" |
1195 | 4 | 4 | ||
1196 | 5 | from __future__ import absolute_import, print_function | ||
1197 | 6 | |||
1198 | 7 | __metaclass__ = type | ||
1199 | 8 | __all__ = ["copy_attribute", "copy_field", "use_template"] | 5 | __all__ = ["copy_attribute", "copy_field", "use_template"] |
1200 | 9 | 6 | ||
1201 | 10 | import sys | 7 | import sys |
1202 | diff --git a/src/lazr/restful/interfaces/__init__.py b/src/lazr/restful/interfaces/__init__.py | |||
1203 | index b0d1c27..8c7ea66 100644 | |||
1204 | --- a/src/lazr/restful/interfaces/__init__.py | |||
1205 | +++ b/src/lazr/restful/interfaces/__init__.py | |||
1206 | @@ -17,8 +17,6 @@ | |||
1207 | 17 | 17 | ||
1208 | 18 | # pylint: disable-msg=W0401 | 18 | # pylint: disable-msg=W0401 |
1209 | 19 | 19 | ||
1210 | 20 | from __future__ import absolute_import, print_function | ||
1211 | 21 | |||
1212 | 22 | __version__ = 1.0 | 20 | __version__ = 1.0 |
1213 | 23 | 21 | ||
1214 | 24 | # Re-export in such a way that __version__ can still be imported if | 22 | # Re-export in such a way that __version__ can still be imported if |
1215 | diff --git a/src/lazr/restful/interfaces/_fields.py b/src/lazr/restful/interfaces/_fields.py | |||
1216 | index d48a87d..36a15c1 100644 | |||
1217 | --- a/src/lazr/restful/interfaces/_fields.py | |||
1218 | +++ b/src/lazr/restful/interfaces/_fields.py | |||
1219 | @@ -16,9 +16,6 @@ | |||
1220 | 16 | 16 | ||
1221 | 17 | """Interfaces for LAZR zope.schema fields.""" | 17 | """Interfaces for LAZR zope.schema fields.""" |
1222 | 18 | 18 | ||
1223 | 19 | from __future__ import absolute_import, print_function | ||
1224 | 20 | |||
1225 | 21 | __metaclass__ = type | ||
1226 | 22 | __all__ = [ | 19 | __all__ = [ |
1227 | 23 | "ICollectionField", | 20 | "ICollectionField", |
1228 | 24 | "IReference", | 21 | "IReference", |
1229 | diff --git a/src/lazr/restful/interfaces/_rest.py b/src/lazr/restful/interfaces/_rest.py | |||
1230 | index 9632dc6..8b92c74 100644 | |||
1231 | --- a/src/lazr/restful/interfaces/_rest.py | |||
1232 | +++ b/src/lazr/restful/interfaces/_rest.py | |||
1233 | @@ -18,9 +18,6 @@ | |||
1234 | 18 | # Pylint doesn't grok zope interfaces. | 18 | # Pylint doesn't grok zope interfaces. |
1235 | 19 | # pylint: disable-msg=E0211,E0213 | 19 | # pylint: disable-msg=E0211,E0213 |
1236 | 20 | 20 | ||
1237 | 21 | from __future__ import absolute_import, print_function | ||
1238 | 22 | |||
1239 | 23 | __metaclass__ = type | ||
1240 | 24 | __all__ = [ | 21 | __all__ = [ |
1241 | 25 | "IByteStorage", | 22 | "IByteStorage", |
1242 | 26 | "IByteStorageResource", | 23 | "IByteStorageResource", |
1243 | @@ -479,8 +476,8 @@ class IWebServiceConfiguration(Interface): | |||
1244 | 479 | caching_policy = List( | 476 | caching_policy = List( |
1245 | 480 | value_type=Int(), | 477 | value_type=Int(), |
1246 | 481 | default=[7 * 24 * HOUR, 1 * HOUR], | 478 | default=[7 * 24 * HOUR, 1 * HOUR], |
1249 | 482 | title=u"The web service caching policy.", | 479 | title="The web service caching policy.", |
1250 | 483 | description=u"""A list of two numbers, each to be used in the | 480 | description="""A list of two numbers, each to be used in the |
1251 | 484 | 'max-age' field of the Cache-Control header. The first number is | 481 | 'max-age' field of the Cache-Control header. The first number is |
1252 | 485 | used when serving the service root for any web service version | 482 | used when serving the service root for any web service version |
1253 | 486 | except the latest one. The second number is used when serving the | 483 | except the latest one. The second number is used when serving the |
1254 | @@ -489,32 +486,32 @@ class IWebServiceConfiguration(Interface): | |||
1255 | 489 | ) | 486 | ) |
1256 | 490 | 487 | ||
1257 | 491 | enable_server_side_representation_cache = Bool( | 488 | enable_server_side_representation_cache = Bool( |
1259 | 492 | title=u"Enable the server-side representation cache.", | 489 | title="Enable the server-side representation cache.", |
1260 | 493 | default=True, | 490 | default=True, |
1262 | 494 | description=u"""If this is false, the server-side representation | 491 | description="""If this is false, the server-side representation |
1263 | 495 | cache will not be used, even if one is registered.""", | 492 | cache will not be used, even if one is registered.""", |
1264 | 496 | ) | 493 | ) |
1265 | 497 | 494 | ||
1266 | 498 | service_description = TextLine( | 495 | service_description = TextLine( |
1269 | 499 | title=u"Service description", | 496 | title="Service description", |
1270 | 500 | description=u"""A human-readable description of the web service. | 497 | description="""A human-readable description of the web service. |
1271 | 501 | 498 | ||
1272 | 502 | The description may contain HTML, but if it does, it must be a | 499 | The description may contain HTML, but if it does, it must be a |
1273 | 503 | valid XHTML fragment. | 500 | valid XHTML fragment. |
1274 | 504 | """, | 501 | """, |
1276 | 505 | default=u"", | 502 | default="", |
1277 | 506 | ) | 503 | ) |
1278 | 507 | 504 | ||
1279 | 508 | view_permission = TextLine( | 505 | view_permission = TextLine( |
1283 | 509 | title=u"View permission", | 506 | title="View permission", |
1284 | 510 | default=u"zope.View", | 507 | default="zope.View", |
1285 | 511 | description=u"The permission to use when checking object visibility.", | 508 | description="The permission to use when checking object visibility.", |
1286 | 512 | ) | 509 | ) |
1287 | 513 | 510 | ||
1288 | 514 | path_override = TextLine( | 511 | path_override = TextLine( |
1292 | 515 | title=u"Web service path override", | 512 | title="Web service path override", |
1293 | 516 | default=u"api", | 513 | default="api", |
1294 | 517 | description=u"The path component for Ajax clients to use when making " | 514 | description="The path component for Ajax clients to use when making " |
1295 | 518 | "HTTP requests to the web service from their current virtual host. " | 515 | "HTTP requests to the web service from their current virtual host. " |
1296 | 519 | "The use of this path component (/api/foo instead of /foo) will " | 516 | "The use of this path component (/api/foo instead of /foo) will " |
1297 | 520 | "ensure that the request is processed as a web service request " | 517 | "ensure that the request is processed as a web service request " |
1298 | @@ -522,29 +519,29 @@ class IWebServiceConfiguration(Interface): | |||
1299 | 522 | ) | 519 | ) |
1300 | 523 | 520 | ||
1301 | 524 | use_https = Bool( | 521 | use_https = Bool( |
1303 | 525 | title=u"Web service is secured", | 522 | title="Web service is secured", |
1304 | 526 | default=True, | 523 | default=True, |
1306 | 527 | description=u"Whether or not requests to the web service are secured " | 524 | description="Whether or not requests to the web service are secured " |
1307 | 528 | "through SSL.", | 525 | "through SSL.", |
1308 | 529 | ) | 526 | ) |
1309 | 530 | 527 | ||
1310 | 531 | hostname = TextLine( | 528 | hostname = TextLine( |
1313 | 532 | title=u"The hostname to be used in generated URLs.", | 529 | title="The hostname to be used in generated URLs.", |
1314 | 533 | description=u"You only need to specify this if you're using the " | 530 | description="You only need to specify this if you're using the " |
1315 | 534 | "RootResourceAbsoluteURL class from lazr.restful.simple. This is " | 531 | "RootResourceAbsoluteURL class from lazr.restful.simple. This is " |
1316 | 535 | "the hostname of the lazr.restful application.", | 532 | "the hostname of the lazr.restful application.", |
1317 | 536 | ) | 533 | ) |
1318 | 537 | 534 | ||
1319 | 538 | port = Int( | 535 | port = Int( |
1322 | 539 | title=u"The TCP port on which the web service is running.", | 536 | title="The TCP port on which the web service is running.", |
1323 | 540 | description=u"Used in generated URLs.", | 537 | description="Used in generated URLs.", |
1324 | 541 | default=0, | 538 | default=0, |
1325 | 542 | ) | 539 | ) |
1326 | 543 | 540 | ||
1327 | 544 | service_root_uri_prefix = TextLine( | 541 | service_root_uri_prefix = TextLine( |
1331 | 545 | title=u"Any URL prefix necessary for the service root.", | 542 | title="Any URL prefix necessary for the service root.", |
1332 | 546 | default=u"", | 543 | default="", |
1333 | 547 | description=u"If your web service is not located at the root of " | 544 | description="If your web service is not located at the root of " |
1334 | 548 | "its domain (for instance, it's rooted at " | 545 | "its domain (for instance, it's rooted at " |
1335 | 549 | "http://foo.com/web-service/ instead of http://api.foo/com/, " | 546 | "http://foo.com/web-service/ instead of http://api.foo/com/, " |
1336 | 550 | "put the URL prefix here. (In the example case, the URL prefix " | 547 | "put the URL prefix here. (In the example case, the URL prefix " |
1337 | @@ -554,8 +551,8 @@ class IWebServiceConfiguration(Interface): | |||
1338 | 554 | active_versions = List( | 551 | active_versions = List( |
1339 | 555 | value_type=TextLine(), | 552 | value_type=TextLine(), |
1340 | 556 | default=[], | 553 | default=[], |
1343 | 557 | title=u"The active versions of the web service.", | 554 | title="The active versions of the web service.", |
1344 | 558 | description=u"""A list of names of active versions of this | 555 | description="""A list of names of active versions of this |
1345 | 559 | web service. They might be version numbers, names such as | 556 | web service. They might be version numbers, names such as |
1346 | 560 | "beta", or the date a particular version was finalized. | 557 | "beta", or the date a particular version was finalized. |
1347 | 561 | 558 | ||
1348 | @@ -571,8 +568,8 @@ class IWebServiceConfiguration(Interface): | |||
1349 | 571 | version_descriptions = Dict( | 568 | version_descriptions = Dict( |
1350 | 572 | key_type=TextLine(), | 569 | key_type=TextLine(), |
1351 | 573 | value_type=Text(), | 570 | value_type=Text(), |
1354 | 574 | title=u"Human-readable descriptions of the web service versions.", | 571 | title="Human-readable descriptions of the web service versions.", |
1355 | 575 | description=u"""A dictionary mapping version names to | 572 | description="""A dictionary mapping version names to |
1356 | 576 | human-readable descriptions. The descriptions should describe | 573 | human-readable descriptions. The descriptions should describe |
1357 | 577 | what distinguishes this version from other versions, and | 574 | what distinguishes this version from other versions, and |
1358 | 578 | mention if/when the version will be removed. | 575 | mention if/when the version will be removed. |
1359 | @@ -585,7 +582,7 @@ class IWebServiceConfiguration(Interface): | |||
1360 | 585 | 582 | ||
1361 | 586 | require_explicit_versions = Bool( | 583 | require_explicit_versions = Bool( |
1362 | 587 | default=False, | 584 | default=False, |
1364 | 588 | description=u"""If true, each exported field and named | 585 | description="""If true, each exported field and named |
1365 | 589 | operation must explicitly declare the first version in which | 586 | operation must explicitly declare the first version in which |
1366 | 590 | it appears. If false, fields and operations are published in | 587 | it appears. If false, fields and operations are published in |
1367 | 591 | all versions.""", | 588 | all versions.""", |
1368 | @@ -593,7 +590,7 @@ class IWebServiceConfiguration(Interface): | |||
1369 | 593 | 590 | ||
1370 | 594 | last_version_with_mutator_named_operations = TextLine( | 591 | last_version_with_mutator_named_operations = TextLine( |
1371 | 595 | default=None, | 592 | default=None, |
1373 | 596 | description=u"""In earlier versions of lazr.restful, mutator methods | 593 | description="""In earlier versions of lazr.restful, mutator methods |
1374 | 597 | were also published as named operations. This redundant | 594 | were also published as named operations. This redundant |
1375 | 598 | behavior is no longer enabled by default, but this setting | 595 | behavior is no longer enabled by default, but this setting |
1376 | 599 | allows for backwards compatibility. | 596 | allows for backwards compatibility. |
1377 | @@ -606,48 +603,48 @@ class IWebServiceConfiguration(Interface): | |||
1378 | 606 | 603 | ||
1379 | 607 | first_version_with_total_size_link = TextLine( | 604 | first_version_with_total_size_link = TextLine( |
1380 | 608 | default=None, | 605 | default=None, |
1382 | 609 | description=u"""In earlier versions of lazr.restful collections | 606 | description="""In earlier versions of lazr.restful collections |
1383 | 610 | included a total_size field, now they include a total_size_link | 607 | included a total_size field, now they include a total_size_link |
1384 | 611 | instead. Setting this value determines in which version the new | 608 | instead. Setting this value determines in which version the new |
1385 | 612 | behavior takes effect.""", | 609 | behavior takes effect.""", |
1386 | 613 | ) | 610 | ) |
1387 | 614 | 611 | ||
1388 | 615 | code_revision = TextLine( | 612 | code_revision = TextLine( |
1391 | 616 | default=u"", | 613 | default="", |
1392 | 617 | description=u"""A string designating the current revision | 614 | description="""A string designating the current revision |
1393 | 618 | number of the code running the webservice. This may be a | 615 | number of the code running the webservice. This may be a |
1394 | 619 | revision number from version control, or a hand-chosen version | 616 | revision number from version control, or a hand-chosen version |
1395 | 620 | number.""", | 617 | number.""", |
1396 | 621 | ) | 618 | ) |
1397 | 622 | 619 | ||
1398 | 623 | show_tracebacks = Bool( | 620 | show_tracebacks = Bool( |
1400 | 624 | title=u"Show tracebacks to end-users", | 621 | title="Show tracebacks to end-users", |
1401 | 625 | default=True, | 622 | default=True, |
1403 | 626 | description=u"Whether or not to show tracebacks in an HTTP response " | 623 | description="Whether or not to show tracebacks in an HTTP response " |
1404 | 627 | "for a request that raised an exception.", | 624 | "for a request that raised an exception.", |
1405 | 628 | ) | 625 | ) |
1406 | 629 | 626 | ||
1407 | 630 | default_batch_size = Int( | 627 | default_batch_size = Int( |
1409 | 631 | title=u"The default batch size to use when serving a collection", | 628 | title="The default batch size to use when serving a collection", |
1410 | 632 | default=50, | 629 | default=50, |
1412 | 633 | description=u"When the client requests a collection and doesn't " | 630 | description="When the client requests a collection and doesn't " |
1413 | 634 | "specify how many entries they want, this many entries will be " | 631 | "specify how many entries they want, this many entries will be " |
1414 | 635 | "served them in the first page.", | 632 | "served them in the first page.", |
1415 | 636 | ) | 633 | ) |
1416 | 637 | 634 | ||
1417 | 638 | max_batch_size = Int( | 635 | max_batch_size = Int( |
1419 | 639 | title=u"The maximum batch size", | 636 | title="The maximum batch size", |
1420 | 640 | default=300, | 637 | default=300, |
1422 | 641 | description=u"When the client requests a batch of entries from " | 638 | description="When the client requests a batch of entries from " |
1423 | 642 | "a collection, they will not be allowed to request more entries " | 639 | "a collection, they will not be allowed to request more entries " |
1424 | 643 | "in the batch than this.", | 640 | "in the batch than this.", |
1425 | 644 | ) | 641 | ) |
1426 | 645 | 642 | ||
1427 | 646 | compensate_for_mod_compress_etag_modification = Bool( | 643 | compensate_for_mod_compress_etag_modification = Bool( |
1429 | 647 | title=u"Accept incoming ETags that appear to have been modified " | 644 | title="Accept incoming ETags that appear to have been modified " |
1430 | 648 | "in transit by Apache's mod_compress.", | 645 | "in transit by Apache's mod_compress.", |
1431 | 649 | default=False, | 646 | default=False, |
1433 | 650 | description=u"""When mod_compress compresses an outgoing | 647 | description="""When mod_compress compresses an outgoing |
1434 | 651 | representation, it (correctly) modifies the ETag. But when | 648 | representation, it (correctly) modifies the ETag. But when |
1435 | 652 | that ETag comes back in on a conditional GET or PUT request, | 649 | that ETag comes back in on a conditional GET or PUT request, |
1436 | 653 | mod_compress does _not_ transparently remove the modification, | 650 | mod_compress does _not_ transparently remove the modification, |
1437 | diff --git a/src/lazr/restful/jsoncache.py b/src/lazr/restful/jsoncache.py | |||
1438 | index 5c217c2..02349c3 100644 | |||
1439 | --- a/src/lazr/restful/jsoncache.py | |||
1440 | +++ b/src/lazr/restful/jsoncache.py | |||
1441 | @@ -2,10 +2,6 @@ | |||
1442 | 2 | # | 2 | # |
1443 | 3 | """A class for storing resources where they can be seen by a template.""" | 3 | """A class for storing resources where they can be seen by a template.""" |
1444 | 4 | 4 | ||
1445 | 5 | from __future__ import absolute_import, print_function | ||
1446 | 6 | |||
1447 | 7 | __metaclass__ = type | ||
1448 | 8 | |||
1449 | 9 | __all__ = ["JSONRequestCache"] | 5 | __all__ = ["JSONRequestCache"] |
1450 | 10 | 6 | ||
1451 | 11 | from lazr.restful.interfaces import IJSONRequestCache, LAZR_WEBSERVICE_NS | 7 | from lazr.restful.interfaces import IJSONRequestCache, LAZR_WEBSERVICE_NS |
1452 | diff --git a/src/lazr/restful/marshallers.py b/src/lazr/restful/marshallers.py | |||
1453 | index bec584a..3439106 100644 | |||
1454 | --- a/src/lazr/restful/marshallers.py | |||
1455 | +++ b/src/lazr/restful/marshallers.py | |||
1456 | @@ -2,9 +2,6 @@ | |||
1457 | 2 | 2 | ||
1458 | 3 | """Marshallers for fields used in HTTP resources.""" | 3 | """Marshallers for fields used in HTTP resources.""" |
1459 | 4 | 4 | ||
1460 | 5 | from __future__ import absolute_import, print_function | ||
1461 | 6 | |||
1462 | 7 | __metaclass__ = type | ||
1463 | 8 | __all__ = [ | 5 | __all__ = [ |
1464 | 9 | "AbstractCollectionFieldMarshaller", | 6 | "AbstractCollectionFieldMarshaller", |
1465 | 10 | "BoolFieldMarshaller", | 7 | "BoolFieldMarshaller", |
1466 | @@ -31,7 +28,6 @@ import re | |||
1467 | 31 | 28 | ||
1468 | 32 | import pytz | 29 | import pytz |
1469 | 33 | import simplejson | 30 | import simplejson |
1470 | 34 | import six | ||
1471 | 35 | from six.moves.urllib.parse import unquote | 31 | from six.moves.urllib.parse import unquote |
1472 | 36 | 32 | ||
1473 | 37 | from zope.datetime import ( | 33 | from zope.datetime import ( |
1474 | @@ -92,9 +88,9 @@ class URLDereferencingMixin: | |||
1475 | 92 | request_host = full_request_host | 88 | request_host = full_request_host |
1476 | 93 | request_port = default_port | 89 | request_port = default_port |
1477 | 94 | 90 | ||
1479 | 95 | if not isinstance(url, six.string_types): | 91 | if not isinstance(url, str): |
1480 | 96 | raise ValueError( | 92 | raise ValueError( |
1482 | 97 | u"got '%s', expected string: %r" % (type(url).__name__, url) | 93 | "got '%s', expected string: %r" % (type(url).__name__, url) |
1483 | 98 | ) | 94 | ) |
1484 | 99 | if url.startswith("/"): | 95 | if url.startswith("/"): |
1485 | 100 | # It's a relative URI. Resolve it relative to the root of this | 96 | # It's a relative URI. Resolve it relative to the root of this |
1486 | @@ -145,9 +141,9 @@ class URLDereferencingMixin: | |||
1487 | 145 | resource = self.dereference_url(url) | 141 | resource = self.dereference_url(url) |
1488 | 146 | except NotFound: | 142 | except NotFound: |
1489 | 147 | # The URL doesn't correspond to any real object. | 143 | # The URL doesn't correspond to any real object. |
1491 | 148 | raise ValueError(u'No such object "%s".' % url) | 144 | raise ValueError('No such object "%s".' % url) |
1492 | 149 | except InvalidURIError: | 145 | except InvalidURIError: |
1494 | 150 | raise ValueError(u'"%s" is not a valid URI.' % url) | 146 | raise ValueError('"%s" is not a valid URI.' % url) |
1495 | 151 | # We looked up the URL and got the thing at the other end of | 147 | # We looked up the URL and got the thing at the other end of |
1496 | 152 | # the URL: a resource. But internally, a resource isn't a | 148 | # the URL: a resource. But internally, a resource isn't a |
1497 | 153 | # valid value for any schema field. Instead we want the object | 149 | # valid value for any schema field. Instead we want the object |
1498 | @@ -193,8 +189,8 @@ class SimpleFieldMarshaller: | |||
1499 | 193 | v = value | 189 | v = value |
1500 | 194 | if isinstance(v, bytes): | 190 | if isinstance(v, bytes): |
1501 | 195 | v = v.decode("utf8") # assume utf8 | 191 | v = v.decode("utf8") # assume utf8 |
1504 | 196 | elif not isinstance(v, six.text_type): | 192 | elif not isinstance(v, str): |
1505 | 197 | v = six.text_type(v) | 193 | v = str(v) |
1506 | 198 | value = simplejson.loads(v) | 194 | value = simplejson.loads(v) |
1507 | 199 | except (ValueError, TypeError): | 195 | except (ValueError, TypeError): |
1508 | 200 | # Pass the value as is. This saves client from having to encode | 196 | # Pass the value as is. This saves client from having to encode |
1509 | @@ -225,7 +221,7 @@ class SimpleFieldMarshaller: | |||
1510 | 225 | else: | 221 | else: |
1511 | 226 | expected_name = self._type.__name__ | 222 | expected_name = self._type.__name__ |
1512 | 227 | raise ValueError( | 223 | raise ValueError( |
1514 | 228 | u"got '%s', expected %s: %r" | 224 | "got '%s', expected %s: %r" |
1515 | 229 | % (type(value).__name__, expected_name, value) | 225 | % (type(value).__name__, expected_name, value) |
1516 | 230 | ) | 226 | ) |
1517 | 231 | return value | 227 | return value |
1518 | @@ -275,9 +271,7 @@ class FloatFieldMarshaller(SimpleFieldMarshaller): | |||
1519 | 275 | 271 | ||
1520 | 276 | Converts the value to a float. | 272 | Converts the value to a float. |
1521 | 277 | """ | 273 | """ |
1525 | 278 | return float( | 274 | return float(super()._marshall_from_json_data(value)) |
1523 | 279 | super(FloatFieldMarshaller, self)._marshall_from_json_data(value) | ||
1524 | 280 | ) | ||
1526 | 281 | 275 | ||
1527 | 282 | 276 | ||
1528 | 283 | class BytesFieldMarshaller(SimpleFieldMarshaller): | 277 | class BytesFieldMarshaller(SimpleFieldMarshaller): |
1529 | @@ -319,7 +313,7 @@ class BytesFieldMarshaller(SimpleFieldMarshaller): | |||
1530 | 319 | if safe_hasattr(value, "seek"): | 313 | if safe_hasattr(value, "seek"): |
1531 | 320 | value.seek(0) | 314 | value.seek(0) |
1532 | 321 | value = value.read() | 315 | value = value.read() |
1534 | 322 | elif not isinstance(value, (bytes, six.text_type)): | 316 | elif not isinstance(value, (bytes, str)): |
1535 | 323 | value = str(value).encode("UTF-8") | 317 | value = str(value).encode("UTF-8") |
1536 | 324 | else: | 318 | else: |
1537 | 325 | # Leave string conversion to _marshall_from_json_data. | 319 | # Leave string conversion to _marshall_from_json_data. |
1538 | @@ -331,17 +325,15 @@ class BytesFieldMarshaller(SimpleFieldMarshaller): | |||
1539 | 331 | 325 | ||
1540 | 332 | Convert all strings to byte strings. | 326 | Convert all strings to byte strings. |
1541 | 333 | """ | 327 | """ |
1543 | 334 | if isinstance(value, six.text_type): | 328 | if isinstance(value, str): |
1544 | 335 | value = value.encode("utf-8") | 329 | value = value.encode("utf-8") |
1548 | 336 | return super(BytesFieldMarshaller, self)._marshall_from_json_data( | 330 | return super()._marshall_from_json_data(value) |
1546 | 337 | value | ||
1547 | 338 | ) | ||
1549 | 339 | 331 | ||
1550 | 340 | 332 | ||
1551 | 341 | class TextFieldMarshaller(SimpleFieldMarshaller): | 333 | class TextFieldMarshaller(SimpleFieldMarshaller): |
1552 | 342 | """FieldMarshaller for IText fields.""" | 334 | """FieldMarshaller for IText fields.""" |
1553 | 343 | 335 | ||
1555 | 344 | _type = six.text_type | 336 | _type = str |
1556 | 345 | _type_error_message = "not a unicode string: %r" | 337 | _type_error_message = "not a unicode string: %r" |
1557 | 346 | 338 | ||
1558 | 347 | def _marshall_from_request(self, value): | 339 | def _marshall_from_request(self, value): |
1559 | @@ -349,12 +341,12 @@ class TextFieldMarshaller(SimpleFieldMarshaller): | |||
1560 | 349 | 341 | ||
1561 | 350 | Converts the value to unicode. | 342 | Converts the value to unicode. |
1562 | 351 | """ | 343 | """ |
1564 | 352 | value = six.text_type(value) | 344 | value = str(value) |
1565 | 353 | # multipart/form-data encoding of text fields is required (RFC 2046 | 345 | # multipart/form-data encoding of text fields is required (RFC 2046 |
1566 | 354 | # section 4.1.1) to use CRLF for line breaks. Normalize to | 346 | # section 4.1.1) to use CRLF for line breaks. Normalize to |
1567 | 355 | # Unix-style LF. | 347 | # Unix-style LF. |
1568 | 356 | value = re.sub(r"\r\n?", "\n", value) | 348 | value = re.sub(r"\r\n?", "\n", value) |
1570 | 357 | return super(TextFieldMarshaller, self)._marshall_from_request(value) | 349 | return super()._marshall_from_request(value) |
1571 | 358 | 350 | ||
1572 | 359 | 351 | ||
1573 | 360 | class FixedVocabularyFieldMarshaller(SimpleFieldMarshaller): | 352 | class FixedVocabularyFieldMarshaller(SimpleFieldMarshaller): |
1574 | @@ -369,7 +361,7 @@ class FixedVocabularyFieldMarshaller(SimpleFieldMarshaller): | |||
1575 | 369 | part of a multiadapter lookup of the appropriate | 361 | part of a multiadapter lookup of the appropriate |
1576 | 370 | marshaller. | 362 | marshaller. |
1577 | 371 | """ | 363 | """ |
1579 | 372 | super(FixedVocabularyFieldMarshaller, self).__init__(field, request) | 364 | super().__init__(field, request) |
1580 | 373 | 365 | ||
1581 | 374 | def unmarshall_to_closeup(self, entry, value): | 366 | def unmarshall_to_closeup(self, entry, value): |
1582 | 375 | """Describe all values, not just the selected value.""" | 367 | """Describe all values, not just the selected value.""" |
1583 | @@ -386,9 +378,7 @@ class TokenizedVocabularyFieldMarshaller(FixedVocabularyFieldMarshaller): | |||
1584 | 386 | """A marshaller that looks up value using a token in a vocabulary.""" | 378 | """A marshaller that looks up value using a token in a vocabulary.""" |
1585 | 387 | 379 | ||
1586 | 388 | def __init__(self, field, request, vocabulary): | 380 | def __init__(self, field, request, vocabulary): |
1590 | 389 | super(TokenizedVocabularyFieldMarshaller, self).__init__( | 381 | super().__init__(field, request, vocabulary) |
1588 | 390 | field, request, vocabulary | ||
1589 | 391 | ) | ||
1591 | 392 | 382 | ||
1592 | 393 | def _marshall_from_json_data(self, value): | 383 | def _marshall_from_json_data(self, value): |
1593 | 394 | """See `SimpleFieldMarshaller`. | 384 | """See `SimpleFieldMarshaller`. |
1594 | @@ -396,11 +386,9 @@ class TokenizedVocabularyFieldMarshaller(FixedVocabularyFieldMarshaller): | |||
1595 | 396 | Looks up the value as a token in the vocabulary. | 386 | Looks up the value as a token in the vocabulary. |
1596 | 397 | """ | 387 | """ |
1597 | 398 | try: | 388 | try: |
1601 | 399 | return self.field.vocabulary.getTermByToken( | 389 | return self.field.vocabulary.getTermByToken(str(value)).value |
1599 | 400 | six.text_type(value) | ||
1600 | 401 | ).value | ||
1602 | 402 | except LookupError: | 390 | except LookupError: |
1604 | 403 | raise ValueError(u"%r isn't a valid token" % value) | 391 | raise ValueError("%r isn't a valid token" % value) |
1605 | 404 | 392 | ||
1606 | 405 | 393 | ||
1607 | 406 | class DateTimeFieldMarshaller(SimpleFieldMarshaller): | 394 | class DateTimeFieldMarshaller(SimpleFieldMarshaller): |
1608 | @@ -454,7 +442,7 @@ class DateFieldMarshaller(DateTimeFieldMarshaller): | |||
1609 | 454 | 442 | ||
1610 | 455 | def _marshall_from_json_data(self, value): | 443 | def _marshall_from_json_data(self, value): |
1611 | 456 | """Parse the value as a datetime.date object.""" | 444 | """Parse the value as a datetime.date object.""" |
1613 | 457 | super_class = super(DateFieldMarshaller, self) | 445 | super_class = super() |
1614 | 458 | date_time = super_class._marshall_from_json_data(value) | 446 | date_time = super_class._marshall_from_json_data(value) |
1615 | 459 | return date_time.date() | 447 | return date_time.date() |
1616 | 460 | 448 | ||
1617 | @@ -475,7 +463,7 @@ class AbstractCollectionFieldMarshaller(SimpleFieldMarshaller): | |||
1618 | 475 | 463 | ||
1619 | 476 | This also looks for the appropriate marshaller for value_type. | 464 | This also looks for the appropriate marshaller for value_type. |
1620 | 477 | """ | 465 | """ |
1622 | 478 | super(AbstractCollectionFieldMarshaller, self).__init__(field, request) | 466 | super().__init__(field, request) |
1623 | 479 | self.value_marshaller = getMultiAdapter( | 467 | self.value_marshaller = getMultiAdapter( |
1624 | 480 | (field.value_type or Field(), request), IFieldMarshaller | 468 | (field.value_type or Field(), request), IFieldMarshaller |
1625 | 481 | ) | 469 | ) |
1626 | @@ -486,9 +474,7 @@ class AbstractCollectionFieldMarshaller(SimpleFieldMarshaller): | |||
1627 | 486 | Marshall every elements of the list using the appropriate | 474 | Marshall every elements of the list using the appropriate |
1628 | 487 | marshaller. | 475 | marshaller. |
1629 | 488 | """ | 476 | """ |
1633 | 489 | value = super( | 477 | value = super()._marshall_from_json_data(value) |
1631 | 490 | AbstractCollectionFieldMarshaller, self | ||
1632 | 491 | )._marshall_from_json_data(value) | ||
1634 | 492 | 478 | ||
1635 | 493 | # In AbstractCollection subclasses, _type contains the type object, | 479 | # In AbstractCollection subclasses, _type contains the type object, |
1636 | 494 | # which can be used as a factory. | 480 | # which can be used as a factory. |
1637 | @@ -556,7 +542,7 @@ class DictFieldMarshaller(SimpleFieldMarshaller): | |||
1638 | 556 | value_type. If key_type or value_type are not specified, the default | 542 | value_type. If key_type or value_type are not specified, the default |
1639 | 557 | field marshaller is used. | 543 | field marshaller is used. |
1640 | 558 | """ | 544 | """ |
1642 | 559 | super(DictFieldMarshaller, self).__init__(field, request) | 545 | super().__init__(field, request) |
1643 | 560 | self.key_marshaller = getMultiAdapter( | 546 | self.key_marshaller = getMultiAdapter( |
1644 | 561 | (field.key_type or Field(), request), IFieldMarshaller | 547 | (field.key_type or Field(), request), IFieldMarshaller |
1645 | 562 | ) | 548 | ) |
1646 | @@ -582,7 +568,7 @@ class DictFieldMarshaller(SimpleFieldMarshaller): | |||
1647 | 582 | try: | 568 | try: |
1648 | 583 | value = dict(nv.split(",", 2) for nv in value) | 569 | value = dict(nv.split(",", 2) for nv in value) |
1649 | 584 | except ValueError: | 570 | except ValueError: |
1651 | 585 | raise ValueError(u"got '%s', list of name,value pairs" % value) | 571 | raise ValueError("got '%s', list of name,value pairs" % value) |
1652 | 586 | return { | 572 | return { |
1653 | 587 | self.key_marshaller.marshall_from_json_data( | 573 | self.key_marshaller.marshall_from_json_data( |
1654 | 588 | key | 574 | key |
1655 | @@ -602,9 +588,7 @@ class DictFieldMarshaller(SimpleFieldMarshaller): | |||
1656 | 602 | if isinstance(value, list): | 588 | if isinstance(value, list): |
1657 | 603 | value = dict(value) | 589 | value = dict(value) |
1658 | 604 | # Call super to check for errors and raise a ValueError if necessary. | 590 | # Call super to check for errors and raise a ValueError if necessary. |
1662 | 605 | value = super(DictFieldMarshaller, self)._marshall_from_json_data( | 591 | value = super()._marshall_from_json_data(value) |
1660 | 606 | value | ||
1661 | 607 | ) | ||
1663 | 608 | return { | 592 | return { |
1664 | 609 | self.key_marshaller.marshall_from_json_data( | 593 | self.key_marshaller.marshall_from_json_data( |
1665 | 610 | key | 594 | key |
1666 | @@ -671,9 +655,7 @@ class SimpleVocabularyLookupFieldMarshaller(FixedVocabularyFieldMarshaller): | |||
1667 | 671 | 655 | ||
1668 | 672 | def __init__(self, field, request, vocabulary): | 656 | def __init__(self, field, request, vocabulary): |
1669 | 673 | """Initialize the marshaller with the vocabulary it'll use.""" | 657 | """Initialize the marshaller with the vocabulary it'll use.""" |
1673 | 674 | super(SimpleVocabularyLookupFieldMarshaller, self).__init__( | 658 | super().__init__(field, request, vocabulary) |
1671 | 675 | field, request, vocabulary | ||
1672 | 676 | ) | ||
1674 | 677 | self.vocabulary = vocabulary | 659 | self.vocabulary = vocabulary |
1675 | 678 | 660 | ||
1676 | 679 | def _marshall_from_json_data(self, value): | 661 | def _marshall_from_json_data(self, value): |
1677 | @@ -684,7 +666,7 @@ class SimpleVocabularyLookupFieldMarshaller(FixedVocabularyFieldMarshaller): | |||
1678 | 684 | return item | 666 | return item |
1679 | 685 | valid_titles.append(item.title) | 667 | valid_titles.append(item.title) |
1680 | 686 | raise ValueError( | 668 | raise ValueError( |
1682 | 687 | u'Invalid value "%s". Acceptable values are: %s' | 669 | 'Invalid value "%s". Acceptable values are: %s' |
1683 | 688 | % (value, ", ".join(valid_titles)) | 670 | % (value, ", ".join(valid_titles)) |
1684 | 689 | ) | 671 | ) |
1685 | 690 | 672 | ||
1686 | @@ -704,7 +686,7 @@ class ObjectLookupFieldMarshaller( | |||
1687 | 704 | """ | 686 | """ |
1688 | 705 | 687 | ||
1689 | 706 | def __init__(self, field, request, vocabulary=None): | 688 | def __init__(self, field, request, vocabulary=None): |
1691 | 707 | super(ObjectLookupFieldMarshaller, self).__init__(field, request) | 689 | super().__init__(field, request) |
1692 | 708 | self.vocabulary = vocabulary | 690 | self.vocabulary = vocabulary |
1693 | 709 | 691 | ||
1694 | 710 | @property | 692 | @property |
1695 | diff --git a/src/lazr/restful/metazcml.py b/src/lazr/restful/metazcml.py | |||
1696 | index 1fe9422..09c0274 100644 | |||
1697 | --- a/src/lazr/restful/metazcml.py | |||
1698 | +++ b/src/lazr/restful/metazcml.py | |||
1699 | @@ -2,9 +2,6 @@ | |||
1700 | 2 | 2 | ||
1701 | 3 | """ZCML registration directives for the LAZR webservice framework.""" | 3 | """ZCML registration directives for the LAZR webservice framework.""" |
1702 | 4 | 4 | ||
1703 | 5 | from __future__ import absolute_import, print_function | ||
1704 | 6 | |||
1705 | 7 | __metaclass__ = type | ||
1706 | 8 | __all__ = [] | 5 | __all__ = [] |
1707 | 9 | 6 | ||
1708 | 10 | 7 | ||
1709 | @@ -82,7 +79,7 @@ class IRegisterDirective(Interface): | |||
1710 | 82 | """ | 79 | """ |
1711 | 83 | 80 | ||
1712 | 84 | module = GlobalObject( | 81 | module = GlobalObject( |
1714 | 85 | title=u"Module which will be inspected for webservice declarations" | 82 | title="Module which will be inspected for webservice declarations" |
1715 | 86 | ) | 83 | ) |
1716 | 87 | 84 | ||
1717 | 88 | 85 | ||
1718 | diff --git a/src/lazr/restful/publisher.py b/src/lazr/restful/publisher.py | |||
1719 | index eb628a4..92b668a 100644 | |||
1720 | --- a/src/lazr/restful/publisher.py | |||
1721 | +++ b/src/lazr/restful/publisher.py | |||
1722 | @@ -6,9 +6,6 @@ This module defines classes that are usually needed for integration | |||
1723 | 6 | with the Zope publisher. | 6 | with the Zope publisher. |
1724 | 7 | """ | 7 | """ |
1725 | 8 | 8 | ||
1726 | 9 | from __future__ import absolute_import, division, print_function | ||
1727 | 10 | |||
1728 | 11 | __metaclass__ = type | ||
1729 | 12 | __all__ = [ | 9 | __all__ = [ |
1730 | 13 | "browser_request_to_web_service_request", | 10 | "browser_request_to_web_service_request", |
1731 | 14 | "WebServicePublicationMixin", | 11 | "WebServicePublicationMixin", |
1732 | @@ -119,9 +116,7 @@ class WebServicePublicationMixin: | |||
1733 | 119 | else: | 116 | else: |
1734 | 120 | # Falls through to our parent version. | 117 | # Falls through to our parent version. |
1735 | 121 | pass | 118 | pass |
1739 | 122 | return super(WebServicePublicationMixin, self).traverseName( | 119 | return super().traverseName(request, ob, name) |
1737 | 123 | request, ob, name | ||
1738 | 124 | ) | ||
1740 | 125 | 120 | ||
1741 | 126 | def _traverseToByteStorage(self, request, entry, field, name): | 121 | def _traverseToByteStorage(self, request, entry, field, name): |
1742 | 127 | """Try to traverse to a byte storage resource in entry.""" | 122 | """Try to traverse to a byte storage resource in entry.""" |
1743 | @@ -223,9 +218,7 @@ class WebServicePublicationMixin: | |||
1744 | 223 | 218 | ||
1745 | 224 | def callObject(self, request, object): | 219 | def callObject(self, request, object): |
1746 | 225 | """Help web browsers handle redirects correctly.""" | 220 | """Help web browsers handle redirects correctly.""" |
1750 | 226 | value = super(WebServicePublicationMixin, self).callObject( | 221 | value = super().callObject(request, object) |
1748 | 227 | request, object | ||
1749 | 228 | ) | ||
1751 | 229 | self._processNotifications(request) | 222 | self._processNotifications(request) |
1752 | 230 | if request.response.getStatus() // 100 == 3: | 223 | if request.response.getStatus() // 100 == 3: |
1753 | 231 | if IWebBrowserInitiatedRequest.providedBy(request): | 224 | if IWebBrowserInitiatedRequest.providedBy(request): |
1754 | @@ -263,7 +256,7 @@ class WebServicePublicationMixin: | |||
1755 | 263 | 256 | ||
1756 | 264 | 257 | ||
1757 | 265 | @implementer(IWebServiceClientRequest) | 258 | @implementer(IWebServiceClientRequest) |
1759 | 266 | class WebServiceRequestTraversal(object): | 259 | class WebServiceRequestTraversal: |
1760 | 267 | """Mixin providing web-service resource wrapping in traversal. | 260 | """Mixin providing web-service resource wrapping in traversal. |
1761 | 268 | 261 | ||
1762 | 269 | This should be mixed in the request using to the base publication used. | 262 | This should be mixed in the request using to the base publication used. |
1763 | @@ -288,7 +281,7 @@ class WebServiceRequestTraversal(object): | |||
1764 | 288 | # was requested and has set the application appropriately, so | 281 | # was requested and has set the application appropriately, so |
1765 | 289 | # now we can get a good value for 'ob' and traverse it. | 282 | # now we can get a good value for 'ob' and traverse it. |
1766 | 290 | ob = self.publication.getApplication(self) | 283 | ob = self.publication.getApplication(self) |
1768 | 291 | result = super(WebServiceRequestTraversal, self).traverse(ob) | 284 | result = super().traverse(ob) |
1769 | 292 | return self.publication.getResource(self, result) | 285 | return self.publication.getResource(self, result) |
1770 | 293 | 286 | ||
1771 | 294 | def _removeVirtualHostTraversals(self): | 287 | def _removeVirtualHostTraversals(self): |
1772 | diff --git a/src/lazr/restful/security.py b/src/lazr/restful/security.py | |||
1773 | index 05d5802..f7cc532 100644 | |||
1774 | --- a/src/lazr/restful/security.py | |||
1775 | +++ b/src/lazr/restful/security.py | |||
1776 | @@ -2,9 +2,6 @@ | |||
1777 | 2 | 2 | ||
1778 | 3 | """Utilities for dealing with zope security.""" | 3 | """Utilities for dealing with zope security.""" |
1779 | 4 | 4 | ||
1780 | 5 | from __future__ import absolute_import, print_function | ||
1781 | 6 | |||
1782 | 7 | __metaclass__ = type | ||
1783 | 8 | __all__ = [ | 5 | __all__ = [ |
1784 | 9 | "protect_schema", | 6 | "protect_schema", |
1785 | 10 | ] | 7 | ] |
1786 | diff --git a/src/lazr/restful/simple.py b/src/lazr/restful/simple.py | |||
1787 | index b846e96..2c58320 100644 | |||
1788 | --- a/src/lazr/restful/simple.py | |||
1789 | +++ b/src/lazr/restful/simple.py | |||
1790 | @@ -1,8 +1,5 @@ | |||
1791 | 1 | """Simple implementations of various Zope and lazr.restful interfaces.""" | 1 | """Simple implementations of various Zope and lazr.restful interfaces.""" |
1792 | 2 | 2 | ||
1793 | 3 | from __future__ import absolute_import, print_function | ||
1794 | 4 | |||
1795 | 5 | __metaclass__ = type | ||
1796 | 6 | __all__ = [ | 3 | __all__ = [ |
1797 | 7 | "BaseRepresentationCache", | 4 | "BaseRepresentationCache", |
1798 | 8 | "BaseWebServiceConfiguration", | 5 | "BaseWebServiceConfiguration", |
1799 | @@ -20,7 +17,6 @@ __all__ = [ | |||
1800 | 20 | 17 | ||
1801 | 21 | import traceback | 18 | import traceback |
1802 | 22 | 19 | ||
1803 | 23 | import six | ||
1804 | 24 | from six.moves.urllib.parse import ( | 20 | from six.moves.urllib.parse import ( |
1805 | 25 | quote, | 21 | quote, |
1806 | 26 | unquote, | 22 | unquote, |
1807 | @@ -63,7 +59,7 @@ from lazr.restful.utils import ( | |||
1808 | 63 | 59 | ||
1809 | 64 | 60 | ||
1810 | 65 | @implementer(IPublication) | 61 | @implementer(IPublication) |
1812 | 66 | class PublicationMixin(object): | 62 | class PublicationMixin: |
1813 | 67 | """A very simple implementation of `IPublication`. | 63 | """A very simple implementation of `IPublication`. |
1814 | 68 | 64 | ||
1815 | 69 | The object passed to the constructor is returned by getApplication(). | 65 | The object passed to the constructor is returned by getApplication(). |
1816 | @@ -160,7 +156,7 @@ class Publication(WebServicePublicationMixin, PublicationMixin): | |||
1817 | 160 | 156 | ||
1818 | 161 | 157 | ||
1819 | 162 | @implementer(ITraverseWithGet) | 158 | @implementer(ITraverseWithGet) |
1821 | 163 | class TraverseWithGet(object): | 159 | class TraverseWithGet: |
1822 | 164 | """An implementation of `IPublishTraverse` that uses the get() method. | 160 | """An implementation of `IPublishTraverse` that uses the get() method. |
1823 | 165 | 161 | ||
1824 | 166 | This is a simple traversal technique that works with any object | 162 | This is a simple traversal technique that works with any object |
1825 | @@ -395,9 +391,7 @@ class MultiplePathPartAbsoluteURL: | |||
1826 | 395 | parts = getattr(self.context, "__path_parts__", None) | 391 | parts = getattr(self.context, "__path_parts__", None) |
1827 | 396 | if parts is None: | 392 | if parts is None: |
1828 | 397 | raise TypeError(_insufficientContext) | 393 | raise TypeError(_insufficientContext) |
1832 | 398 | if isinstance(parts, six.string_types) or not hasattr( | 394 | if isinstance(parts, str) or not hasattr(parts, "__iter__"): |
1830 | 399 | parts, "__iter__" | ||
1831 | 400 | ): | ||
1833 | 401 | raise TypeError( | 395 | raise TypeError( |
1834 | 402 | "Expected an iterable of strings for __path_parts__." | 396 | "Expected an iterable of strings for __path_parts__." |
1835 | 403 | ) | 397 | ) |
1836 | @@ -409,7 +403,7 @@ class MultiplePathPartAbsoluteURL: | |||
1837 | 409 | 403 | ||
1838 | 410 | 404 | ||
1839 | 411 | @implementer(IRepresentationCache) | 405 | @implementer(IRepresentationCache) |
1841 | 412 | class BaseRepresentationCache(object): | 406 | class BaseRepresentationCache: |
1842 | 413 | """A useful base class for representation caches. | 407 | """A useful base class for representation caches. |
1843 | 414 | 408 | ||
1844 | 415 | When an object is invalidated, all of its representations must be | 409 | When an object is invalidated, all of its representations must be |
1845 | diff --git a/src/lazr/restful/tales.py b/src/lazr/restful/tales.py | |||
1846 | index 2968667..0be2185 100644 | |||
1847 | --- a/src/lazr/restful/tales.py | |||
1848 | +++ b/src/lazr/restful/tales.py | |||
1849 | @@ -26,10 +26,6 @@ | |||
1850 | 26 | 26 | ||
1851 | 27 | """Implementation of the ws: namespace in TALES.""" | 27 | """Implementation of the ws: namespace in TALES.""" |
1852 | 28 | 28 | ||
1853 | 29 | from __future__ import absolute_import, print_function | ||
1854 | 30 | |||
1855 | 31 | __metaclass__ = type | ||
1856 | 32 | |||
1857 | 33 | import operator | 29 | import operator |
1858 | 34 | import re | 30 | import re |
1859 | 35 | import simplejson | 31 | import simplejson |
1860 | @@ -370,7 +366,7 @@ class WadlEntryResourceAPI(WadlResourceAPI): | |||
1861 | 370 | 366 | ||
1862 | 371 | def __init__(self, entry_resource): | 367 | def __init__(self, entry_resource): |
1863 | 372 | "Initialize with an entry resource." | 368 | "Initialize with an entry resource." |
1865 | 373 | super(WadlEntryResourceAPI, self).__init__(entry_resource) | 369 | super().__init__(entry_resource) |
1866 | 374 | self.entry = self.resource.entry | 370 | self.entry = self.resource.entry |
1867 | 375 | self.schema = self.entry.schema | 371 | self.schema = self.entry.schema |
1868 | 376 | 372 | ||
1869 | @@ -407,7 +403,7 @@ class WadlCollectionResourceAPI(WadlResourceAPI): | |||
1870 | 407 | + quote(relationship_name) | 403 | + quote(relationship_name) |
1871 | 408 | ) | 404 | ) |
1872 | 409 | else: | 405 | else: |
1874 | 410 | return super(WadlCollectionResourceAPI, self).url | 406 | return super().url |
1875 | 411 | 407 | ||
1876 | 412 | @property | 408 | @property |
1877 | 413 | def type_link(self): | 409 | def type_link(self): |
1878 | @@ -563,9 +559,7 @@ class WadlEntryInterfaceAdapterAPI(WadlResourceAdapterAPI): | |||
1879 | 563 | """ | 559 | """ |
1880 | 564 | 560 | ||
1881 | 565 | def __init__(self, entry_interface): | 561 | def __init__(self, entry_interface): |
1885 | 566 | super(WadlEntryInterfaceAdapterAPI, self).__init__( | 562 | super().__init__(entry_interface, IEntry) |
1883 | 567 | entry_interface, IEntry | ||
1884 | 568 | ) | ||
1886 | 569 | self.utility = EntryAdapterUtility.forEntryInterface( | 563 | self.utility = EntryAdapterUtility.forEntryInterface( |
1887 | 570 | entry_interface, get_current_web_service_request() | 564 | entry_interface, get_current_web_service_request() |
1888 | 571 | ) | 565 | ) |
1889 | @@ -584,7 +578,7 @@ class WadlEntryAdapterAPI(WadlResourceAdapterAPI): | |||
1890 | 584 | """ | 578 | """ |
1891 | 585 | 579 | ||
1892 | 586 | def __init__(self, adapter): | 580 | def __init__(self, adapter): |
1894 | 587 | super(WadlEntryAdapterAPI, self).__init__(adapter, IEntry) | 581 | super().__init__(adapter, IEntry) |
1895 | 588 | self.utility = EntryAdapterUtility(adapter) | 582 | self.utility = EntryAdapterUtility(adapter) |
1896 | 589 | 583 | ||
1897 | 590 | @property | 584 | @property |
1898 | @@ -662,7 +656,7 @@ class WadlCollectionAdapterAPI(WadlResourceAdapterAPI): | |||
1899 | 662 | "Namespace for WADL functions that operate on collection adapters." | 656 | "Namespace for WADL functions that operate on collection adapters." |
1900 | 663 | 657 | ||
1901 | 664 | def __init__(self, adapter): | 658 | def __init__(self, adapter): |
1903 | 665 | super(WadlCollectionAdapterAPI, self).__init__(adapter, ICollection) | 659 | super().__init__(adapter, ICollection) |
1904 | 666 | 660 | ||
1905 | 667 | @property | 661 | @property |
1906 | 668 | def collection_type(self): | 662 | def collection_type(self): |
1907 | diff --git a/src/lazr/restful/testing/event.py b/src/lazr/restful/testing/event.py | |||
1908 | index 7431413..e199790 100644 | |||
1909 | --- a/src/lazr/restful/testing/event.py | |||
1910 | +++ b/src/lazr/restful/testing/event.py | |||
1911 | @@ -2,10 +2,6 @@ | |||
1912 | 2 | 2 | ||
1913 | 3 | """Helper class for checking the event notifications.""" | 3 | """Helper class for checking the event notifications.""" |
1914 | 4 | 4 | ||
1915 | 5 | from __future__ import absolute_import, print_function | ||
1916 | 6 | |||
1917 | 7 | __metaclass__ = type | ||
1918 | 8 | |||
1919 | 9 | import zope.component | 5 | import zope.component |
1920 | 10 | 6 | ||
1921 | 11 | 7 | ||
1922 | diff --git a/src/lazr/restful/testing/helpers.py b/src/lazr/restful/testing/helpers.py | |||
1923 | index 46c7d90..fc9c8b1 100644 | |||
1924 | --- a/src/lazr/restful/testing/helpers.py | |||
1925 | +++ b/src/lazr/restful/testing/helpers.py | |||
1926 | @@ -1,5 +1,3 @@ | |||
1927 | 1 | from __future__ import absolute_import, print_function | ||
1928 | 2 | |||
1929 | 3 | import sys | 1 | import sys |
1930 | 4 | from types import ModuleType | 2 | from types import ModuleType |
1931 | 5 | 3 | ||
1932 | diff --git a/src/lazr/restful/testing/tales.py b/src/lazr/restful/testing/tales.py | |||
1933 | index ad64e0b..ce08dce 100644 | |||
1934 | --- a/src/lazr/restful/testing/tales.py | |||
1935 | +++ b/src/lazr/restful/testing/tales.py | |||
1936 | @@ -2,10 +2,6 @@ | |||
1937 | 2 | 2 | ||
1938 | 3 | """Helper functions for testing TALES expressions.""" | 3 | """Helper functions for testing TALES expressions.""" |
1939 | 4 | 4 | ||
1940 | 5 | from __future__ import absolute_import, print_function | ||
1941 | 6 | |||
1942 | 7 | __metaclass__ = type | ||
1943 | 8 | |||
1944 | 9 | __all__ = [ | 5 | __all__ = [ |
1945 | 10 | "test_tales", | 6 | "test_tales", |
1946 | 11 | ] | 7 | ] |
1947 | diff --git a/src/lazr/restful/testing/webservice.py b/src/lazr/restful/testing/webservice.py | |||
1948 | index 9eccb04..a4405b1 100644 | |||
1949 | --- a/src/lazr/restful/testing/webservice.py | |||
1950 | +++ b/src/lazr/restful/testing/webservice.py | |||
1951 | @@ -2,9 +2,6 @@ | |||
1952 | 2 | 2 | ||
1953 | 3 | """Testing helpers for webservice unit tests.""" | 3 | """Testing helpers for webservice unit tests.""" |
1954 | 4 | 4 | ||
1955 | 5 | from __future__ import absolute_import, print_function | ||
1956 | 6 | |||
1957 | 7 | __metaclass__ = type | ||
1958 | 8 | __all__ = [ | 5 | __all__ = [ |
1959 | 9 | "create_web_service_request", | 6 | "create_web_service_request", |
1960 | 10 | "StubAbsoluteURL", | 7 | "StubAbsoluteURL", |
1961 | @@ -141,7 +138,7 @@ class FakeResponse: | |||
1962 | 141 | if result is None: | 138 | if result is None: |
1963 | 142 | result = "" | 139 | result = "" |
1964 | 143 | 140 | ||
1966 | 144 | if not isinstance(result, six.string_types): | 141 | if not isinstance(result, str): |
1967 | 145 | raise ValueError("only strings and None results are handled") | 142 | raise ValueError("only strings and None results are handled") |
1968 | 146 | 143 | ||
1969 | 147 | self.result = result | 144 | self.result = result |
1970 | @@ -200,7 +197,7 @@ def pformat_value(value): | |||
1971 | 200 | JSON strings are always Unicode, never bytes, so this doesn't introduce | 197 | JSON strings are always Unicode, never bytes, so this doesn't introduce |
1972 | 201 | ambiguity. | 198 | ambiguity. |
1973 | 202 | """ | 199 | """ |
1975 | 203 | if isinstance(value, six.text_type): | 200 | if isinstance(value, str): |
1976 | 204 | value = value.encode("unicode_escape").decode("ASCII") | 201 | value = value.encode("unicode_escape").decode("ASCII") |
1977 | 205 | if "'" in value and '"' not in value: | 202 | if "'" in value and '"' not in value: |
1978 | 206 | return '"%s"' % value | 203 | return '"%s"' % value |
1979 | @@ -259,7 +256,7 @@ class WebServiceApplication(Application): | |||
1980 | 259 | """A WSGI application for the tests.""" | 256 | """A WSGI application for the tests.""" |
1981 | 260 | 257 | ||
1982 | 261 | def __init__(self, global_config, publication, **options): | 258 | def __init__(self, global_config, publication, **options): |
1984 | 262 | if isinstance(publication, six.string_types): | 259 | if isinstance(publication, str): |
1985 | 263 | Application.__init__(self, global_config, publication, **options) | 260 | Application.__init__(self, global_config, publication, **options) |
1986 | 264 | else: | 261 | else: |
1987 | 265 | self.publication = publication(global_config, **options) | 262 | self.publication = publication(global_config, **options) |
1988 | @@ -329,7 +326,7 @@ class WebServiceCaller: | |||
1989 | 329 | headers=None, | 326 | headers=None, |
1990 | 330 | api_version=None, | 327 | api_version=None, |
1991 | 331 | ): | 328 | ): |
1993 | 332 | if isinstance(path_or_url, (bytes, six.text_type)): | 329 | if isinstance(path_or_url, (bytes, str)): |
1994 | 333 | path_or_url = six.ensure_str(path_or_url) | 330 | path_or_url = six.ensure_str(path_or_url) |
1995 | 334 | else: | 331 | else: |
1996 | 335 | path_or_url = str(path_or_url) | 332 | path_or_url = str(path_or_url) |
1997 | @@ -468,7 +465,7 @@ class WebServiceCaller: | |||
1998 | 468 | if isinstance(value, io.BufferedIOBase): | 465 | if isinstance(value, io.BufferedIOBase): |
1999 | 469 | buf.write(value.read()) | 466 | buf.write(value.read()) |
2000 | 470 | else: | 467 | else: |
2002 | 471 | if not isinstance(value, six.string_types): | 468 | if not isinstance(value, str): |
2003 | 472 | value = simplejson.dumps(value) | 469 | value = simplejson.dumps(value) |
2004 | 473 | lines = re.split(r"\r\n|\r|\n", value) | 470 | lines = re.split(r"\r\n|\r|\n", value) |
2005 | 474 | for line in lines[:-1]: | 471 | for line in lines[:-1]: |
2006 | @@ -536,7 +533,7 @@ class WebServiceCaller: | |||
2007 | 536 | 533 | ||
2008 | 537 | This may mean turning the value into a JSON string. | 534 | This may mean turning the value into a JSON string. |
2009 | 538 | """ | 535 | """ |
2011 | 539 | if not isinstance(value, six.string_types): | 536 | if not isinstance(value, str): |
2012 | 540 | value = simplejson.dumps(value) | 537 | value = simplejson.dumps(value) |
2013 | 541 | return quote(value) | 538 | return quote(value) |
2014 | 542 | 539 | ||
2015 | @@ -560,17 +557,16 @@ class WebServiceAjaxCaller(WebServiceCaller): | |||
2016 | 560 | def default_api_version(self): | 557 | def default_api_version(self): |
2017 | 561 | """Introduce the Ajax path override to the URI prefix.""" | 558 | """Introduce the Ajax path override to the URI prefix.""" |
2018 | 562 | config = getUtility(IWebServiceConfiguration) | 559 | config = getUtility(IWebServiceConfiguration) |
2020 | 563 | default_version = super(WebServiceAjaxCaller, self).default_api_version | 560 | default_version = super().default_api_version |
2021 | 564 | return config.path_override + "/" + default_version | 561 | return config.path_override + "/" + default_version |
2022 | 565 | 562 | ||
2023 | 566 | 563 | ||
2024 | 567 | @six.python_2_unicode_compatible | ||
2025 | 568 | class WebServiceResponseWrapper(ProxyBase): | 564 | class WebServiceResponseWrapper(ProxyBase): |
2026 | 569 | """A response from the web service with easy access to the JSON body.""" | 565 | """A response from the web service with easy access to the JSON body.""" |
2027 | 570 | 566 | ||
2028 | 571 | def __init__(self, response): | 567 | def __init__(self, response): |
2029 | 572 | self.body = response.read() | 568 | self.body = response.read() |
2031 | 573 | super(WebServiceResponseWrapper, self).__init__(response) | 569 | super().__init__(response) |
2032 | 574 | 570 | ||
2033 | 575 | def getHeader(self, key, default=None): | 571 | def getHeader(self, key, default=None): |
2034 | 576 | return self.getheader(key, default) | 572 | return self.getheader(key, default) |
2035 | @@ -659,7 +655,7 @@ class TestCaseWithWebServiceFixtures(CleanUp, unittest.TestCase): | |||
2036 | 659 | """ | 655 | """ |
2037 | 660 | 656 | ||
2038 | 661 | def setUp(self): | 657 | def setUp(self): |
2040 | 662 | super(TestCaseWithWebServiceFixtures, self).setUp() | 658 | super().setUp() |
2041 | 663 | # Register a simple configuration object. | 659 | # Register a simple configuration object. |
2042 | 664 | webservice_configuration = WebServiceTestConfiguration() | 660 | webservice_configuration = WebServiceTestConfiguration() |
2043 | 665 | sm = getGlobalSiteManager() | 661 | sm = getGlobalSiteManager() |
2044 | @@ -717,7 +713,7 @@ class WebServiceTestCase(TestCaseWithWebServiceFixtures): | |||
2045 | 717 | 713 | ||
2046 | 718 | def setUp(self): | 714 | def setUp(self): |
2047 | 719 | """Set the component registry with the given model.""" | 715 | """Set the component registry with the given model.""" |
2049 | 720 | super(WebServiceTestCase, self).setUp() | 716 | super().setUp() |
2050 | 721 | 717 | ||
2051 | 722 | # Register a service root resource | 718 | # Register a service root resource |
2052 | 723 | sm = getGlobalSiteManager() | 719 | sm = getGlobalSiteManager() |
2053 | @@ -769,12 +765,12 @@ class IGenericEntry(Interface): | |||
2054 | 769 | # pylint: disable-msg=E0213 | 765 | # pylint: disable-msg=E0213 |
2055 | 770 | a_field = exported( | 766 | a_field = exported( |
2056 | 771 | TextLine( | 767 | TextLine( |
2059 | 772 | title=u'A "field"', | 768 | title='A "field"', |
2060 | 773 | description=u"The only field that can be <> 0 in the entry.", | 769 | description="The only field that can be <> 0 in the entry.", |
2061 | 774 | ) | 770 | ) |
2062 | 775 | ) | 771 | ) |
2063 | 776 | 772 | ||
2065 | 777 | @operation_parameters(message=TextLine(title=u"Message to say")) | 773 | @operation_parameters(message=TextLine(title="Message to say")) |
2066 | 778 | @export_read_operation() | 774 | @export_read_operation() |
2067 | 779 | def greet(message): | 775 | def greet(message): |
2068 | 780 | """Print an appropriate greeting based on the message. | 776 | """Print an appropriate greeting based on the message. |
2069 | @@ -831,4 +827,4 @@ def simple_renderer(value): | |||
2070 | 831 | This is a good HTML field renderer to use in tests, because it | 827 | This is a good HTML field renderer to use in tests, because it |
2071 | 832 | tests Unicode values and embedded HTML. | 828 | tests Unicode values and embedded HTML. |
2072 | 833 | """ | 829 | """ |
2074 | 834 | return u"\N{SNOWMAN} <b>%s</b>" % value | 830 | return "\N{SNOWMAN} <b>%s</b>" % value |
2075 | diff --git a/src/lazr/restful/tests/test_declarations.py b/src/lazr/restful/tests/test_declarations.py | |||
2076 | index f1c688c..305709b 100644 | |||
2077 | --- a/src/lazr/restful/tests/test_declarations.py | |||
2078 | +++ b/src/lazr/restful/tests/test_declarations.py | |||
2079 | @@ -2,8 +2,6 @@ | |||
2080 | 2 | 2 | ||
2081 | 3 | """Unit tests for the conversion of interfaces into a web service.""" | 3 | """Unit tests for the conversion of interfaces into a web service.""" |
2082 | 4 | 4 | ||
2083 | 5 | from __future__ import absolute_import, print_function | ||
2084 | 6 | |||
2085 | 7 | import sys | 5 | import sys |
2086 | 8 | 6 | ||
2087 | 9 | import testtools | 7 | import testtools |
2088 | @@ -85,7 +83,7 @@ class ContributingInterfacesTestCase(TestCaseWithWebServiceFixtures): | |||
2089 | 85 | """Tests for interfaces that contribute fields/operations to others.""" | 83 | """Tests for interfaces that contribute fields/operations to others.""" |
2090 | 86 | 84 | ||
2091 | 87 | def setUp(self): | 85 | def setUp(self): |
2093 | 88 | super(ContributingInterfacesTestCase, self).setUp() | 86 | super().setUp() |
2094 | 89 | sm = getSiteManager() | 87 | sm = getSiteManager() |
2095 | 90 | sm.registerAdapter(ProductToHasBugsAdapter) | 88 | sm.registerAdapter(ProductToHasBugsAdapter) |
2096 | 91 | sm.registerAdapter(ProjectToHasBugsAdapter) | 89 | sm.registerAdapter(ProjectToHasBugsAdapter) |
2097 | @@ -152,7 +150,7 @@ class ContributingInterfacesTestCase(TestCaseWithWebServiceFixtures): | |||
2098 | 152 | @exported_as_webservice_entry(contributes_to=[IProduct]) | 150 | @exported_as_webservice_entry(contributes_to=[IProduct]) |
2099 | 153 | class IHasTooManyAccessors(Interface): | 151 | class IHasTooManyAccessors(Interface): |
2100 | 154 | needs_an_accessor = exported( | 152 | needs_an_accessor = exported( |
2102 | 155 | TextLine(title=u"This needs an accessor", readonly=True) | 153 | TextLine(title="This needs an accessor", readonly=True) |
2103 | 156 | ) | 154 | ) |
2104 | 157 | 155 | ||
2105 | 158 | @accessor_for(needs_an_accessor) | 156 | @accessor_for(needs_an_accessor) |
2106 | @@ -353,7 +351,7 @@ class ContributingInterfacesTestCase(TestCaseWithWebServiceFixtures): | |||
2107 | 353 | 351 | ||
2108 | 354 | @exported_as_webservice_entry(contributes_to=[INotExported]) | 352 | @exported_as_webservice_entry(contributes_to=[INotExported]) |
2109 | 355 | class IContributor(Interface): | 353 | class IContributor(Interface): |
2111 | 356 | title = exported(TextLine(title=u"The project title")) | 354 | title = exported(TextLine(title="The project title")) |
2112 | 357 | 355 | ||
2113 | 358 | self.assertRaises( | 356 | self.assertRaises( |
2114 | 359 | AttemptToContributeToNonExportedInterface, | 357 | AttemptToContributeToNonExportedInterface, |
2115 | @@ -436,7 +434,7 @@ class TestExportAsWebserviceEntry(testtools.TestCase): | |||
2116 | 436 | """Tests for export_as_webservice_entry.""" | 434 | """Tests for export_as_webservice_entry.""" |
2117 | 437 | 435 | ||
2118 | 438 | def setUp(self): | 436 | def setUp(self): |
2120 | 439 | super(TestExportAsWebserviceEntry, self).setUp() | 437 | super().setUp() |
2121 | 440 | if sys.version_info[0] >= 3: | 438 | if sys.version_info[0] >= 3: |
2122 | 441 | self.skipTest( | 439 | self.skipTest( |
2123 | 442 | "export_as_webservice_entry is only supported on Python 2" | 440 | "export_as_webservice_entry is only supported on Python 2" |
2124 | @@ -454,7 +452,7 @@ class TestExportAsWebserviceEntry(testtools.TestCase): | |||
2125 | 454 | def test_requires_interface(self): | 452 | def test_requires_interface(self): |
2126 | 455 | # export_as_webservice_entry can only be used on Interface. | 453 | # export_as_webservice_entry can only be used on Interface. |
2127 | 456 | def export_non_interface(): | 454 | def export_non_interface(): |
2129 | 457 | class NotAnInterface(object): | 455 | class NotAnInterface: |
2130 | 458 | export_as_webservice_entry() | 456 | export_as_webservice_entry() |
2131 | 459 | 457 | ||
2132 | 460 | exception = self.assertRaises(TypeError, export_non_interface) | 458 | exception = self.assertRaises(TypeError, export_non_interface) |
2133 | @@ -478,7 +476,7 @@ class TestExportAsWebserviceCollection(testtools.TestCase): | |||
2134 | 478 | """Tests for export_as_webservice_collection.""" | 476 | """Tests for export_as_webservice_collection.""" |
2135 | 479 | 477 | ||
2136 | 480 | def setUp(self): | 478 | def setUp(self): |
2138 | 481 | super(TestExportAsWebserviceCollection, self).setUp() | 479 | super().setUp() |
2139 | 482 | if sys.version_info[0] >= 3: | 480 | if sys.version_info[0] >= 3: |
2140 | 483 | self.skipTest( | 481 | self.skipTest( |
2141 | 484 | "export_as_webservice_collection is only supported on " | 482 | "export_as_webservice_collection is only supported on " |
2142 | @@ -568,7 +566,7 @@ class TestExportAsWebserviceCollection(testtools.TestCase): | |||
2143 | 568 | def test_requires_interface(self): | 566 | def test_requires_interface(self): |
2144 | 569 | # export_as_webservice_collection can only be used on Interface. | 567 | # export_as_webservice_collection can only be used on Interface. |
2145 | 570 | def export_non_interface(): | 568 | def export_non_interface(): |
2147 | 571 | class NotAnInterface(object): | 569 | class NotAnInterface: |
2148 | 572 | export_as_webservice_collection(Interface) | 570 | export_as_webservice_collection(Interface) |
2149 | 573 | 571 | ||
2150 | 574 | exception = self.assertRaises(TypeError, export_non_interface) | 572 | exception = self.assertRaises(TypeError, export_non_interface) |
2151 | @@ -626,21 +624,21 @@ class TestFindExportedInterfaces(testtools.TestCase): | |||
2152 | 626 | ) | 624 | ) |
2153 | 627 | 625 | ||
2154 | 628 | def test_finds_exported_exceptions(self): | 626 | def test_finds_exported_exceptions(self): |
2156 | 629 | class Module(object): | 627 | class Module: |
2157 | 630 | NotExportedException_copy = NotExportedException | 628 | NotExportedException_copy = NotExportedException |
2158 | 631 | ExportedExceptionOne_copy = ExportedExceptionOne | 629 | ExportedExceptionOne_copy = ExportedExceptionOne |
2159 | 632 | 630 | ||
2160 | 633 | self.assertExportsNames(Module, ["ExportedExceptionOne"]) | 631 | self.assertExportsNames(Module, ["ExportedExceptionOne"]) |
2161 | 634 | 632 | ||
2162 | 635 | def test_finds_exported_interfaces(self): | 633 | def test_finds_exported_interfaces(self): |
2164 | 636 | class Module(object): | 634 | class Module: |
2165 | 637 | INotExported_copy = INotExported | 635 | INotExported_copy = INotExported |
2166 | 638 | IExported_copy = IExported | 636 | IExported_copy = IExported |
2167 | 639 | 637 | ||
2168 | 640 | self.assertExportsNames(Module, ["IExported"]) | 638 | self.assertExportsNames(Module, ["IExported"]) |
2169 | 641 | 639 | ||
2170 | 642 | def test_honours_all(self): | 640 | def test_honours_all(self): |
2172 | 643 | class Module(object): | 641 | class Module: |
2173 | 644 | __all__ = ["ExportedExceptionOne_copy"] | 642 | __all__ = ["ExportedExceptionOne_copy"] |
2174 | 645 | ExportedExceptionOne_copy = ExportedExceptionOne | 643 | ExportedExceptionOne_copy = ExportedExceptionOne |
2175 | 646 | ExportedExceptionTwo_copy = ExportedExceptionTwo | 644 | ExportedExceptionTwo_copy = ExportedExceptionTwo |
2176 | @@ -648,7 +646,7 @@ class TestFindExportedInterfaces(testtools.TestCase): | |||
2177 | 648 | self.assertExportsNames(Module, ["ExportedExceptionOne"]) | 646 | self.assertExportsNames(Module, ["ExportedExceptionOne"]) |
2178 | 649 | 647 | ||
2179 | 650 | def test_skips_leading_underscore_without_all(self): | 648 | def test_skips_leading_underscore_without_all(self): |
2181 | 651 | class Module(object): | 649 | class Module: |
2182 | 652 | ExportedExceptionOne_copy = ExportedExceptionOne | 650 | ExportedExceptionOne_copy = ExportedExceptionOne |
2183 | 653 | _ExportedExceptionTwo_copy = ExportedExceptionTwo | 651 | _ExportedExceptionTwo_copy = ExportedExceptionTwo |
2184 | 654 | 652 | ||
2185 | @@ -657,7 +655,7 @@ class TestFindExportedInterfaces(testtools.TestCase): | |||
2186 | 657 | 655 | ||
2187 | 658 | @exported_as_webservice_entry() | 656 | @exported_as_webservice_entry() |
2188 | 659 | class IProduct(Interface): | 657 | class IProduct(Interface): |
2190 | 660 | title = exported(TextLine(title=u"The product title")) | 658 | title = exported(TextLine(title="The product title")) |
2191 | 661 | # Need to define the three attributes below because we have a test which | 659 | # Need to define the three attributes below because we have a test which |
2192 | 662 | # wraps a Product object with a security proxy and later uses adapters | 660 | # wraps a Product object with a security proxy and later uses adapters |
2193 | 663 | # that access _dev_branch, _branches and _bug_count. | 661 | # that access _dev_branch, _branches and _bug_count. |
2194 | @@ -668,7 +666,7 @@ class IProduct(Interface): | |||
2195 | 668 | 666 | ||
2196 | 669 | 667 | ||
2197 | 670 | @implementer(IProduct) | 668 | @implementer(IProduct) |
2199 | 671 | class Product(object): | 669 | class Product: |
2200 | 672 | title = "A product" | 670 | title = "A product" |
2201 | 673 | _bug_count = 0 | 671 | _bug_count = 0 |
2202 | 674 | _dev_branch = None | 672 | _dev_branch = None |
2203 | @@ -678,21 +676,21 @@ class Product(object): | |||
2204 | 678 | 676 | ||
2205 | 679 | @exported_as_webservice_entry() | 677 | @exported_as_webservice_entry() |
2206 | 680 | class IProject(Interface): | 678 | class IProject(Interface): |
2208 | 681 | title = exported(TextLine(title=u"The project title")) | 679 | title = exported(TextLine(title="The project title")) |
2209 | 682 | 680 | ||
2210 | 683 | 681 | ||
2211 | 684 | @implementer(IProject) | 682 | @implementer(IProject) |
2213 | 685 | class Project(object): | 683 | class Project: |
2214 | 686 | title = "A project" | 684 | title = "A project" |
2215 | 687 | _bug_count = 0 | 685 | _bug_count = 0 |
2216 | 688 | 686 | ||
2217 | 689 | 687 | ||
2218 | 690 | @exported_as_webservice_entry(contributes_to=[IProduct, IProject]) | 688 | @exported_as_webservice_entry(contributes_to=[IProduct, IProject]) |
2219 | 691 | class IHasBugs(Interface): | 689 | class IHasBugs(Interface): |
2222 | 692 | bug_count = exported(Int(title=u"Number of bugs")) | 690 | bug_count = exported(Int(title="Number of bugs")) |
2223 | 693 | not_exported = TextLine(title=u"Not exported") | 691 | not_exported = TextLine(title="Not exported") |
2224 | 694 | bug_target_name = exported( | 692 | bug_target_name = exported( |
2226 | 695 | TextLine(title=u"The bug target name of this object.", readonly=True) | 693 | TextLine(title="The bug target name of this object.", readonly=True) |
2227 | 696 | ) | 694 | ) |
2228 | 697 | 695 | ||
2229 | 698 | @export_read_operation() | 696 | @export_read_operation() |
2230 | @@ -726,13 +724,13 @@ class IHasBugs(Interface): | |||
2231 | 726 | 724 | ||
2232 | 727 | @exported_as_webservice_entry(contributes_to=[IProduct]) | 725 | @exported_as_webservice_entry(contributes_to=[IProduct]) |
2233 | 728 | class IHasBugs2(Interface): | 726 | class IHasBugs2(Interface): |
2236 | 729 | bug_count = exported(Int(title=u"Number of bugs")) | 727 | bug_count = exported(Int(title="Number of bugs")) |
2237 | 730 | not_exported = TextLine(title=u"Not exported") | 728 | not_exported = TextLine(title="Not exported") |
2238 | 731 | 729 | ||
2239 | 732 | 730 | ||
2240 | 733 | @exported_as_webservice_entry(contributes_to=[IProduct]) | 731 | @exported_as_webservice_entry(contributes_to=[IProduct]) |
2241 | 734 | class IHasBugs3(Interface): | 732 | class IHasBugs3(Interface): |
2243 | 735 | not_exported = TextLine(title=u"Not exported") | 733 | not_exported = TextLine(title="Not exported") |
2244 | 736 | 734 | ||
2245 | 737 | @export_read_operation() | 735 | @export_read_operation() |
2246 | 738 | def getBugsCount(): | 736 | def getBugsCount(): |
2247 | @@ -741,7 +739,7 @@ class IHasBugs3(Interface): | |||
2248 | 741 | 739 | ||
2249 | 742 | @adapter(IProduct) | 740 | @adapter(IProduct) |
2250 | 743 | @implementer(IHasBugs) | 741 | @implementer(IHasBugs) |
2252 | 744 | class ProductToHasBugsAdapter(object): | 742 | class ProductToHasBugsAdapter: |
2253 | 745 | def __init__(self, context): | 743 | def __init__(self, context): |
2254 | 746 | self.context = context | 744 | self.context = context |
2255 | 747 | self.bug_count = context._bug_count | 745 | self.bug_count = context._bug_count |
2256 | @@ -766,18 +764,18 @@ class ProjectToHasBugsAdapter(ProductToHasBugsAdapter): | |||
2257 | 766 | 764 | ||
2258 | 767 | @exported_as_webservice_entry() | 765 | @exported_as_webservice_entry() |
2259 | 768 | class IBranch(Interface): | 766 | class IBranch(Interface): |
2261 | 769 | name = TextLine(title=u"The branch name") | 767 | name = TextLine(title="The branch name") |
2262 | 770 | 768 | ||
2263 | 771 | 769 | ||
2264 | 772 | @implementer(IBranch) | 770 | @implementer(IBranch) |
2266 | 773 | class Branch(object): | 771 | class Branch: |
2267 | 774 | def __init__(self, name): | 772 | def __init__(self, name): |
2268 | 775 | self.name = name | 773 | self.name = name |
2269 | 776 | 774 | ||
2270 | 777 | 775 | ||
2271 | 778 | @exported_as_webservice_entry(contributes_to=[IProduct]) | 776 | @exported_as_webservice_entry(contributes_to=[IProduct]) |
2272 | 779 | class IHasBranches(Interface): | 777 | class IHasBranches(Interface): |
2274 | 780 | not_exported = TextLine(title=u"Not exported") | 778 | not_exported = TextLine(title="Not exported") |
2275 | 781 | development_branch = exported( | 779 | development_branch = exported( |
2276 | 782 | Reference(schema=IBranch, readonly=True), | 780 | Reference(schema=IBranch, readonly=True), |
2277 | 783 | ("2.0", dict(exported_as="development_branch_20")), | 781 | ("2.0", dict(exported_as="development_branch_20")), |
2278 | @@ -804,7 +802,7 @@ class IHasBranches(Interface): | |||
2279 | 804 | 802 | ||
2280 | 805 | @adapter(IProduct) | 803 | @adapter(IProduct) |
2281 | 806 | @implementer(IHasBranches) | 804 | @implementer(IHasBranches) |
2283 | 807 | class ProductToHasBranchesAdapter(object): | 805 | class ProductToHasBranchesAdapter: |
2284 | 808 | def __init__(self, context): | 806 | def __init__(self, context): |
2285 | 809 | self.context = context | 807 | self.context = context |
2286 | 810 | 808 | ||
2287 | @@ -876,7 +874,7 @@ class TestEntryMultiversion(TestCaseWithWebServiceFixtures): | |||
2288 | 876 | interfaces = generate_entry_interfaces( | 874 | interfaces = generate_entry_interfaces( |
2289 | 877 | INotInitiallyExported, | 875 | INotInitiallyExported, |
2290 | 878 | [], | 876 | [], |
2292 | 879 | *getUtility(IWebServiceConfiguration).active_versions | 877 | *getUtility(IWebServiceConfiguration).active_versions, |
2293 | 880 | ) | 878 | ) |
2294 | 881 | self.assertEqual(len(interfaces), 1) | 879 | self.assertEqual(len(interfaces), 1) |
2295 | 882 | self.assertEqual(interfaces[0].version, "2.0") | 880 | self.assertEqual(interfaces[0].version, "2.0") |
2296 | @@ -887,7 +885,7 @@ class TestEntryMultiversion(TestCaseWithWebServiceFixtures): | |||
2297 | 887 | interfaces = generate_entry_interfaces( | 885 | interfaces = generate_entry_interfaces( |
2298 | 888 | INotPresentInLaterVersion, | 886 | INotPresentInLaterVersion, |
2299 | 889 | [], | 887 | [], |
2301 | 890 | *getUtility(IWebServiceConfiguration).active_versions | 888 | *getUtility(IWebServiceConfiguration).active_versions, |
2302 | 891 | ) | 889 | ) |
2303 | 892 | self.assertEqual(len(interfaces), 1) | 890 | self.assertEqual(len(interfaces), 1) |
2304 | 893 | self.assertEqual(interfaces[0].version, "1.0") | 891 | self.assertEqual(interfaces[0].version, "1.0") |
2305 | @@ -898,7 +896,7 @@ class TestEntryMultiversion(TestCaseWithWebServiceFixtures): | |||
2306 | 898 | interfaces = generate_entry_interfaces( | 896 | interfaces = generate_entry_interfaces( |
2307 | 899 | IHasDifferentNamesInDifferentVersions, | 897 | IHasDifferentNamesInDifferentVersions, |
2308 | 900 | [], | 898 | [], |
2310 | 901 | *getUtility(IWebServiceConfiguration).active_versions | 899 | *getUtility(IWebServiceConfiguration).active_versions, |
2311 | 902 | ) | 900 | ) |
2312 | 903 | interface_10 = interfaces[0].object | 901 | interface_10 = interfaces[0].object |
2313 | 904 | tags_10 = interface_10.getTaggedValue(LAZR_WEBSERVICE_NAME) | 902 | tags_10 = interface_10.getTaggedValue(LAZR_WEBSERVICE_NAME) |
2314 | @@ -936,7 +934,7 @@ class TestEntryMultiversion(TestCaseWithWebServiceFixtures): | |||
2315 | 936 | interfaces = generate_entry_interfaces( | 934 | interfaces = generate_entry_interfaces( |
2316 | 937 | IHasDifferentSingularNamesInDifferentVersions, | 935 | IHasDifferentSingularNamesInDifferentVersions, |
2317 | 938 | [], | 936 | [], |
2319 | 939 | *getUtility(IWebServiceConfiguration).active_versions | 937 | *getUtility(IWebServiceConfiguration).active_versions, |
2320 | 940 | ) | 938 | ) |
2321 | 941 | interface_10 = interfaces[0].object | 939 | interface_10 = interfaces[0].object |
2322 | 942 | tags_10 = interface_10.getTaggedValue(LAZR_WEBSERVICE_NAME) | 940 | tags_10 = interface_10.getTaggedValue(LAZR_WEBSERVICE_NAME) |
2323 | @@ -1024,7 +1022,7 @@ class IFieldExplicitOperationDefinition(Interface): | |||
2324 | 1024 | 1022 | ||
2325 | 1025 | 1023 | ||
2326 | 1026 | @implementer(IFieldExplicitOperationDefinition) | 1024 | @implementer(IFieldExplicitOperationDefinition) |
2328 | 1027 | class FieldExplicitOperationDefinition(object): | 1025 | class FieldExplicitOperationDefinition: |
2329 | 1028 | pass | 1026 | pass |
2330 | 1029 | 1027 | ||
2331 | 1030 | 1028 | ||
2332 | @@ -1032,7 +1030,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2333 | 1032 | """Test behavior when require_explicit_versions is True.""" | 1030 | """Test behavior when require_explicit_versions is True.""" |
2334 | 1033 | 1031 | ||
2335 | 1034 | def setUp(self): | 1032 | def setUp(self): |
2337 | 1035 | super(TestRequireExplicitVersions, self).setUp() | 1033 | super().setUp() |
2338 | 1036 | self.utility = getUtility(IWebServiceConfiguration) | 1034 | self.utility = getUtility(IWebServiceConfiguration) |
2339 | 1037 | self.utility.require_explicit_versions = True | 1035 | self.utility.require_explicit_versions = True |
2340 | 1038 | 1036 | ||
2341 | @@ -1061,7 +1059,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2342 | 1061 | generate_entry_interfaces, | 1059 | generate_entry_interfaces, |
2343 | 1062 | IEntryExportedWithoutAsOf, | 1060 | IEntryExportedWithoutAsOf, |
2344 | 1063 | [], | 1061 | [], |
2346 | 1064 | *self.utility.active_versions | 1062 | *self.utility.active_versions, |
2347 | 1065 | ) | 1063 | ) |
2348 | 1066 | self.assertEqual( | 1064 | self.assertEqual( |
2349 | 1067 | str(exception), | 1065 | str(exception), |
2350 | @@ -1078,7 +1076,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2351 | 1078 | interfaces = generate_entry_interfaces( | 1076 | interfaces = generate_entry_interfaces( |
2352 | 1079 | IFieldExportedToEarliestVersionUsingAsOf, | 1077 | IFieldExportedToEarliestVersionUsingAsOf, |
2353 | 1080 | [], | 1078 | [], |
2355 | 1081 | *self.utility.active_versions | 1079 | *self.utility.active_versions, |
2356 | 1082 | ) | 1080 | ) |
2357 | 1083 | interface_10 = interfaces[0].object | 1081 | interface_10 = interfaces[0].object |
2358 | 1084 | interface_20 = interfaces[1].object | 1082 | interface_20 = interfaces[1].object |
2359 | @@ -1093,7 +1091,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2360 | 1093 | interfaces = generate_entry_interfaces( | 1091 | interfaces = generate_entry_interfaces( |
2361 | 1094 | IFieldExportedToLatestVersionUsingAsOf, | 1092 | IFieldExportedToLatestVersionUsingAsOf, |
2362 | 1095 | [], | 1093 | [], |
2364 | 1096 | *self.utility.active_versions | 1094 | *self.utility.active_versions, |
2365 | 1097 | ) | 1095 | ) |
2366 | 1098 | interface_10 = interfaces[0].object | 1096 | interface_10 = interfaces[0].object |
2367 | 1099 | interface_20 = interfaces[1].object | 1097 | interface_20 = interfaces[1].object |
2368 | @@ -1108,7 +1106,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2369 | 1108 | generate_entry_interfaces, | 1106 | generate_entry_interfaces, |
2370 | 1109 | IFieldExportedWithoutAsOf, | 1107 | IFieldExportedWithoutAsOf, |
2371 | 1110 | [], | 1108 | [], |
2373 | 1111 | *self.utility.active_versions | 1109 | *self.utility.active_versions, |
2374 | 1112 | ) | 1110 | ) |
2375 | 1113 | self.assertEqual( | 1111 | self.assertEqual( |
2376 | 1114 | str(exception), | 1112 | str(exception), |
2377 | @@ -1140,7 +1138,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2378 | 1140 | generate_entry_interfaces, | 1138 | generate_entry_interfaces, |
2379 | 1141 | IFieldAsOfNonexistentVersion, | 1139 | IFieldAsOfNonexistentVersion, |
2380 | 1142 | [], | 1140 | [], |
2382 | 1143 | *self.utility.active_versions | 1141 | *self.utility.active_versions, |
2383 | 1144 | ) | 1142 | ) |
2384 | 1145 | self.assertEqual( | 1143 | self.assertEqual( |
2385 | 1146 | str(exception), | 1144 | str(exception), |
2386 | @@ -1158,7 +1156,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2387 | 1158 | generate_entry_interfaces, | 1156 | generate_entry_interfaces, |
2388 | 1159 | IFieldDoubleDefinition, | 1157 | IFieldDoubleDefinition, |
2389 | 1160 | [], | 1158 | [], |
2391 | 1161 | *self.utility.active_versions | 1159 | *self.utility.active_versions, |
2392 | 1162 | ) | 1160 | ) |
2393 | 1163 | self.assertEqual( | 1161 | self.assertEqual( |
2394 | 1164 | str(exception), | 1162 | str(exception), |
2395 | @@ -1176,7 +1174,7 @@ class TestRequireExplicitVersions(TestCaseWithWebServiceFixtures): | |||
2396 | 1176 | generate_entry_interfaces, | 1174 | generate_entry_interfaces, |
2397 | 1177 | IFieldDefiningAttributesBeforeAsOf, | 1175 | IFieldDefiningAttributesBeforeAsOf, |
2398 | 1178 | [], | 1176 | [], |
2400 | 1179 | *self.utility.active_versions | 1177 | *self.utility.active_versions, |
2401 | 1180 | ) | 1178 | ) |
2402 | 1181 | self.assertEqual( | 1179 | self.assertEqual( |
2403 | 1182 | str(exception), | 1180 | str(exception), |
2404 | @@ -1370,7 +1368,7 @@ class TestCoherenceChecking(TestCaseWithWebServiceFixtures): | |||
2405 | 1370 | ValueError, | 1368 | ValueError, |
2406 | 1371 | register_test_module, | 1369 | register_test_module, |
2407 | 1372 | "testmod", | 1370 | "testmod", |
2409 | 1373 | *(list(classes) + [expect_failure_due_to_interface]) | 1371 | *(list(classes) + [expect_failure_due_to_interface]), |
2410 | 1374 | ) | 1372 | ) |
2411 | 1375 | expected_message = ( | 1373 | expected_message = ( |
2412 | 1376 | "In version %(version)s, %(reason)s, but version %(version)s " | 1374 | "In version %(version)s, %(reason)s, but version %(version)s " |
2413 | diff --git a/src/lazr/restful/tests/test_docs.py b/src/lazr/restful/tests/test_docs.py | |||
2414 | index a503ae6..26f9645 100644 | |||
2415 | --- a/src/lazr/restful/tests/test_docs.py | |||
2416 | +++ b/src/lazr/restful/tests/test_docs.py | |||
2417 | @@ -17,9 +17,6 @@ | |||
2418 | 17 | 17 | ||
2419 | 18 | # pylint: disable=E0611,W0142 | 18 | # pylint: disable=E0611,W0142 |
2420 | 19 | 19 | ||
2421 | 20 | from __future__ import absolute_import, print_function | ||
2422 | 21 | |||
2423 | 22 | __metaclass__ = type | ||
2424 | 23 | __all__ = [] | 20 | __all__ = [] |
2425 | 24 | 21 | ||
2426 | 25 | import atexit | 22 | import atexit |
2427 | @@ -66,19 +63,14 @@ def load_tests(loader, tests, pattern): | |||
2428 | 66 | ) | 63 | ) |
2429 | 67 | ) | 64 | ) |
2430 | 68 | atexit.register(cleanup_resources) | 65 | atexit.register(cleanup_resources) |
2431 | 69 | globs = { | ||
2432 | 70 | "absolute_import": absolute_import, | ||
2433 | 71 | "print_function": print_function, | ||
2434 | 72 | } | ||
2435 | 73 | tests.addTest( | 66 | tests.addTest( |
2436 | 74 | doctest.DocFileSuite( | 67 | doctest.DocFileSuite( |
2437 | 75 | *doctest_files, | 68 | *doctest_files, |
2438 | 76 | module_relative=False, | 69 | module_relative=False, |
2439 | 77 | optionflags=DOCTEST_FLAGS, | 70 | optionflags=DOCTEST_FLAGS, |
2440 | 78 | tearDown=tearDown, | 71 | tearDown=tearDown, |
2441 | 79 | globs=globs, | ||
2442 | 80 | encoding="UTF-8", | 72 | encoding="UTF-8", |
2444 | 81 | checker=checker | 73 | checker=checker, |
2445 | 82 | ) | 74 | ) |
2446 | 83 | ) | 75 | ) |
2447 | 84 | return tests | 76 | return tests |
2448 | diff --git a/src/lazr/restful/tests/test_error.py b/src/lazr/restful/tests/test_error.py | |||
2449 | index d407ccb..69adf07 100644 | |||
2450 | --- a/src/lazr/restful/tests/test_error.py | |||
2451 | +++ b/src/lazr/restful/tests/test_error.py | |||
2452 | @@ -2,10 +2,6 @@ | |||
2453 | 2 | 2 | ||
2454 | 3 | """Tests of lazr.restful navigation.""" | 3 | """Tests of lazr.restful navigation.""" |
2455 | 4 | 4 | ||
2456 | 5 | from __future__ import absolute_import, print_function | ||
2457 | 6 | |||
2458 | 7 | __metaclass__ = type | ||
2459 | 8 | |||
2460 | 9 | from pkg_resources import resource_filename | 5 | from pkg_resources import resource_filename |
2461 | 10 | import os | 6 | import os |
2462 | 11 | import traceback | 7 | import traceback |
2463 | @@ -30,7 +26,7 @@ from lazr.restful.testing.webservice import FakeRequest | |||
2464 | 30 | class TestResource(ReadWriteResource): | 26 | class TestResource(ReadWriteResource): |
2465 | 31 | def __init__(self, callable, request): | 27 | def __init__(self, callable, request): |
2466 | 32 | self.callable = callable | 28 | self.callable = callable |
2468 | 33 | super(TestResource, self).__init__(context=None, request=request) | 29 | super().__init__(context=None, request=request) |
2469 | 34 | 30 | ||
2470 | 35 | def do_GET(self): | 31 | def do_GET(self): |
2471 | 36 | return self.callable() | 32 | return self.callable() |
2472 | @@ -57,7 +53,7 @@ class ErrorsTestCase(unittest.TestCase): | |||
2473 | 57 | pass | 53 | pass |
2474 | 58 | 54 | ||
2475 | 59 | self.exception_class = MyException | 55 | self.exception_class = MyException |
2477 | 60 | super(ErrorsTestCase, self).setUp() | 56 | super().setUp() |
2478 | 61 | 57 | ||
2479 | 62 | def test_decorated_exception_class_becomes_error_view(self): | 58 | def test_decorated_exception_class_becomes_error_view(self): |
2480 | 63 | # An exposed exception, when raised, will set the response | 59 | # An exposed exception, when raised, will set the response |
2481 | @@ -140,7 +136,7 @@ class ErrorsTestCase(unittest.TestCase): | |||
2482 | 140 | # Register a view for the exception that does not subclass | 136 | # Register a view for the exception that does not subclass |
2483 | 141 | # WebServiceExceptionView and provides no information about | 137 | # WebServiceExceptionView and provides no information about |
2484 | 142 | # which HTTP status code should be used. | 138 | # which HTTP status code should be used. |
2486 | 143 | class ViewHasNoStatus(object): | 139 | class ViewHasNoStatus: |
2487 | 144 | def __init__(*args): | 140 | def __init__(*args): |
2488 | 145 | pass | 141 | pass |
2489 | 146 | 142 | ||
2490 | diff --git a/src/lazr/restful/tests/test_etag.py b/src/lazr/restful/tests/test_etag.py | |||
2491 | index ed9a950..e9421a0 100644 | |||
2492 | --- a/src/lazr/restful/tests/test_etag.py | |||
2493 | +++ b/src/lazr/restful/tests/test_etag.py | |||
2494 | @@ -1,10 +1,6 @@ | |||
2495 | 1 | # Copyright 2008 Canonical Ltd. All rights reserved. | 1 | # Copyright 2008 Canonical Ltd. All rights reserved. |
2496 | 2 | """Tests for ETag generation.""" | 2 | """Tests for ETag generation.""" |
2497 | 3 | 3 | ||
2498 | 4 | from __future__ import absolute_import, print_function | ||
2499 | 5 | |||
2500 | 6 | __metaclass__ = type | ||
2501 | 7 | |||
2502 | 8 | from collections import OrderedDict | 4 | from collections import OrderedDict |
2503 | 9 | from datetime import ( | 5 | from datetime import ( |
2504 | 10 | date, | 6 | date, |
2505 | @@ -178,11 +174,11 @@ class EntryFieldResourceTests(unittest.TestCase): | |||
2506 | 178 | self.set_field_value("this is the field value") | 174 | self.set_field_value("this is the field value") |
2507 | 179 | 175 | ||
2508 | 180 | # Find the cores generated with a given revision... | 176 | # Find the cores generated with a given revision... |
2510 | 181 | self.config.code_revision = u"42" | 177 | self.config.code_revision = "42" |
2511 | 182 | first_cores = self.resource._getETagCores(self.resource.JSON_TYPE) | 178 | first_cores = self.resource._getETagCores(self.resource.JSON_TYPE) |
2512 | 183 | 179 | ||
2513 | 184 | # ...find the cores generated with a different revision. | 180 | # ...find the cores generated with a different revision. |
2515 | 185 | self.config.code_revision = u"99" | 181 | self.config.code_revision = "99" |
2516 | 186 | second_cores = self.resource._getETagCores(self.resource.JSON_TYPE) | 182 | second_cores = self.resource._getETagCores(self.resource.JSON_TYPE) |
2517 | 187 | 183 | ||
2518 | 188 | # The cores should be different. | 184 | # The cores should be different. |
2519 | @@ -223,11 +219,11 @@ class ServiceRootResourceTests(unittest.TestCase): | |||
2520 | 223 | # web service change. | 219 | # web service change. |
2521 | 224 | 220 | ||
2522 | 225 | # Find the cores generated with a given revision... | 221 | # Find the cores generated with a given revision... |
2524 | 226 | self.config.code_revision = u"42" | 222 | self.config.code_revision = "42" |
2525 | 227 | first_cores = self.resource._getETagCores(self.resource.JSON_TYPE) | 223 | first_cores = self.resource._getETagCores(self.resource.JSON_TYPE) |
2526 | 228 | 224 | ||
2527 | 229 | # ...find the cores generated with a different revision. | 225 | # ...find the cores generated with a different revision. |
2529 | 230 | self.config.code_revision = u"99" | 226 | self.config.code_revision = "99" |
2530 | 231 | second_cores = self.resource._getETagCores(self.resource.JSON_TYPE) | 227 | second_cores = self.resource._getETagCores(self.resource.JSON_TYPE) |
2531 | 232 | 228 | ||
2532 | 233 | # The cores should be different. | 229 | # The cores should be different. |
2533 | @@ -240,12 +236,12 @@ class ServiceRootResourceTests(unittest.TestCase): | |||
2534 | 240 | # information.) | 236 | # information.) |
2535 | 241 | 237 | ||
2536 | 242 | # Find the ETag generated with a given revision... | 238 | # Find the ETag generated with a given revision... |
2538 | 243 | self.config.code_revision = u"42" | 239 | self.config.code_revision = "42" |
2539 | 244 | first_etag = self.resource.getETag(self.resource.WADL_TYPE) | 240 | first_etag = self.resource.getETag(self.resource.WADL_TYPE) |
2540 | 245 | 241 | ||
2541 | 246 | # ...and find the ETag generated with a different revision. | 242 | # ...and find the ETag generated with a different revision. |
2542 | 247 | self.resource.etags_by_media_type = {} | 243 | self.resource.etags_by_media_type = {} |
2544 | 248 | self.config.code_revision = u"99" | 244 | self.config.code_revision = "99" |
2545 | 249 | second_etag = self.resource.getETag(self.resource.WADL_TYPE) | 245 | second_etag = self.resource.getETag(self.resource.WADL_TYPE) |
2546 | 250 | 246 | ||
2547 | 251 | # The ETags should be different. | 247 | # The ETags should be different. |
2548 | diff --git a/src/lazr/restful/tests/test_navigation.py b/src/lazr/restful/tests/test_navigation.py | |||
2549 | index 568205e..ec5cc6d 100644 | |||
2550 | --- a/src/lazr/restful/tests/test_navigation.py | |||
2551 | +++ b/src/lazr/restful/tests/test_navigation.py | |||
2552 | @@ -2,10 +2,6 @@ | |||
2553 | 2 | 2 | ||
2554 | 3 | """Tests of lazr.restful navigation.""" | 3 | """Tests of lazr.restful navigation.""" |
2555 | 4 | 4 | ||
2556 | 5 | from __future__ import absolute_import, print_function | ||
2557 | 6 | |||
2558 | 7 | __metaclass__ = type | ||
2559 | 8 | |||
2560 | 9 | import unittest | 5 | import unittest |
2561 | 10 | 6 | ||
2562 | 11 | from zope.component import ( | 7 | from zope.component import ( |
2563 | @@ -34,14 +30,14 @@ from lazr.restful.testing.webservice import FakeRequest | |||
2564 | 34 | class IChild(Interface): | 30 | class IChild(Interface): |
2565 | 35 | """Interface for a simple entry.""" | 31 | """Interface for a simple entry.""" |
2566 | 36 | 32 | ||
2569 | 37 | one = Text(title=u"One") | 33 | one = Text(title="One") |
2570 | 38 | two = Text(title=u"Two") | 34 | two = Text(title="Two") |
2571 | 39 | 35 | ||
2572 | 40 | 36 | ||
2573 | 41 | class IParent(Interface): | 37 | class IParent(Interface): |
2574 | 42 | """Interface for a simple entry that contains another entry.""" | 38 | """Interface for a simple entry that contains another entry.""" |
2575 | 43 | 39 | ||
2577 | 44 | three = Text(title=u"Three") | 40 | three = Text(title="Three") |
2578 | 45 | child = Reference(schema=IChild) | 41 | child = Reference(schema=IChild) |
2579 | 46 | 42 | ||
2580 | 47 | 43 | ||
2581 | @@ -49,8 +45,8 @@ class IParent(Interface): | |||
2582 | 49 | class Child: | 45 | class Child: |
2583 | 50 | """A simple implementation of IChild.""" | 46 | """A simple implementation of IChild.""" |
2584 | 51 | 47 | ||
2587 | 52 | one = u"one" | 48 | one = "one" |
2588 | 53 | two = u"two" | 49 | two = "two" |
2589 | 54 | 50 | ||
2590 | 55 | 51 | ||
2591 | 56 | class ChildEntry: | 52 | class ChildEntry: |
2592 | @@ -66,7 +62,7 @@ class ChildEntry: | |||
2593 | 66 | class Parent: | 62 | class Parent: |
2594 | 67 | """A simple implementation of IParent.""" | 63 | """A simple implementation of IParent.""" |
2595 | 68 | 64 | ||
2597 | 69 | three = u"three" | 65 | three = "three" |
2598 | 70 | child = Child() | 66 | child = Child() |
2599 | 71 | 67 | ||
2600 | 72 | 68 | ||
2601 | diff --git a/src/lazr/restful/tests/test_utils.py b/src/lazr/restful/tests/test_utils.py | |||
2602 | index d095e02..db180d0 100644 | |||
2603 | --- a/src/lazr/restful/tests/test_utils.py | |||
2604 | +++ b/src/lazr/restful/tests/test_utils.py | |||
2605 | @@ -2,10 +2,6 @@ | |||
2606 | 2 | 2 | ||
2607 | 3 | """Test for lazr.restful.utils.""" | 3 | """Test for lazr.restful.utils.""" |
2608 | 4 | 4 | ||
2609 | 5 | from __future__ import absolute_import, print_function | ||
2610 | 6 | |||
2611 | 7 | __metaclass__ = type | ||
2612 | 8 | |||
2613 | 9 | import random | 5 | import random |
2614 | 10 | import testtools | 6 | import testtools |
2615 | 11 | import unittest | 7 | import unittest |
2616 | @@ -101,7 +97,7 @@ class TestUtils(unittest.TestCase): | |||
2617 | 101 | 97 | ||
2618 | 102 | class TestVersionedDict(testtools.TestCase): | 98 | class TestVersionedDict(testtools.TestCase): |
2619 | 103 | def setUp(self): | 99 | def setUp(self): |
2621 | 104 | super(TestVersionedDict, self).setUp() | 100 | super().setUp() |
2622 | 105 | self.dict = VersionedDict() | 101 | self.dict = VersionedDict() |
2623 | 106 | 102 | ||
2624 | 107 | def test_rename_version_works(self): | 103 | def test_rename_version_works(self): |
2625 | diff --git a/src/lazr/restful/tests/test_webservice.py b/src/lazr/restful/tests/test_webservice.py | |||
2626 | index 4864150..e8c8010 100644 | |||
2627 | --- a/src/lazr/restful/tests/test_webservice.py | |||
2628 | +++ b/src/lazr/restful/tests/test_webservice.py | |||
2629 | @@ -2,10 +2,6 @@ | |||
2630 | 2 | 2 | ||
2631 | 3 | """Test for the WADL generation.""" | 3 | """Test for the WADL generation.""" |
2632 | 4 | 4 | ||
2633 | 5 | from __future__ import absolute_import, print_function | ||
2634 | 6 | |||
2635 | 7 | __metaclass__ = type | ||
2636 | 8 | |||
2637 | 9 | from contextlib import contextmanager | 5 | from contextlib import contextmanager |
2638 | 10 | from io import ( | 6 | from io import ( |
2639 | 11 | BytesIO, | 7 | BytesIO, |
2640 | @@ -19,7 +15,6 @@ import re | |||
2641 | 19 | import simplejson | 15 | import simplejson |
2642 | 20 | import unittest | 16 | import unittest |
2643 | 21 | 17 | ||
2644 | 22 | import six | ||
2645 | 23 | from zope.component import ( | 18 | from zope.component import ( |
2646 | 24 | eventtesting, | 19 | eventtesting, |
2647 | 25 | getGlobalSiteManager, | 20 | getGlobalSiteManager, |
2648 | @@ -256,7 +251,7 @@ class EntryTestCase(WebServiceTestCase): | |||
2649 | 256 | class IHasOneField(Interface): | 251 | class IHasOneField(Interface): |
2650 | 257 | """An entry with a single field.""" | 252 | """An entry with a single field.""" |
2651 | 258 | 253 | ||
2653 | 259 | a_field = exported(TextLine(title=u"A field.")) | 254 | a_field = exported(TextLine(title="A field.")) |
2654 | 260 | 255 | ||
2655 | 261 | 256 | ||
2656 | 262 | @implementer(IHasOneField) | 257 | @implementer(IHasOneField) |
2657 | @@ -271,8 +266,8 @@ class HasOneField: | |||
2658 | 271 | class IHasTwoFields(Interface): | 266 | class IHasTwoFields(Interface): |
2659 | 272 | """An entry with two fields.""" | 267 | """An entry with two fields.""" |
2660 | 273 | 268 | ||
2663 | 274 | a_field = exported(TextLine(title=u"A field.")) | 269 | a_field = exported(TextLine(title="A field.")) |
2664 | 275 | another_field = exported(TextLine(title=u"Another field.")) | 270 | another_field = exported(TextLine(title="Another field.")) |
2665 | 276 | 271 | ||
2666 | 277 | 272 | ||
2667 | 278 | @implementer(IHasTwoFields) | 273 | @implementer(IHasTwoFields) |
2668 | @@ -353,7 +348,7 @@ class TestEntryWebLink(EntryTestCase): | |||
2669 | 353 | class IHasNoWebLink(Interface): | 348 | class IHasNoWebLink(Interface): |
2670 | 354 | """An entry that does not publish a web_link.""" | 349 | """An entry that does not publish a web_link.""" |
2671 | 355 | 350 | ||
2673 | 356 | a_field = exported(TextLine(title=u"A field.")) | 351 | a_field = exported(TextLine(title="A field.")) |
2674 | 357 | 352 | ||
2675 | 358 | 353 | ||
2676 | 359 | @implementer(IHasNoWebLink) | 354 | @implementer(IHasNoWebLink) |
2677 | @@ -383,7 +378,7 @@ class InterfaceRestrictedField(TextLine): | |||
2678 | 383 | 378 | ||
2679 | 384 | def __init__(self, restrict_to_interface, *args, **kwargs): | 379 | def __init__(self, restrict_to_interface, *args, **kwargs): |
2680 | 385 | self.restrict_to_interface = restrict_to_interface | 380 | self.restrict_to_interface = restrict_to_interface |
2682 | 386 | super(InterfaceRestrictedField, self).__init__(*args, **kwargs) | 381 | super().__init__(*args, **kwargs) |
2683 | 387 | 382 | ||
2684 | 388 | def bind(self, context): | 383 | def bind(self, context): |
2685 | 389 | if not self.restrict_to_interface.providedBy(context): | 384 | if not self.restrict_to_interface.providedBy(context): |
2686 | @@ -391,7 +386,7 @@ class InterfaceRestrictedField(TextLine): | |||
2687 | 391 | "InterfaceRestrictedField can only be used with %s" | 386 | "InterfaceRestrictedField can only be used with %s" |
2688 | 392 | % self.restrict_to_interface.__name__ | 387 | % self.restrict_to_interface.__name__ |
2689 | 393 | ) | 388 | ) |
2691 | 394 | return super(InterfaceRestrictedField, self).bind(context) | 389 | return super().bind(context) |
2692 | 395 | 390 | ||
2693 | 396 | 391 | ||
2694 | 397 | @exported_as_webservice_entry() | 392 | @exported_as_webservice_entry() |
2695 | @@ -413,7 +408,7 @@ class HasRestrictedField: | |||
2696 | 413 | class IHasFieldExportedAsDifferentName(Interface): | 408 | class IHasFieldExportedAsDifferentName(Interface): |
2697 | 414 | """An entry with a field exported as a different name.""" | 409 | """An entry with a field exported as a different name.""" |
2698 | 415 | 410 | ||
2700 | 416 | a_field = exported(TextLine(title=u"A field."), exported_as="field") | 411 | a_field = exported(TextLine(title="A field."), exported_as="field") |
2701 | 417 | 412 | ||
2702 | 418 | 413 | ||
2703 | 419 | @implementer(IHasFieldExportedAsDifferentName) | 414 | @implementer(IHasFieldExportedAsDifferentName) |
2704 | @@ -437,7 +432,7 @@ class TestEntryWrite(EntryTestCase): | |||
2705 | 437 | # If web_link is not published, applyChanges rejects a request | 432 | # If web_link is not published, applyChanges rejects a request |
2706 | 438 | # that references it. | 433 | # that references it. |
2707 | 439 | with self.entry_resource(HasOneField, "") as resource: | 434 | with self.entry_resource(HasOneField, "") as resource: |
2709 | 440 | errors = resource.applyChanges({"web_link": u"some_value"}) | 435 | errors = resource.applyChanges({"web_link": "some_value"}) |
2710 | 441 | self.assertEqual( | 436 | self.assertEqual( |
2711 | 442 | errors, | 437 | errors, |
2712 | 443 | "web_link: You tried to modify a nonexistent attribute.", | 438 | "web_link: You tried to modify a nonexistent attribute.", |
2713 | @@ -448,7 +443,7 @@ class TestEntryWrite(EntryTestCase): | |||
2714 | 448 | self._register_website_url_space(IHasOneField) | 443 | self._register_website_url_space(IHasOneField) |
2715 | 449 | 444 | ||
2716 | 450 | with self.entry_resource(HasOneField, "") as resource: | 445 | with self.entry_resource(HasOneField, "") as resource: |
2718 | 451 | errors = resource.applyChanges({"web_link": u"some_value"}) | 446 | errors = resource.applyChanges({"web_link": "some_value"}) |
2719 | 452 | self.assertEqual( | 447 | self.assertEqual( |
2720 | 453 | errors, "web_link: You tried to modify a read-only attribute." | 448 | errors, "web_link: You tried to modify a read-only attribute." |
2721 | 454 | ) | 449 | ) |
2722 | @@ -484,7 +479,7 @@ class TestEntryWrite(EntryTestCase): | |||
2723 | 484 | 479 | ||
2724 | 485 | with self.entry_resource( | 480 | with self.entry_resource( |
2725 | 486 | HasFieldExportedAsDifferentName, | 481 | HasFieldExportedAsDifferentName, |
2727 | 487 | u"initial value", | 482 | "initial value", |
2728 | 488 | ) as resource: | 483 | ) as resource: |
2729 | 489 | # We have an entry that has a different name on the | 484 | # We have an entry that has a different name on the |
2730 | 490 | # entry than on its context. | 485 | # entry than on its context. |
2731 | @@ -492,13 +487,13 @@ class TestEntryWrite(EntryTestCase): | |||
2732 | 492 | self.assertEqual(entry.field, entry.context.a_field) | 487 | self.assertEqual(entry.field, entry.context.a_field) |
2733 | 493 | # This populates the cache. | 488 | # This populates the cache. |
2734 | 494 | self.assertEqual( | 489 | self.assertEqual( |
2736 | 495 | u"initial value", resource.toDataForJSON()["field"] | 490 | "initial value", resource.toDataForJSON()["field"] |
2737 | 496 | ) | 491 | ) |
2738 | 497 | # This returns the changed value. | 492 | # This returns the changed value. |
2739 | 498 | representation = simplejson.loads( | 493 | representation = simplejson.loads( |
2741 | 499 | resource.applyChanges(dict(field=u"new value")) | 494 | resource.applyChanges(dict(field="new value")) |
2742 | 500 | ) | 495 | ) |
2744 | 501 | self.assertEqual(u"new value", representation["field"]) | 496 | self.assertEqual("new value", representation["field"]) |
2745 | 502 | 497 | ||
2746 | 503 | 498 | ||
2747 | 504 | class TestEntryWriteForRestrictedField(EntryTestCase): | 499 | class TestEntryWriteForRestrictedField(EntryTestCase): |
2748 | @@ -518,7 +513,7 @@ class TestEntryWriteForRestrictedField(EntryTestCase): | |||
2749 | 518 | entry = resource.entry | 513 | entry = resource.entry |
2750 | 519 | entry.schema["a_field"].restrict_to_interface = IHasRestrictedField | 514 | entry.schema["a_field"].restrict_to_interface = IHasRestrictedField |
2751 | 520 | self.assertEqual(entry.a_field, "") | 515 | self.assertEqual(entry.a_field, "") |
2753 | 521 | resource.applyChanges({"a_field": u"a_value"}) | 516 | resource.applyChanges({"a_field": "a_value"}) |
2754 | 522 | self.assertEqual(entry.a_field, "a_value") | 517 | self.assertEqual(entry.a_field, "a_value") |
2755 | 523 | 518 | ||
2756 | 524 | # Make sure that IHasRestrictedField itself works correctly. | 519 | # Make sure that IHasRestrictedField itself works correctly. |
2757 | @@ -531,7 +526,7 @@ class TestEntryWriteForRestrictedField(EntryTestCase): | |||
2758 | 531 | self.assertRaises( | 526 | self.assertRaises( |
2759 | 532 | AssertionError, | 527 | AssertionError, |
2760 | 533 | resource.applyChanges, | 528 | resource.applyChanges, |
2762 | 534 | {"a_field": u"a_new_value"}, | 529 | {"a_field": "a_new_value"}, |
2763 | 535 | ) | 530 | ) |
2764 | 536 | self.assertEqual(resource.entry.a_field, "a_value") | 531 | self.assertEqual(resource.entry.a_field, "a_value") |
2765 | 537 | 532 | ||
2766 | @@ -542,9 +537,9 @@ class HTMLRepresentationTest(EntryTestCase): | |||
2767 | 542 | default_media_type = "application/xhtml+xml" | 537 | default_media_type = "application/xhtml+xml" |
2768 | 543 | 538 | ||
2769 | 544 | def setUp(self): | 539 | def setUp(self): |
2771 | 545 | super(HTMLRepresentationTest, self).setUp() | 540 | super().setUp() |
2772 | 546 | self._register_url_adapter(IHasOneField) | 541 | self._register_url_adapter(IHasOneField) |
2774 | 547 | self.unicode_message = u"Hello from a \N{SNOWMAN}" | 542 | self.unicode_message = "Hello from a \N{SNOWMAN}" |
2775 | 548 | self.utf8_message = self.unicode_message.encode("utf-8") | 543 | self.utf8_message = self.unicode_message.encode("utf-8") |
2776 | 549 | 544 | ||
2777 | 550 | def test_entry_html_representation_is_utf8(self): | 545 | def test_entry_html_representation_is_utf8(self): |
2778 | @@ -567,15 +562,13 @@ class JSONPlusHTMLRepresentationTest(EntryTestCase): | |||
2779 | 567 | testmodule_objects = [HasTwoFields, IHasTwoFields] | 562 | testmodule_objects = [HasTwoFields, IHasTwoFields] |
2780 | 568 | 563 | ||
2781 | 569 | def setUp(self): | 564 | def setUp(self): |
2783 | 570 | super(JSONPlusHTMLRepresentationTest, self).setUp() | 565 | super().setUp() |
2784 | 571 | self.default_media_type = "application/json;include=lp_html" | 566 | self.default_media_type = "application/json;include=lp_html" |
2785 | 572 | self._register_url_adapter(IHasTwoFields) | 567 | self._register_url_adapter(IHasTwoFields) |
2786 | 573 | 568 | ||
2787 | 574 | def register_html_field_renderer(self, name=""): | 569 | def register_html_field_renderer(self, name=""): |
2788 | 575 | """Simplify the register_html_field_renderer call.""" | 570 | """Simplify the register_html_field_renderer call.""" |
2792 | 576 | super( | 571 | super().register_html_field_renderer( |
2790 | 577 | JSONPlusHTMLRepresentationTest, self | ||
2791 | 578 | ).register_html_field_renderer( | ||
2793 | 579 | IHasTwoFields, ITextLine, simple_renderer, name | 572 | IHasTwoFields, ITextLine, simple_renderer, name |
2794 | 580 | ) | 573 | ) |
2795 | 581 | 574 | ||
2796 | @@ -584,8 +577,8 @@ class JSONPlusHTMLRepresentationTest(EntryTestCase): | |||
2797 | 584 | """Simplify the entry_resource call.""" | 577 | """Simplify the entry_resource call.""" |
2798 | 585 | with self.entry_resource( | 578 | with self.entry_resource( |
2799 | 586 | HasTwoFields, | 579 | HasTwoFields, |
2802 | 587 | six.text_type(value_1), | 580 | str(value_1), |
2803 | 588 | six.text_type(value_2), | 581 | str(value_2), |
2804 | 589 | ) as resource: | 582 | ) as resource: |
2805 | 590 | yield resource | 583 | yield resource |
2806 | 591 | 584 | ||
2807 | @@ -654,7 +647,7 @@ class JSONPlusHTMLRepresentationTest(EntryTestCase): | |||
2808 | 654 | with self.resource() as resource: | 647 | with self.resource() as resource: |
2809 | 655 | json_plus_xhtml = resource.JSON_PLUS_XHTML_TYPE | 648 | json_plus_xhtml = resource.JSON_PLUS_XHTML_TYPE |
2810 | 656 | json = simplejson.loads( | 649 | json = simplejson.loads( |
2812 | 657 | six.text_type(resource._representation(json_plus_xhtml)) | 650 | str(resource._representation(json_plus_xhtml)) |
2813 | 658 | ) | 651 | ) |
2814 | 659 | resource.applyChanges(json, json_plus_xhtml) | 652 | resource.applyChanges(json, json_plus_xhtml) |
2815 | 660 | self.assertEqual(resource.request.response.getStatus(), 209) | 653 | self.assertEqual(resource.request.response.getStatus(), 209) |
2816 | @@ -664,9 +657,7 @@ class JSONPlusHTMLRepresentationTest(EntryTestCase): | |||
2817 | 664 | json = None | 657 | json = None |
2818 | 665 | with self.resource() as resource: | 658 | with self.resource() as resource: |
2819 | 666 | json = simplejson.loads( | 659 | json = simplejson.loads( |
2823 | 667 | six.text_type( | 660 | str(resource._representation(resource.JSON_PLUS_XHTML_TYPE)) |
2821 | 668 | resource._representation(resource.JSON_PLUS_XHTML_TYPE) | ||
2822 | 669 | ) | ||
2824 | 670 | ) | 661 | ) |
2825 | 671 | resource.applyChanges(json, resource.JSON_TYPE) | 662 | resource.applyChanges(json, resource.JSON_TYPE) |
2826 | 672 | self.assertEqual(resource.request.response.getStatus(), 400) | 663 | self.assertEqual(resource.request.response.getStatus(), 400) |
2827 | @@ -676,7 +667,7 @@ class UnicodeChoice(EnumeratedType): | |||
2828 | 676 | """A choice between an ASCII value and a Unicode value.""" | 667 | """A choice between an ASCII value and a Unicode value.""" |
2829 | 677 | 668 | ||
2830 | 678 | ASCII = Item("Ascii", "Ascii choice") | 669 | ASCII = Item("Ascii", "Ascii choice") |
2832 | 679 | UNICODE = Item(u"Uni\u00e7ode", "Uni\u00e7ode choice") | 670 | UNICODE = Item("Uni\u00e7ode", "Uni\u00e7ode choice") |
2833 | 680 | 671 | ||
2834 | 681 | 672 | ||
2835 | 682 | @exported_as_webservice_entry() | 673 | @exported_as_webservice_entry() |
2836 | @@ -686,7 +677,7 @@ class ICanBeSetToUnicodeValue(Interface): | |||
2837 | 686 | a_field = exported( | 677 | a_field = exported( |
2838 | 687 | Choice( | 678 | Choice( |
2839 | 688 | vocabulary=UnicodeChoice, | 679 | vocabulary=UnicodeChoice, |
2841 | 689 | title=u"A value that might be ASCII or Unicode.", | 680 | title="A value that might be ASCII or Unicode.", |
2842 | 690 | required=False, | 681 | required=False, |
2843 | 691 | default=None, | 682 | default=None, |
2844 | 692 | ) | 683 | ) |
2845 | @@ -707,7 +698,7 @@ class UnicodeErrorTestCase(EntryTestCase): | |||
2846 | 707 | testmodule_objects = [CanBeSetToUnicodeValue, ICanBeSetToUnicodeValue] | 698 | testmodule_objects = [CanBeSetToUnicodeValue, ICanBeSetToUnicodeValue] |
2847 | 708 | 699 | ||
2848 | 709 | def setUp(self): | 700 | def setUp(self): |
2850 | 710 | super(UnicodeErrorTestCase, self).setUp() | 701 | super().setUp() |
2851 | 711 | self._register_url_adapter(ICanBeSetToUnicodeValue) | 702 | self._register_url_adapter(ICanBeSetToUnicodeValue) |
2852 | 712 | 703 | ||
2853 | 713 | def test_unicode_error(self): | 704 | def test_unicode_error(self): |
2854 | @@ -715,14 +706,14 @@ class UnicodeErrorTestCase(EntryTestCase): | |||
2855 | 715 | 706 | ||
2856 | 716 | # This will raise an exception, which will cause the request | 707 | # This will raise an exception, which will cause the request |
2857 | 717 | # to fail with a 400 error code. | 708 | # to fail with a 400 error code. |
2859 | 718 | error = resource.applyChanges({"a_field": u"No such value"}) | 709 | error = resource.applyChanges({"a_field": "No such value"}) |
2860 | 719 | self.assertEqual(resource.request.response.getStatus(), 400) | 710 | self.assertEqual(resource.request.response.getStatus(), 400) |
2861 | 720 | 711 | ||
2862 | 721 | # The error message is a Unicode string which mentions both | 712 | # The error message is a Unicode string which mentions both |
2863 | 722 | # the ASCII value and the Unicode value, | 713 | # the ASCII value and the Unicode value, |
2864 | 723 | expected_error = ( | 714 | expected_error = ( |
2867 | 724 | u'a_field: Invalid value "No such value". Acceptable values ' | 715 | 'a_field: Invalid value "No such value". Acceptable values ' |
2868 | 725 | u"are: Ascii, Uni\u00e7ode" | 716 | "are: Ascii, Uni\u00e7ode" |
2869 | 726 | ) | 717 | ) |
2870 | 727 | self.assertEqual(error, expected_error) | 718 | self.assertEqual(error, expected_error) |
2871 | 728 | 719 | ||
2872 | @@ -887,7 +878,7 @@ class DuplicateNameTestCase(WebServiceTestCase): | |||
2873 | 887 | def make_entry(name): | 878 | def make_entry(name): |
2874 | 888 | """Make an entity with some attibutes to expose as a web service.""" | 879 | """Make an entity with some attibutes to expose as a web service.""" |
2875 | 889 | fields = { | 880 | fields = { |
2877 | 890 | "%s_field" % letter: exported(TextLine(title=u"Field %s" % letter)) | 881 | "%s_field" % letter: exported(TextLine(title="Field %s" % letter)) |
2878 | 891 | for letter in "rstuvwxyz" | 882 | for letter in "rstuvwxyz" |
2879 | 892 | } | 883 | } |
2880 | 893 | cls = InterfaceClass(name, bases=(Interface,), attrs=fields) | 884 | cls = InterfaceClass(name, bases=(Interface,), attrs=fields) |
2881 | @@ -901,7 +892,7 @@ class TestWadlDeterminism(WebServiceTestCase): | |||
2882 | 901 | # make some -- randomly ordered -- objects to use to build the WADL | 892 | # make some -- randomly ordered -- objects to use to build the WADL |
2883 | 902 | self.testmodule_objects = [make_entry(name) for name in "abcdefghijk"] | 893 | self.testmodule_objects = [make_entry(name) for name in "abcdefghijk"] |
2884 | 903 | random.shuffle(self.testmodule_objects) | 894 | random.shuffle(self.testmodule_objects) |
2886 | 904 | super(TestWadlDeterminism, self).__init__(*args, **kwargs) | 895 | super().__init__(*args, **kwargs) |
2887 | 905 | 896 | ||
2888 | 906 | @property | 897 | @property |
2889 | 907 | def wadl(self): | 898 | def wadl(self): |
2890 | @@ -1026,7 +1017,7 @@ class BaseBatchingTest: | |||
2891 | 1026 | testmodule_objects = [HasRestrictedField, IHasRestrictedField] | 1017 | testmodule_objects = [HasRestrictedField, IHasRestrictedField] |
2892 | 1027 | 1018 | ||
2893 | 1028 | def setUp(self): | 1019 | def setUp(self): |
2895 | 1029 | super(BaseBatchingTest, self).setUp() | 1020 | super().setUp() |
2896 | 1030 | # Register TestEntry as the IEntry implementation for ITestEntry. | 1021 | # Register TestEntry as the IEntry implementation for ITestEntry. |
2897 | 1031 | getGlobalSiteManager().registerAdapter( | 1022 | getGlobalSiteManager().registerAdapter( |
2898 | 1032 | TestEntry, [ITestEntry, IWebServiceClientRequest], provided=IEntry | 1023 | TestEntry, [ITestEntry, IWebServiceClientRequest], provided=IEntry |
2899 | @@ -1100,7 +1091,7 @@ class NotificationsProviderTest(EntryTestCase): | |||
2900 | 1100 | ] | 1091 | ] |
2901 | 1101 | 1092 | ||
2902 | 1102 | def setUp(self): | 1093 | def setUp(self): |
2904 | 1103 | super(NotificationsProviderTest, self).setUp() | 1094 | super().setUp() |
2905 | 1104 | self.default_media_type = "application/json;include=lp_html" | 1095 | self.default_media_type = "application/json;include=lp_html" |
2906 | 1105 | self._register_website_url_space(IHasOneField) | 1096 | self._register_website_url_space(IHasOneField) |
2907 | 1106 | self._register_notification_adapter() | 1097 | self._register_notification_adapter() |
2908 | @@ -1146,7 +1137,7 @@ class EventTestCase(EntryTestCase): | |||
2909 | 1146 | testmodule_objects = [IHasOneField] | 1137 | testmodule_objects = [IHasOneField] |
2910 | 1147 | 1138 | ||
2911 | 1148 | def setUp(self): | 1139 | def setUp(self): |
2913 | 1149 | super(EventTestCase, self).setUp() | 1140 | super().setUp() |
2914 | 1150 | self._register_url_adapter(IHasOneField) | 1141 | self._register_url_adapter(IHasOneField) |
2915 | 1151 | eventtesting.setUp() | 1142 | eventtesting.setUp() |
2916 | 1152 | 1143 | ||
2917 | @@ -1154,7 +1145,7 @@ class EventTestCase(EntryTestCase): | |||
2918 | 1154 | # Passing in a non-empty changeset spawns an | 1145 | # Passing in a non-empty changeset spawns an |
2919 | 1155 | # IObjectModifiedEvent. | 1146 | # IObjectModifiedEvent. |
2920 | 1156 | with self.entry_resource(HasOneField, "") as resource: | 1147 | with self.entry_resource(HasOneField, "") as resource: |
2922 | 1157 | resource.applyChanges({"a_field": u"Some value"}) | 1148 | resource.applyChanges({"a_field": "Some value"}) |
2923 | 1158 | events = eventtesting.getEvents() | 1149 | events = eventtesting.getEvents() |
2924 | 1159 | self.assertEqual(len(events), 1) | 1150 | self.assertEqual(len(events), 1) |
2925 | 1160 | event = events[0] | 1151 | event = events[0] |
2926 | @@ -1175,9 +1166,9 @@ class MalformedRequest(EntryTestCase): | |||
2927 | 1175 | default_media_type = "application/xhtml+xml" | 1166 | default_media_type = "application/xhtml+xml" |
2928 | 1176 | 1167 | ||
2929 | 1177 | def setUp(self): | 1168 | def setUp(self): |
2931 | 1178 | super(MalformedRequest, self).setUp() | 1169 | super().setUp() |
2932 | 1179 | self._register_url_adapter(IHasOneField) | 1170 | self._register_url_adapter(IHasOneField) |
2934 | 1180 | self.unicode_message = u"Hello from a \N{SNOWMAN}" | 1171 | self.unicode_message = "Hello from a \N{SNOWMAN}" |
2935 | 1181 | 1172 | ||
2936 | 1182 | def test_multiple_named_operations_generate_error_on_GET(self): | 1173 | def test_multiple_named_operations_generate_error_on_GET(self): |
2937 | 1183 | with self.entry_resource( | 1174 | with self.entry_resource( |
2938 | diff --git a/src/lazr/restful/utils.py b/src/lazr/restful/utils.py | |||
2939 | index 043ed87..2175977 100644 | |||
2940 | --- a/src/lazr/restful/utils.py | |||
2941 | +++ b/src/lazr/restful/utils.py | |||
2942 | @@ -2,9 +2,6 @@ | |||
2943 | 2 | 2 | ||
2944 | 3 | """Various utility functions.""" | 3 | """Various utility functions.""" |
2945 | 4 | 4 | ||
2946 | 5 | from __future__ import absolute_import, print_function | ||
2947 | 6 | |||
2948 | 7 | __metaclass__ = type | ||
2949 | 8 | __all__ = [ | 5 | __all__ = [ |
2950 | 9 | "camelcase_to_underscore_separated", | 6 | "camelcase_to_underscore_separated", |
2951 | 10 | "get_current_browser_request", | 7 | "get_current_browser_request", |
2952 | @@ -20,7 +17,7 @@ __all__ = [ | |||
2953 | 20 | "VersionedObject", | 17 | "VersionedObject", |
2954 | 21 | ] | 18 | ] |
2955 | 22 | 19 | ||
2957 | 23 | 20 | import builtins | |
2958 | 24 | import collections | 21 | import collections |
2959 | 25 | import copy | 22 | import copy |
2960 | 26 | import operator | 23 | import operator |
2961 | @@ -28,8 +25,6 @@ import re | |||
2962 | 28 | import string | 25 | import string |
2963 | 29 | import subprocess | 26 | import subprocess |
2964 | 30 | 27 | ||
2965 | 31 | import six | ||
2966 | 32 | |||
2967 | 33 | from zope.component import getUtility | 28 | from zope.component import getUtility |
2968 | 34 | from zope.schema import getFieldsInOrder | 29 | from zope.schema import getFieldsInOrder |
2969 | 35 | from zope.interface import alsoProvides, classImplements | 30 | from zope.interface import alsoProvides, classImplements |
2970 | @@ -134,7 +129,7 @@ VersionedObject = collections.namedtuple( | |||
2971 | 134 | ) | 129 | ) |
2972 | 135 | 130 | ||
2973 | 136 | 131 | ||
2975 | 137 | class VersionedDict(object): | 132 | class VersionedDict: |
2976 | 138 | """A stack of named dictionaries. | 133 | """A stack of named dictionaries. |
2977 | 139 | 134 | ||
2978 | 140 | Most access to the stack actually operates on the dictionary on | 135 | Most access to the stack actually operates on the dictionary on |
2979 | @@ -368,9 +363,11 @@ def safe_hasattr(ob, name): | |||
2980 | 368 | 363 | ||
2981 | 369 | def smartquote(str): | 364 | def smartquote(str): |
2982 | 370 | """Return a copy of the string, with typographical quote marks applied.""" | 365 | """Return a copy of the string, with typographical quote marks applied.""" |
2986 | 371 | str = six.text_type(str) | 366 | # Using builtins.str here is weird, but it lets us cope with the |
2987 | 372 | str = re.compile(u'(^| )(")([^" ])').sub(u"\\1\u201c\\3", str) | 367 | # unfortunate naming of our positional argument without breaking API. |
2988 | 373 | str = re.compile(u'([^ "])(")($|[\\s.,;:!?])').sub(u"\\1\u201d\\3", str) | 368 | str = builtins.str(str) |
2989 | 369 | str = re.compile('(^| )(")([^" ])').sub("\\1\u201c\\3", str) | ||
2990 | 370 | str = re.compile('([^ "])(")($|[\\s.,;:!?])').sub("\\1\u201d\\3", str) | ||
2991 | 374 | return str | 371 | return str |
2992 | 375 | 372 | ||
2993 | 376 | 373 | ||
2994 | diff --git a/src/lazr/restful/wsgi.py b/src/lazr/restful/wsgi.py | |||
2995 | index 2b03ab3..fc298e0 100644 | |||
2996 | --- a/src/lazr/restful/wsgi.py | |||
2997 | +++ b/src/lazr/restful/wsgi.py | |||
2998 | @@ -1,8 +1,5 @@ | |||
2999 | 1 | """A WSGI application for a lazr.restful web service.""" | 1 | """A WSGI application for a lazr.restful web service.""" |
3000 | 2 | 2 | ||
3001 | 3 | from __future__ import absolute_import, print_function | ||
3002 | 4 | |||
3003 | 5 | __metaclass__ = type | ||
3004 | 6 | __all__ = [ | 3 | __all__ = [ |
3005 | 7 | "BaseWSGIWebServiceConfiguration", | 4 | "BaseWSGIWebServiceConfiguration", |
3006 | 8 | "WSGIApplication", | 5 | "WSGIApplication", |
LGTM with a minor issue, see comment