Merge lp:~allenap/convoy/python3-clean-up into lp:convoy

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
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.

To post a comment you must log in.
Revision history for this message
Fabrice Matrat (fabricematrat) wrote :

LGTM

review: Approve

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

Subscribers

People subscribed via source and target branches

to all changes: