Loading django/utils/safestring.py +12 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ import warnings from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import Promise, curry from django.utils.functional import Promise, curry, wraps class EscapeData(object): Loading Loading @@ -117,11 +117,20 @@ else: SafeUnicode = SafeText def _safety_decorator(safety_marker, func): @wraps(func) def wrapped(*args, **kwargs): return safety_marker(func(*args, **kwargs)) return wrapped def mark_safe(s): """ Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string or unicode object is appropriate. If used on a method as a decorator, mark the returned data as safe. Can be called multiple times on a single string. """ if hasattr(s, '__html__'): Loading @@ -130,6 +139,8 @@ def mark_safe(s): return SafeBytes(s) if isinstance(s, (six.text_type, Promise)): return SafeText(s) if callable(s): return _safety_decorator(mark_safe, s) return SafeString(str(s)) Loading docs/ref/utils.txt +6 −0 Original line number Diff line number Diff line Loading @@ -832,6 +832,8 @@ appropriate entities. Can be called multiple times on a single string. Can also be used as a decorator. For building up fragments of HTML, you should normally be using :func:`django.utils.html.format_html` instead. Loading @@ -846,6 +848,10 @@ appropriate entities. >>> type(mystr) <type 'str'> .. versionchanged:: 1.11 Added support for decorator usage. .. function:: mark_for_escaping(s) .. deprecated:: 1.10 Loading docs/releases/1.11.txt +1 −1 Original line number Diff line number Diff line Loading @@ -202,7 +202,7 @@ Signals Templates ~~~~~~~~~ * ... * :meth:`~django.utils.safestring.mark_safe` can now be used as a decorator. Tests ~~~~~ Loading tests/decorators/tests.py +4 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ from django.utils.decorators import method_decorator from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.functional import allow_lazy, keep_lazy, keep_lazy_text, lazy from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy from django.views.decorators.cache import ( cache_control, cache_page, never_cache, Loading Loading @@ -74,6 +75,9 @@ full_decorator = compose( keep_lazy(HttpResponse), keep_lazy_text, lazy, # django.utils.safestring mark_safe, ) fully_decorated = full_decorator(fully_decorated) Loading tests/utils_tests/test_safestring.py +30 −0 Original line number Diff line number Diff line Loading @@ -109,3 +109,33 @@ class SafeStringTest(SimpleTestCase): s = text.slugify(lazystr('a')) s += mark_safe('&b') self.assertRenderEqual('{{ s }}', 'a&b', s=s) def test_mark_safe_as_decorator(self): """ mark_safe used as a decorator leaves the result of a function unchanged. """ def clean_string_provider(): return '<html><body>dummy</body></html>' self.assertEqual(mark_safe(clean_string_provider)(), clean_string_provider()) def test_mark_safe_decorator_does_not_affect_dunder_html(self): """ mark_safe doesn't affect a callable that has an __html__() method. """ class SafeStringContainer: def __html__(self): return '<html></html>' self.assertIs(mark_safe(SafeStringContainer), SafeStringContainer) def test_mark_safe_decorator_does_not_affect_promises(self): """ mark_safe doesn't affect lazy strings (Promise objects). """ def html_str(): return '<html></html>' lazy_str = lazy(html_str, str)() self.assertEqual(mark_safe(lazy_str), html_str()) Loading
django/utils/safestring.py +12 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ import warnings from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning from django.utils.functional import Promise, curry from django.utils.functional import Promise, curry, wraps class EscapeData(object): Loading Loading @@ -117,11 +117,20 @@ else: SafeUnicode = SafeText def _safety_decorator(safety_marker, func): @wraps(func) def wrapped(*args, **kwargs): return safety_marker(func(*args, **kwargs)) return wrapped def mark_safe(s): """ Explicitly mark a string as safe for (HTML) output purposes. The returned object can be used everywhere a string or unicode object is appropriate. If used on a method as a decorator, mark the returned data as safe. Can be called multiple times on a single string. """ if hasattr(s, '__html__'): Loading @@ -130,6 +139,8 @@ def mark_safe(s): return SafeBytes(s) if isinstance(s, (six.text_type, Promise)): return SafeText(s) if callable(s): return _safety_decorator(mark_safe, s) return SafeString(str(s)) Loading
docs/ref/utils.txt +6 −0 Original line number Diff line number Diff line Loading @@ -832,6 +832,8 @@ appropriate entities. Can be called multiple times on a single string. Can also be used as a decorator. For building up fragments of HTML, you should normally be using :func:`django.utils.html.format_html` instead. Loading @@ -846,6 +848,10 @@ appropriate entities. >>> type(mystr) <type 'str'> .. versionchanged:: 1.11 Added support for decorator usage. .. function:: mark_for_escaping(s) .. deprecated:: 1.10 Loading
docs/releases/1.11.txt +1 −1 Original line number Diff line number Diff line Loading @@ -202,7 +202,7 @@ Signals Templates ~~~~~~~~~ * ... * :meth:`~django.utils.safestring.mark_safe` can now be used as a decorator. Tests ~~~~~ Loading
tests/decorators/tests.py +4 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ from django.utils.decorators import method_decorator from django.utils.deprecation import RemovedInDjango20Warning from django.utils.encoding import force_text from django.utils.functional import allow_lazy, keep_lazy, keep_lazy_text, lazy from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy from django.views.decorators.cache import ( cache_control, cache_page, never_cache, Loading Loading @@ -74,6 +75,9 @@ full_decorator = compose( keep_lazy(HttpResponse), keep_lazy_text, lazy, # django.utils.safestring mark_safe, ) fully_decorated = full_decorator(fully_decorated) Loading
tests/utils_tests/test_safestring.py +30 −0 Original line number Diff line number Diff line Loading @@ -109,3 +109,33 @@ class SafeStringTest(SimpleTestCase): s = text.slugify(lazystr('a')) s += mark_safe('&b') self.assertRenderEqual('{{ s }}', 'a&b', s=s) def test_mark_safe_as_decorator(self): """ mark_safe used as a decorator leaves the result of a function unchanged. """ def clean_string_provider(): return '<html><body>dummy</body></html>' self.assertEqual(mark_safe(clean_string_provider)(), clean_string_provider()) def test_mark_safe_decorator_does_not_affect_dunder_html(self): """ mark_safe doesn't affect a callable that has an __html__() method. """ class SafeStringContainer: def __html__(self): return '<html></html>' self.assertIs(mark_safe(SafeStringContainer), SafeStringContainer) def test_mark_safe_decorator_does_not_affect_promises(self): """ mark_safe doesn't affect lazy strings (Promise objects). """ def html_str(): return '<html></html>' lazy_str = lazy(html_str, str)() self.assertEqual(mark_safe(lazy_str), html_str())