Ticket #10107: patch.2.diff

File patch.2.diff, 5.0 KB (added by matehat, 15 years ago)
Line 
1Index: django/utils/safestring.py
2===================================================================
3--- django/utils/safestring.py (revision 9781)
4+++ django/utils/safestring.py (working copy)
5@@ -4,7 +4,7 @@
6 that the producer of the string has already turned characters that should not
7 be interpreted by the HTML engine (e.g. '<') into the appropriate entities.
8 """
9-from django.utils.functional import curry, Promise
10+from django.utils.functional import curry, wraps, Promise
11
12 class EscapeData(object):
13 pass
14@@ -86,13 +86,24 @@
15
16 encode = curry(_proxy_method, method = unicode.encode)
17
18-def mark_safe(s):
19+def _safety_decorator(safety_marker, func):
20+ @wraps(func)
21+ def wrapped(*args, **kwargs):
22+ return safety_marker(func(*args, **kwargs))
23+ return wrapped
24+
25+
26+def mark_safe(s=None):
27 """
28 Explicitly mark a string as safe for (HTML) output purposes. The returned
29 object can be used everywhere a string or unicode object is appropriate.
30
31 Can be called multiple times on a single string.
32 """
33+ if s is None: # Used like: @mark_safe()
34+ return curry(_safety_decorator, mark_safe)
35+ if callable(s): # Used like: @mark_safe
36+ return _safety_decorator(mark_safe, s)
37 if isinstance(s, SafeData):
38 return s
39 if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str):
40@@ -101,7 +112,7 @@
41 return SafeUnicode(s)
42 return SafeString(str(s))
43
44-def mark_for_escaping(s):
45+def mark_for_escaping(s=None):
46 """
47 Explicitly mark a string as requiring HTML escaping upon output. Has no
48 effect on SafeData subclasses.
49@@ -109,6 +120,11 @@
50 Can be called multiple times on a single string (the resulting escaping is
51 only applied once).
52 """
53+
54+ if s is None:
55+ return curry(_safety_decorator, mark_for_escaping)
56+ if callable(s):
57+ return _safety_decorator(mark_for_escaping, s)
58 if isinstance(s, (SafeData, EscapeData)):
59 return s
60 if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str):
61Index: tests/regressiontests/decorators/tests.py
62===================================================================
63--- tests/regressiontests/decorators/tests.py (revision 9781)
64+++ tests/regressiontests/decorators/tests.py (working copy)
65@@ -3,6 +3,7 @@
66
67from django.http import HttpResponse
68from django.utils.functional import allow_lazy, lazy, memoize
69+from django.utils.safestring import mark_safe, mark_for_escaping
70from django.views.decorators.http import require_http_methods, require_GET, require_POST
71from django.views.decorators.vary import vary_on_headers, vary_on_cookie
72from django.views.decorators.cache import cache_page, never_cache, cache_control
73@@ -14,6 +15,7 @@
74 return HttpResponse('<html><body>dummy</body></html>')
75fully_decorated.anything = "Expected __dict__"
76
77+
78# django.views.decorators.http
79fully_decorated = require_http_methods(["GET"])(fully_decorated)
80fully_decorated = require_GET(fully_decorated)
81@@ -41,8 +43,11 @@
82fully_decorated = allow_lazy(fully_decorated)
83fully_decorated = lazy(fully_decorated)
84
85+# django.utils.safestring
86+fully_decorated = mark_safe(fully_decorated)
87+fully_decorated = mark_for_escaping(fully_decorated)
88+
89class DecoratorsTest(TestCase):
90-
91 def test_attributes(self):
92 """
93 Tests that django decorators set certain attributes of the wrapped
94@@ -54,3 +59,37 @@
95 self.assertEquals(fully_decorated.__name__, 'fully_decorated')
96 self.assertEquals(fully_decorated.__doc__, 'Expected __doc__')
97 self.assertEquals(fully_decorated.__dict__['anything'], 'Expected __dict__')
98+
99+ def test_escaping(self):
100+ """
101+ Tests that safety markers from django.utils.safestring
102+ return the proper str or unicode subclass for use in templates.
103+
104+ Tests are done by comparing directly a sample rendered Template instance
105+ with the unicode content it should contain.
106+ """
107+ from django.template import Template, Context
108+ template = Template("{{ data }}")
109+
110+ rendered = { 'safe': u'<html><body>dummy</body></html>',
111+ 'escaped': u'&lt;html&gt;&lt;body&gt;dummy&lt;/body&gt;&lt;/html&gt;' }
112+ def clean_unicode_provider():
113+ return u'<html><body>dummy</body></html>'
114+
115+ def clean_string_provider():
116+ return '<html><body>dummy</body></html>'
117+
118+ escaped_unicode = mark_for_escaping(clean_unicode_provider)()
119+ safe_unicode = mark_safe(clean_unicode_provider)()
120+ escaped_str = mark_for_escaping(clean_string_provider)()
121+ safe_str = mark_safe(clean_string_provider)()
122+
123+ self.assertEquals(template.render(Context({'data': escaped_unicode})),
124+ rendered['escaped'])
125+ self.assertEquals(template.render(Context({'data': safe_unicode})),
126+ rendered['safe'])
127+ self.assertEquals(template.render(Context({'data': escaped_str})),
128+ rendered['escaped'])
129+ self.assertEquals(template.render(Context({'data': safe_str})),
130+ rendered['safe'])
131+
Back to Top