Merge lp:~kernevil/ubuntu/saucy/pylons/fix-useless-import into lp:ubuntu/saucy/pylons

Proposed by Kernevil
Status: Needs review
Proposed branch: lp:~kernevil/ubuntu/saucy/pylons/fix-useless-import
Merge into: lp:ubuntu/saucy/pylons
Diff against target: 366 lines (+246/-18)
10 files modified
.pc/.quilt_patches (+1/-0)
.pc/.quilt_series (+1/-0)
.pc/applied-patches (+1/-0)
.pc/fix-useless-import.patch/pylons/decorators/__init__.py (+207/-0)
debian/changelog (+6/-0)
debian/patches/fix-useless-import.patch (+12/-0)
debian/patches/ipython_0.11_compatibility.patch (+4/-4)
debian/patches/move_data_outside_site-packages.patch (+13/-13)
debian/patches/series (+1/-0)
pylons/decorators/__init__.py (+0/-1)
To merge this branch: bzr merge lp:~kernevil/ubuntu/saucy/pylons/fix-useless-import
Reviewer Review Type Date Requested Status
Sebastien Bacher Needs Fixing
Review via email: mp+211046@code.launchpad.net
To post a comment you must log in.
14. By Kernevil

Fix useless import

Revision history for this message
Sebastien Bacher (seb128) wrote :

Thank you for your work there. The issue is fixed in trusty, if you want a stable update to saucy could you update the bug to include the SRU informations (https://wiki.ubuntu.com/StableReleaseUpdates) and add a changelog entry to your update?

review: Needs Fixing

Unmerged revisions

14. By Kernevil

Fix useless import

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.pc/.quilt_patches'
2--- .pc/.quilt_patches 1970-01-01 00:00:00 +0000
3+++ .pc/.quilt_patches 2014-03-14 14:46:27 +0000
4@@ -0,0 +1,1 @@
5+debian/patches
6
7=== added file '.pc/.quilt_series'
8--- .pc/.quilt_series 1970-01-01 00:00:00 +0000
9+++ .pc/.quilt_series 2014-03-14 14:46:27 +0000
10@@ -0,0 +1,1 @@
11+series
12
13=== modified file '.pc/applied-patches'
14--- .pc/applied-patches 2011-08-02 21:17:36 +0000
15+++ .pc/applied-patches 2014-03-14 14:46:27 +0000
16@@ -1,2 +1,3 @@
17 move_data_outside_site-packages.patch
18 ipython_0.11_compatibility.patch
19+fix-useless-import.patch
20
21=== added directory '.pc/fix-useless-import.patch'
22=== added file '.pc/fix-useless-import.patch/.timestamp'
23=== added directory '.pc/fix-useless-import.patch/pylons'
24=== added directory '.pc/fix-useless-import.patch/pylons/decorators'
25=== added file '.pc/fix-useless-import.patch/pylons/decorators/__init__.py'
26--- .pc/fix-useless-import.patch/pylons/decorators/__init__.py 1970-01-01 00:00:00 +0000
27+++ .pc/fix-useless-import.patch/pylons/decorators/__init__.py 2014-03-14 14:46:27 +0000
28@@ -0,0 +1,207 @@
29+"""Pylons Decorators
30+
31+Common decorators intended for use in controllers. Additional
32+decorators for use with controllers are in the
33+:mod:`~pylons.decorators.cache`, :mod:`~pylons.decorators.rest` and
34+:mod:`~pylons.decorators.secure` modules.
35+
36+"""
37+import logging
38+import sys
39+import warnings
40+
41+import formencode
42+import simplejson
43+from decorator import decorator
44+from formencode import api, htmlfill, variabledecode
45+from webob.multidict import UnicodeMultiDict
46+
47+from pylons.decorators.util import get_pylons
48+from pylons.i18n import _ as pylons_gettext
49+
50+__all__ = ['jsonify', 'validate']
51+
52+log = logging.getLogger(__name__)
53+
54+@decorator
55+def jsonify(func, *args, **kwargs):
56+ """Action decorator that formats output for JSON
57+
58+ Given a function that will return content, this decorator will turn
59+ the result into JSON, with a content-type of 'application/json' and
60+ output it.
61+
62+ """
63+ pylons = get_pylons(args)
64+ pylons.response.headers['Content-Type'] = 'application/json'
65+ data = func(*args, **kwargs)
66+ if isinstance(data, (list, tuple)):
67+ msg = "JSON responses with Array envelopes are susceptible to " \
68+ "cross-site data leak attacks, see " \
69+ "http://pylonshq.com/warnings/JSONArray"
70+ warnings.warn(msg, Warning, 2)
71+ log.warning(msg)
72+ log.debug("Returning JSON wrapped action output")
73+ return simplejson.dumps(data)
74+
75+
76+def validate(schema=None, validators=None, form=None, variable_decode=False,
77+ dict_char='.', list_char='-', post_only=True, state=None,
78+ on_get=False, **htmlfill_kwargs):
79+ """Validate input either for a FormEncode schema, or individual
80+ validators
81+
82+ Given a form schema or dict of validators, validate will attempt to
83+ validate the schema or validator list.
84+
85+ If validation was successful, the valid result dict will be saved
86+ as ``self.form_result``. Otherwise, the action will be re-run as if
87+ it was a GET, and the output will be filled by FormEncode's
88+ htmlfill to fill in the form field errors.
89+
90+ ``schema``
91+ Refers to a FormEncode Schema object to use during validation.
92+ ``form``
93+ Method used to display the form, which will be used to get the
94+ HTML representation of the form for error filling.
95+ ``variable_decode``
96+ Boolean to indicate whether FormEncode's variable decode
97+ function should be run on the form input before validation.
98+ ``dict_char``
99+ Passed through to FormEncode. Toggles the form field naming
100+ scheme used to determine what is used to represent a dict. This
101+ option is only applicable when used with variable_decode=True.
102+ ``list_char``
103+ Passed through to FormEncode. Toggles the form field naming
104+ scheme used to determine what is used to represent a list. This
105+ option is only applicable when used with variable_decode=True.
106+ ``post_only``
107+ Boolean that indicates whether or not GET (query) variables
108+ should be included during validation.
109+
110+ .. warning::
111+ ``post_only`` applies to *where* the arguments to be
112+ validated come from. It does *not* restrict the form to
113+ only working with post, merely only checking POST vars.
114+ ``state``
115+ Passed through to FormEncode for use in validators that utilize
116+ a state object.
117+ ``on_get``
118+ Whether to validate on GET requests. By default only POST
119+ requests are validated.
120+
121+ Example::
122+
123+ class SomeController(BaseController):
124+
125+ def create(self, id):
126+ return render('/myform.mako')
127+
128+ @validate(schema=model.forms.myshema(), form='create')
129+ def update(self, id):
130+ # Do something with self.form_result
131+ pass
132+
133+ """
134+ if state is None:
135+ state = PylonsFormEncodeState
136+ def wrapper(func, self, *args, **kwargs):
137+ """Decorator Wrapper function"""
138+ request = self._py_object.request
139+ errors = {}
140+
141+ # Skip the validation if on_get is False and its a GET
142+ if not on_get and request.environ['REQUEST_METHOD'] == 'GET':
143+ return func(self, *args, **kwargs)
144+
145+ # If they want post args only, use just the post args
146+ if post_only:
147+ params = request.POST
148+ else:
149+ params = request.params
150+
151+ params = params.mixed()
152+ if variable_decode:
153+ log.debug("Running variable_decode on params")
154+ decoded = variabledecode.variable_decode(params, dict_char,
155+ list_char)
156+ else:
157+ decoded = params
158+
159+ if schema:
160+ log.debug("Validating against a schema")
161+ try:
162+ self.form_result = schema.to_python(decoded, state)
163+ except formencode.Invalid, e:
164+ errors = e.unpack_errors(variable_decode, dict_char, list_char)
165+ if validators:
166+ log.debug("Validating against provided validators")
167+ if isinstance(validators, dict):
168+ if not hasattr(self, 'form_result'):
169+ self.form_result = {}
170+ for field, validator in validators.iteritems():
171+ try:
172+ self.form_result[field] = \
173+ validator.to_python(decoded.get(field), state)
174+ except formencode.Invalid, error:
175+ errors[field] = error
176+ if errors:
177+ log.debug("Errors found in validation, parsing form with htmlfill "
178+ "for errors")
179+ request.environ['REQUEST_METHOD'] = 'GET'
180+ self._py_object.tmpl_context.form_errors = errors
181+
182+ # If there's no form supplied, just continue with the current
183+ # function call.
184+ if not form:
185+ return func(self, *args, **kwargs)
186+
187+ request.environ['pylons.routes_dict']['action'] = form
188+ response = self._dispatch_call()
189+
190+ # If the form_content is an exception response, return it
191+ if hasattr(response, '_exception'):
192+ return response
193+
194+ htmlfill_kwargs2 = htmlfill_kwargs.copy()
195+ htmlfill_kwargs2.setdefault('encoding', request.charset)
196+ return htmlfill.render(response, defaults=params, errors=errors,
197+ **htmlfill_kwargs2)
198+ return func(self, *args, **kwargs)
199+ return decorator(wrapper)
200+
201+
202+def pylons_formencode_gettext(value):
203+ """Translates a string ``value`` using pylons gettext first and if
204+ that fails, formencode gettext.
205+
206+ This allows to "merge" localized error messages from built-in
207+ FormEncode's validators with application-specific validators.
208+
209+ """
210+ trans = pylons_gettext(value)
211+ if trans == value:
212+ # translation failed, try formencode
213+ trans = api._stdtrans(value)
214+ return trans
215+
216+
217+class PylonsFormEncodeState(object):
218+ """A ``state`` for FormEncode validate API that includes smart
219+ ``_`` hook.
220+
221+ The FormEncode library used by validate() decorator has some
222+ provision for localizing error messages. In particular, it looks
223+ for attribute ``_`` in the application-specific state object that
224+ gets passed to every ``.to_python()`` call. If it is found, the
225+ ``_`` is assumed to be a gettext-like function and is called to
226+ localize error messages.
227+
228+ One complication is that FormEncode ships with localized error
229+ messages for standard validators so the user may want to re-use
230+ them instead of gathering and translating everything from scratch.
231+ To allow this, we pass as ``_`` a function which looks up
232+ translation both in application and formencode message catalogs.
233+
234+ """
235+ _ = staticmethod(pylons_formencode_gettext)
236
237=== added file '.pc/ipython_0.11_compatibility.patch/.timestamp'
238=== added file '.pc/move_data_outside_site-packages.patch/.timestamp'
239=== modified file 'debian/changelog'
240--- debian/changelog 2011-08-02 21:17:36 +0000
241+++ debian/changelog 2014-03-14 14:46:27 +0000
242@@ -1,3 +1,9 @@
243+pylons (1.0-3) unstable; urgency=low
244+
245+ * Add fix-useless-import.patch (closes: #1292505)
246+
247+ -- Samuel Cabrero <scabrero@zentyal.com> Fri, 14 Mar 2014 15:28:15 +0100
248+
249 pylons (1.0-2) unstable; urgency=low
250
251 * Add ipython_0.11_compatibility patch (thanks to Julian Taylor)
252
253=== added file 'debian/patches/fix-useless-import.patch'
254--- debian/patches/fix-useless-import.patch 1970-01-01 00:00:00 +0000
255+++ debian/patches/fix-useless-import.patch 2014-03-14 14:46:27 +0000
256@@ -0,0 +1,12 @@
257+Index: fix-useless-import/pylons/decorators/__init__.py
258+===================================================================
259+--- fix-useless-import.orig/pylons/decorators/__init__.py 2014-03-14 15:25:49.079736000 +0100
260++++ fix-useless-import/pylons/decorators/__init__.py 2014-03-14 15:26:55.106453748 +0100
261+@@ -14,7 +14,6 @@
262+ import simplejson
263+ from decorator import decorator
264+ from formencode import api, htmlfill, variabledecode
265+-from webob.multidict import UnicodeMultiDict
266+
267+ from pylons.decorators.util import get_pylons
268+ from pylons.i18n import _ as pylons_gettext
269
270=== modified file 'debian/patches/ipython_0.11_compatibility.patch'
271--- debian/patches/ipython_0.11_compatibility.patch 2011-08-02 21:17:36 +0000
272+++ debian/patches/ipython_0.11_compatibility.patch 2014-03-14 14:46:27 +0000
273@@ -1,8 +1,8 @@
274-Index: pylons-0.10/pylons/commands.py
275+Index: fix-useless-import/pylons/commands.py
276 ===================================================================
277---- pylons-0.10.orig/pylons/commands.py 2011-07-24 15:28:25.708719706 +0200
278-+++ pylons-0.10/pylons/commands.py 2011-07-24 15:28:31.848719709 +0200
279-@@ -514,10 +514,14 @@
280+--- fix-useless-import.orig/pylons/commands.py 2014-03-14 15:43:20.402418528 +0100
281++++ fix-useless-import/pylons/commands.py 2014-03-14 15:43:20.398418528 +0100
282+@@ -560,10 +560,14 @@
283 raise ImportError()
284
285 # try to use IPython if possible
286
287=== modified file 'debian/patches/move_data_outside_site-packages.patch'
288--- debian/patches/move_data_outside_site-packages.patch 2009-11-30 00:26:47 +0000
289+++ debian/patches/move_data_outside_site-packages.patch 2014-03-14 14:46:27 +0000
290@@ -3,11 +3,11 @@
291 # note that paster is modified in Debian to look for templates in
292 # /usr/share/paster_templates/ so this part of the code doesn't have to
293 # be patched
294-Index: pylons-0.9.7/setup.py
295+Index: fix-useless-import/setup.py
296 ===================================================================
297---- pylons-0.9.7.orig/setup.py
298-+++ pylons-0.9.7/setup.py
299-@@ -74,7 +74,7 @@ the `Pylons download page <http://pylons
300+--- fix-useless-import.orig/setup.py 2014-03-14 15:43:20.382418528 +0100
301++++ fix-useless-import/setup.py 2014-03-14 15:43:20.378418529 +0100
302+@@ -74,7 +74,7 @@
303 url='http://www.pylonshq.com/',
304 packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']),
305 zip_safe=False,
306@@ -16,11 +16,11 @@
307 test_suite='nose.collector',
308 tests_require=tests_require,
309 install_requires=[
310-Index: pylons-0.9.7/pylons/middleware.py
311+Index: fix-useless-import/pylons/middleware.py
312 ===================================================================
313---- pylons-0.9.7.orig/pylons/middleware.py
314-+++ pylons-0.9.7/pylons/middleware.py
315-@@ -24,7 +24,7 @@ __all__ = ['ErrorDocuments', 'ErrorHandl
316+--- fix-useless-import.orig/pylons/middleware.py 2014-03-14 15:43:20.382418528 +0100
317++++ fix-useless-import/pylons/middleware.py 2014-03-14 15:43:20.378418529 +0100
318+@@ -18,7 +18,7 @@
319
320 log = logging.getLogger(__name__)
321
322@@ -29,11 +29,11 @@
323
324 head_html = """\
325 <link rel="stylesheet" href="{{prefix}}/media/pylons/style/itraceback.css" \
326-Index: pylons-0.9.7/pylons/commands.py
327+Index: fix-useless-import/pylons/commands.py
328 ===================================================================
329---- pylons-0.9.7.orig/pylons/commands.py
330-+++ pylons-0.9.7/pylons/commands.py
331-@@ -169,7 +169,7 @@ class ControllerCommand(Command):
332+--- fix-useless-import.orig/pylons/commands.py 2014-03-14 15:43:20.382418528 +0100
333++++ fix-useless-import/pylons/commands.py 2014-03-14 15:43:29.000000000 +0100
334+@@ -170,7 +170,7 @@
335 def command(self):
336 """Main command to create controller"""
337 try:
338@@ -42,7 +42,7 @@
339 try:
340 name, directory = file_op.parse_path_name_args(self.args[0])
341 except:
342-@@ -276,7 +276,7 @@ class RestControllerCommand(Command):
343+@@ -279,7 +279,7 @@
344 def command(self):
345 """Main command to create controller"""
346 try:
347
348=== modified file 'debian/patches/series'
349--- debian/patches/series 2011-08-02 21:17:36 +0000
350+++ debian/patches/series 2014-03-14 14:46:27 +0000
351@@ -1,2 +1,3 @@
352 move_data_outside_site-packages.patch
353 ipython_0.11_compatibility.patch
354+fix-useless-import.patch
355
356=== modified file 'pylons/decorators/__init__.py'
357--- pylons/decorators/__init__.py 2011-08-02 21:17:36 +0000
358+++ pylons/decorators/__init__.py 2014-03-14 14:46:27 +0000
359@@ -14,7 +14,6 @@
360 import simplejson
361 from decorator import decorator
362 from formencode import api, htmlfill, variabledecode
363-from webob.multidict import UnicodeMultiDict
364
365 from pylons.decorators.util import get_pylons
366 from pylons.i18n import _ as pylons_gettext

Subscribers

People subscribed via source and target branches

to all changes: