Merge lp:~allenap/convoy/python3-clean-up into lp:convoy
- python3-clean-up
- Merge into trunk
Proposed by
Gavin Panella
Status: | Merged |
---|---|
Merged at revision: | 38 |
Proposed branch: | lp:~allenap/convoy/python3-clean-up |
Merge into: | lp:convoy |
Prerequisite: | lp:~allenap/convoy/python3 |
Diff against target: |
347 lines (+89/-65) 5 files modified
convoy/combo.py (+11/-5) convoy/meta.py (+15/-16) convoy/tests/test_combo.py (+54/-39) convoy/tests/test_meta.py (+8/-4) setup.py (+1/-1) |
To merge this branch: | bzr merge lp:~allenap/convoy/python3-clean-up |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Fabrice Matrat (community) | Approve | ||
Review via email: mp+277292@code.launchpad.net |
Commit message
Tidy up after the Python 3 porting effort.
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'convoy/combo.py' |
2 | --- convoy/combo.py 2015-11-11 19:53:19 +0000 |
3 | +++ convoy/combo.py 2015-11-11 19:53:19 +0000 |
4 | @@ -15,13 +15,17 @@ |
5 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
6 | |
7 | |
8 | -import cgi |
9 | import logging |
10 | import os.path |
11 | import re |
12 | import sys |
13 | |
14 | try: |
15 | + from urllib.parse import parse_qsl |
16 | +except ImportError: |
17 | + from cgi import parse_qsl |
18 | + |
19 | +try: |
20 | import urllib.parse as urlparse |
21 | except ImportError: |
22 | import urlparse |
23 | @@ -56,7 +60,7 @@ |
24 | |
25 | Returns the list of arguments in the original order. |
26 | """ |
27 | - params = cgi.parse_qsl(query, keep_blank_values=True) |
28 | + params = parse_qsl(query, keep_blank_values=True) |
29 | return tuple([param for param, value in params]) |
30 | |
31 | |
32 | @@ -124,12 +128,13 @@ |
33 | parts = relative_parts + url.split(b"/") |
34 | result = [] |
35 | for part in parts: |
36 | - if part == b".." and result and result[-1] != b"..": |
37 | + if part == b".." and result[-1:] != [b".."]: |
38 | result.pop(-1) |
39 | continue |
40 | result.append(part) |
41 | return b"url(x)".replace(b"x", b"/".join( |
42 | - part for part in [resource_prefix] + result if part)) |
43 | + part for part in [resource_prefix] + result |
44 | + if part)) |
45 | |
46 | file_content = URL_RE.sub(fix_relative_url, file_content) |
47 | yield file_content |
48 | @@ -143,7 +148,8 @@ |
49 | yield chunk |
50 | |
51 | |
52 | -def combo_app(root, resource_prefix="", rewrite_urls=True, additional_headers=None): |
53 | +def combo_app( |
54 | + root, resource_prefix="", rewrite_urls=True, additional_headers=None): |
55 | """A simple YUI Combo Service WSGI app. |
56 | |
57 | Serves any files under C{root}, setting an appropriate |
58 | |
59 | === modified file 'convoy/meta.py' |
60 | --- convoy/meta.py 2015-11-11 19:53:19 +0000 |
61 | +++ convoy/meta.py 2015-11-11 19:53:19 +0000 |
62 | @@ -170,11 +170,10 @@ |
63 | return match.group(1) + literals_map[literal] + match.group(3) |
64 | return match.group(0) |
65 | |
66 | - |
67 | linebreak = ",\n " |
68 | variables_decl = "var SKIN_SAM_PREFIX = 'skin-sam-'" + linebreak |
69 | if self.prefix: |
70 | - variables_decl += "PREFIX = '%s'%s" % (self.prefix, linebreak) |
71 | + variables_decl += "PREFIX = '%s'%s" % (self.prefix, linebreak) |
72 | extra_variables = [] |
73 | for literal, variable in sorted(literals_map.items()): |
74 | extra_variable = "%s = %s" % ( |
75 | @@ -220,8 +219,8 @@ |
76 | # It's easy to think that doing 'CORE_CSS + %(values)s' |
77 | # instead of using concat would work, but it doesn't; |
78 | # you'll end up with a string instead of a list. |
79 | - module_decl.append("after_list = CORE_CSS"); |
80 | - module_decl.append("after_list.concat(%s)" % value); |
81 | + module_decl.append("after_list = CORE_CSS") |
82 | + module_decl.append("after_list.concat(%s)" % value) |
83 | value = "after_list" |
84 | if key == "path": |
85 | value = value.replace( |
86 | @@ -369,15 +368,15 @@ |
87 | |
88 | |
89 | def main(): |
90 | - options, args = get_options() |
91 | - if options.src_dir is None: |
92 | - options.src_dir = os.getcwd() |
93 | - Builder( |
94 | - name=options.name, |
95 | - src_dir=os.path.abspath(options.src_dir), |
96 | - output=options.output, |
97 | - prefix=options.prefix, |
98 | - exclude_regex=options.exclude_regex, |
99 | - ext=options.ext, |
100 | - include_skin=not options.no_skin, |
101 | - ).do_build() |
102 | + options, args = get_options() |
103 | + if options.src_dir is None: |
104 | + options.src_dir = os.getcwd() |
105 | + Builder( |
106 | + name=options.name, |
107 | + src_dir=os.path.abspath(options.src_dir), |
108 | + output=options.output, |
109 | + prefix=options.prefix, |
110 | + exclude_regex=options.exclude_regex, |
111 | + ext=options.ext, |
112 | + include_skin=not options.no_skin, |
113 | + ).do_build() |
114 | |
115 | === modified file 'convoy/tests/test_combo.py' |
116 | --- convoy/tests/test_combo.py 2015-11-11 19:53:19 +0000 |
117 | +++ convoy/tests/test_combo.py 2015-11-11 19:53:19 +0000 |
118 | @@ -88,10 +88,11 @@ |
119 | "/* event-custom/event-custom-min.js */", |
120 | "** event-custom-min **")) |
121 | self.assertEqual( |
122 | - b"".join(combine_files(["yui/yui-min.js", |
123 | - "oop/oop-min.js", |
124 | - "event-custom/event-custom-min.js"], |
125 | - root=test_dir)).strip(), |
126 | + b"".join(combine_files( |
127 | + ["yui/yui-min.js", |
128 | + "oop/oop-min.js", |
129 | + "event-custom/event-custom-min.js"], |
130 | + root=test_dir)).strip(), |
131 | expected.encode("ascii")) |
132 | |
133 | def test_combine_files_yields_only_byte_strings(self): |
134 | @@ -144,9 +145,10 @@ |
135 | } |
136 | """ |
137 | self.assertTextEquals( |
138 | - b"".join(combine_files(["widget/assets/skins/sam/widget.css", |
139 | - "editor/assets/skins/sam/editor.css"], |
140 | - root=test_dir)).strip(), |
141 | + b"".join(combine_files( |
142 | + ["widget/assets/skins/sam/widget.css", |
143 | + "editor/assets/skins/sam/editor.css"], |
144 | + root=test_dir)).strip(), |
145 | expected) |
146 | |
147 | def test_combine_css_leaves_absolute_urls_untouched(self): |
148 | @@ -189,9 +191,10 @@ |
149 | } |
150 | """ |
151 | self.assertTextEquals( |
152 | - b"".join(combine_files(["widget/assets/skins/sam/widget.css", |
153 | - "editor/assets/skins/sam/editor.css"], |
154 | - root=test_dir)).strip(), |
155 | + b"".join(combine_files( |
156 | + ["widget/assets/skins/sam/widget.css", |
157 | + "editor/assets/skins/sam/editor.css"], |
158 | + root=test_dir)).strip(), |
159 | expected) |
160 | |
161 | def test_combine_css_leaves_data_uris_untouched(self): |
162 | @@ -234,9 +237,10 @@ |
163 | } |
164 | """ |
165 | self.assertTextEquals( |
166 | - b"".join(combine_files(["widget/assets/skins/sam/widget.css", |
167 | - "editor/assets/skins/sam/editor.css"], |
168 | - root=test_dir)).strip(), |
169 | + b"".join(combine_files( |
170 | + ["widget/assets/skins/sam/widget.css", |
171 | + "editor/assets/skins/sam/editor.css"], |
172 | + root=test_dir)).strip(), |
173 | expected) |
174 | |
175 | def test_no_parent_hack(self): |
176 | @@ -336,10 +340,10 @@ |
177 | } |
178 | """ |
179 | self.assertTextEquals( |
180 | - b"".join(combine_files(["widget/assets/skins/sam/widget.css", |
181 | - "editor/assets/skins/sam/editor.css"], |
182 | - root=test_dir, |
183 | - resource_prefix="/static/")).strip(), |
184 | + b"".join(combine_files( |
185 | + ["widget/assets/skins/sam/widget.css", |
186 | + "editor/assets/skins/sam/editor.css"], |
187 | + root=test_dir, resource_prefix="/static/")).strip(), |
188 | expected) |
189 | |
190 | def test_combine_css_adds_custom_prefix_minified(self): |
191 | @@ -367,20 +371,18 @@ |
192 | def test_rewrite_url_normalizes_parent_references(self): |
193 | """URL references in CSS files get normalized for parent dirs.""" |
194 | test_dir = self.makeDir() |
195 | - files = [ |
196 | - self.makeSampleFile( |
197 | - test_dir, |
198 | - os.path.join("yui", "base", "base.css"), |
199 | - ".foo{background-image:url(../../img.png)}"), |
200 | - ] |
201 | + self.makeSampleFile( |
202 | + test_dir, os.path.join("yui", "base", "base.css"), |
203 | + ".foo{background-image:url(../../img.png)}"), |
204 | |
205 | expected = """ |
206 | /* yui/base/base.css */ |
207 | .foo{background-image:url(img.png)} |
208 | """ |
209 | self.assertTextEquals( |
210 | - b"".join(combine_files(["yui/base/base.css"], |
211 | - root=test_dir)).strip(), |
212 | + b"".join(combine_files( |
213 | + ["yui/base/base.css"], |
214 | + root=test_dir)).strip(), |
215 | expected) |
216 | |
217 | |
218 | @@ -437,8 +439,10 @@ |
219 | ["yui/yui-min.js", |
220 | "oop/oop-min.js", |
221 | "event-custom/event-custom-min.js"]), status=200) |
222 | - self.assertEqual(res.headers, [("Content-Type", "text/javascript"), |
223 | - ("X-Content-Type-Options", "nosniff")]) |
224 | + self.assertEqual(res.headers, [ |
225 | + ("Content-Type", "text/javascript"), |
226 | + ("X-Content-Type-Options", "nosniff"), |
227 | + ]) |
228 | self.assertEqual(res.body.strip(), expected.encode("ascii")) |
229 | |
230 | def test_combo_app_sets_content_type_for_css(self): |
231 | @@ -452,8 +456,10 @@ |
232 | |
233 | res = self.app.get("/?" + "&".join( |
234 | ["widget/skin/sam/widget.css"]), status=200) |
235 | - self.assertEqual(res.headers, [("Content-Type", "text/css"), |
236 | - ("X-Content-Type-Options", "nosniff")]) |
237 | + self.assertEqual(res.headers, [ |
238 | + ("Content-Type", "text/css"), |
239 | + ("X-Content-Type-Options", "nosniff"), |
240 | + ]) |
241 | self.assertEqual(res.body.strip(), expected.encode("ascii")) |
242 | |
243 | def test_no_filename_gives_404(self): |
244 | @@ -467,12 +473,16 @@ |
245 | Content-Type and X-Content-Type-Options headers set for |
246 | non-existent files. |
247 | """ |
248 | - res = self.app.get("/?" + "&".join( |
249 | - ["foo/bar/baz", |
250 | - "<html><script>alert(document.domain)</script></html>"]), |
251 | - status=400) |
252 | - self.assertEqual(res.headers, [("Content-Type", "text/plain"), |
253 | - ("X-Content-Type-Options", "nosniff")]) |
254 | + res = self.app.get( |
255 | + "/?" + "&".join([ |
256 | + "foo/bar/baz", |
257 | + "<html><script>alert(document.domain)</script></html>", |
258 | + ]), |
259 | + status=400) |
260 | + self.assertEqual(res.headers, [ |
261 | + ("Content-Type", "text/plain"), |
262 | + ("X-Content-Type-Options", "nosniff"), |
263 | + ]) |
264 | |
265 | def test_js_comment_escape_hack(self): |
266 | """Attacks to break out of the JS comment will get a 400 error.""" |
267 | @@ -528,9 +538,14 @@ |
268 | app.get("/../etc?yui-min&passwd", status=400) |
269 | |
270 | def test_cache_headers_set(self): |
271 | - app = TestApp(combo_app(self.root, additional_headers=[('Cache-Control', 'max-age=3600, public')])) |
272 | + app = TestApp(combo_app( |
273 | + self.root, additional_headers=[ |
274 | + ('Cache-Control', 'max-age=3600, public'), |
275 | + ])) |
276 | res = app.get("/?" + "&".join( |
277 | ["widget/skin/sam/widget.css"]), status=400) |
278 | - self.assertEqual(res.headers, [("Content-Type", "text/css"), |
279 | - ("X-Content-Type-Options", "nosniff"), |
280 | - ('Cache-Control', 'max-age=3600, public')]) |
281 | + self.assertEqual(res.headers, [ |
282 | + ("Content-Type", "text/css"), |
283 | + ("X-Content-Type-Options", "nosniff"), |
284 | + ('Cache-Control', 'max-age=3600, public'), |
285 | + ]) |
286 | |
287 | === modified file 'convoy/tests/test_meta.py' |
288 | --- convoy/tests/test_meta.py 2015-11-11 19:53:19 +0000 |
289 | +++ convoy/tests/test_meta.py 2015-11-11 19:53:19 +0000 |
290 | @@ -126,7 +126,8 @@ |
291 | metadata = extract_metadata("""\ |
292 | YUI.add('lazr.anim', function(Y){ |
293 | Y.log('Hello World'); |
294 | - }, '0.1', {"use": ["dom"], "requires": [ "node" ,"anim" , "event" ]}); |
295 | + }, '0.1', {"use": ["dom"], "requires": [ |
296 | + "node" ,"anim" , "event" ]}); |
297 | """) |
298 | |
299 | self.assertEqual(len(metadata), 1) |
300 | @@ -141,7 +142,8 @@ |
301 | metadata = extract_metadata("""\ |
302 | YUI.add('lazr.anim', function(Y){ |
303 | Y.log('Hello World'); |
304 | - }, '0.1', {"requires": [ "node" ,"anim" , "event" ], "use": ["dom"]}); |
305 | + }, '0.1', {"requires": [ "node" ,"anim" , "event" ], |
306 | + "use": ["dom"]}); |
307 | """) |
308 | |
309 | self.assertEqual(len(metadata), 1) |
310 | @@ -177,7 +179,9 @@ |
311 | """ |
312 | metadata = extract_metadata(""" |
313 | YUI.add('test', function(Y) { |
314 | - this._dds[h[i]] = new YAHOO.util.DragDrop(this._handles[h[i]], this.get('id') + '-handle-' + h, { useShim: this.get('useShim') }); |
315 | + this._dds[h[i]] = new YAHOO.util.DragDrop( |
316 | + this._handles[h[i]], this.get('id') + '-handle-' + h, { |
317 | + useShim: this.get('useShim') }); |
318 | }, '1.0', {requires: ['dom']}); |
319 | """) |
320 | |
321 | @@ -205,7 +209,6 @@ |
322 | self.assertEqual(metadata[0]["requires"], ["node", "anim", "event"]) |
323 | self.assertEqual(metadata[0]["use"], ["dom"]) |
324 | |
325 | - |
326 | def test_extract_has_no_quotes(self): |
327 | """ |
328 | If the javascript is using object literals, we should adjust for |
329 | @@ -312,6 +315,7 @@ |
330 | self.assertEqual(metadata[0]["supersedes"], ["old-anim"]) |
331 | self.assertEqual(metadata[0]["after"], ["lazr.base"]) |
332 | |
333 | + |
334 | class GenerateMetadataTest(ConvoyTestCase): |
335 | |
336 | def readFile(self, path): |
337 | |
338 | === modified file 'setup.py' |
339 | --- setup.py 2015-11-11 19:53:19 +0000 |
340 | +++ setup.py 2015-11-11 19:53:19 +0000 |
341 | @@ -1,5 +1,5 @@ |
342 | # Convoy is a WSGI app for loading multiple files in the same request. |
343 | -# Copyright (C) 2010-2015 Canonical, Ltd. |
344 | +# Copyright (C) 2011-2015 Canonical, Ltd. |
345 | # |
346 | # This program is free software: you can redistribute it and/or modify |
347 | # it under the terms of the GNU Affero General Public License as |
LGTM