Refs #27753 -- Favored SafeString over SafeText.
This commit is contained in:
parent
d55e882927
commit
77d25dbd0f
|
@ -13,7 +13,7 @@ from django.db import connections
|
||||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||||
from django.db.utils import DatabaseError as WrappedDatabaseError
|
from django.db.utils import DatabaseError as WrappedDatabaseError
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeString
|
||||||
from django.utils.version import get_version_tuple
|
from django.utils.version import get_version_tuple
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -44,7 +44,7 @@ from .operations import DatabaseOperations # NOQA isort:skip
|
||||||
from .schema import DatabaseSchemaEditor # NOQA isort:skip
|
from .schema import DatabaseSchemaEditor # NOQA isort:skip
|
||||||
from .utils import utc_tzinfo_factory # NOQA isort:skip
|
from .utils import utc_tzinfo_factory # NOQA isort:skip
|
||||||
|
|
||||||
psycopg2.extensions.register_adapter(SafeText, psycopg2.extensions.QuotedString)
|
psycopg2.extensions.register_adapter(SafeString, psycopg2.extensions.QuotedString)
|
||||||
psycopg2.extras.register_uuid()
|
psycopg2.extras.register_uuid()
|
||||||
|
|
||||||
# Register support for inet[] manually so we don't have to handle the Inet()
|
# Register support for inet[] manually so we don't have to handle the Inet()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.middleware.csrf import get_token
|
from django.middleware.csrf import get_token
|
||||||
from django.utils.functional import lazy
|
from django.utils.functional import lazy
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeString
|
||||||
|
|
||||||
|
|
||||||
def csrf_input(request):
|
def csrf_input(request):
|
||||||
|
@ -10,5 +10,5 @@ def csrf_input(request):
|
||||||
get_token(request))
|
get_token(request))
|
||||||
|
|
||||||
|
|
||||||
csrf_input_lazy = lazy(csrf_input, SafeText, str)
|
csrf_input_lazy = lazy(csrf_input, SafeString, str)
|
||||||
csrf_token_lazy = lazy(get_token, str)
|
csrf_token_lazy = lazy(get_token, str)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from urllib.parse import (
|
||||||
|
|
||||||
from django.utils.functional import Promise, keep_lazy, keep_lazy_text
|
from django.utils.functional import Promise, keep_lazy, keep_lazy_text
|
||||||
from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS
|
from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS
|
||||||
from django.utils.safestring import SafeData, SafeText, mark_safe
|
from django.utils.safestring import SafeData, SafeString, mark_safe
|
||||||
from django.utils.text import normalize_newlines
|
from django.utils.text import normalize_newlines
|
||||||
|
|
||||||
# Configuration for urlize() function.
|
# Configuration for urlize() function.
|
||||||
|
@ -33,7 +33,7 @@ _html_escapes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy(str, SafeText)
|
@keep_lazy(str, SafeString)
|
||||||
def escape(text):
|
def escape(text):
|
||||||
"""
|
"""
|
||||||
Return the given text with ampersands, quotes and angle brackets encoded
|
Return the given text with ampersands, quotes and angle brackets encoded
|
||||||
|
@ -65,7 +65,7 @@ _js_escapes = {
|
||||||
_js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32))
|
_js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32))
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy(str, SafeText)
|
@keep_lazy(str, SafeString)
|
||||||
def escapejs(value):
|
def escapejs(value):
|
||||||
"""Hex encode characters for use in JavaScript strings."""
|
"""Hex encode characters for use in JavaScript strings."""
|
||||||
return mark_safe(str(value).translate(_js_escapes))
|
return mark_safe(str(value).translate(_js_escapes))
|
||||||
|
@ -372,7 +372,7 @@ def avoid_wrapping(value):
|
||||||
def html_safe(klass):
|
def html_safe(klass):
|
||||||
"""
|
"""
|
||||||
A decorator that defines the __html__ method. This helps non-Django
|
A decorator that defines the __html__ method. This helps non-Django
|
||||||
templates to detect classes whose __str__ methods return SafeText.
|
templates to detect classes whose __str__ methods return SafeString.
|
||||||
"""
|
"""
|
||||||
if '__html__' in klass.__dict__:
|
if '__html__' in klass.__dict__:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
|
|
|
@ -18,7 +18,7 @@ class SafeData:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class SafeText(str, SafeData):
|
class SafeString(str, SafeData):
|
||||||
"""
|
"""
|
||||||
A str subclass that has been specifically marked as "safe" for HTML output
|
A str subclass that has been specifically marked as "safe" for HTML output
|
||||||
purposes.
|
purposes.
|
||||||
|
@ -30,14 +30,14 @@ class SafeText(str, SafeData):
|
||||||
"""
|
"""
|
||||||
t = super().__add__(rhs)
|
t = super().__add__(rhs)
|
||||||
if isinstance(rhs, SafeData):
|
if isinstance(rhs, SafeData):
|
||||||
return SafeText(t)
|
return SafeString(t)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
SafeString = SafeText
|
SafeText = SafeString # For backwards compatibility since Django 2.0.
|
||||||
|
|
||||||
|
|
||||||
def _safety_decorator(safety_marker, func):
|
def _safety_decorator(safety_marker, func):
|
||||||
|
@ -60,4 +60,4 @@ def mark_safe(s):
|
||||||
return s
|
return s
|
||||||
if callable(s):
|
if callable(s):
|
||||||
return _safety_decorator(mark_safe, s)
|
return _safety_decorator(mark_safe, s)
|
||||||
return SafeText(s)
|
return SafeString(s)
|
||||||
|
|
|
@ -200,12 +200,12 @@ passed around inside the template code:
|
||||||
to be interpreted as-is on the client side.
|
to be interpreted as-is on the client side.
|
||||||
|
|
||||||
Internally, these strings are of type
|
Internally, these strings are of type
|
||||||
:class:`~django.utils.safestring.SafeText`. You can test for them
|
:class:`~django.utils.safestring.SafeString`. You can test for them
|
||||||
using code like::
|
using code like::
|
||||||
|
|
||||||
from django.utils.safestring import SafeText
|
from django.utils.safestring import SafeString
|
||||||
|
|
||||||
if isinstance(value, SafeText):
|
if isinstance(value, SafeString):
|
||||||
# Do something with the "safe" string.
|
# Do something with the "safe" string.
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
|
@ -748,14 +748,8 @@ appropriate entities.
|
||||||
|
|
||||||
.. class:: SafeString
|
.. class:: SafeString
|
||||||
|
|
||||||
A ``str`` subclass that has been specifically marked as "safe"
|
A ``str`` subclass that has been specifically marked as "safe" (requires no
|
||||||
(requires no further escaping) for HTML output purposes. Alias of
|
further escaping) for HTML output purposes.
|
||||||
:class:`SafeText`.
|
|
||||||
|
|
||||||
.. class:: SafeText
|
|
||||||
|
|
||||||
A ``str`` subclass that has been specifically marked as "safe" for HTML
|
|
||||||
output purposes.
|
|
||||||
|
|
||||||
.. function:: mark_safe(s)
|
.. function:: mark_safe(s)
|
||||||
|
|
||||||
|
@ -774,7 +768,7 @@ appropriate entities.
|
||||||
>>> mystr = '<b>Hello World</b> '
|
>>> mystr = '<b>Hello World</b> '
|
||||||
>>> mystr = mark_safe(mystr)
|
>>> mystr = mark_safe(mystr)
|
||||||
>>> type(mystr)
|
>>> type(mystr)
|
||||||
<class 'django.utils.safestring.SafeText'>
|
<class 'django.utils.safestring.SafeString'>
|
||||||
|
|
||||||
>>> mystr = mystr.strip() # removing whitespace
|
>>> mystr = mystr.strip() # removing whitespace
|
||||||
>>> type(mystr)
|
>>> type(mystr)
|
||||||
|
|
|
@ -28,7 +28,7 @@ from django.utils.formats import (
|
||||||
localize_input, reset_format_cache, sanitize_separators, time_format,
|
localize_input, reset_format_cache, sanitize_separators, time_format,
|
||||||
)
|
)
|
||||||
from django.utils.numberformat import format as nformat
|
from django.utils.numberformat import format as nformat
|
||||||
from django.utils.safestring import SafeText, mark_safe
|
from django.utils.safestring import SafeString, mark_safe
|
||||||
from django.utils.translation import (
|
from django.utils.translation import (
|
||||||
LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate,
|
LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate,
|
||||||
get_language, get_language_bidi, get_language_from_request,
|
get_language, get_language_bidi, get_language_from_request,
|
||||||
|
@ -287,10 +287,10 @@ class TranslationTests(SimpleTestCase):
|
||||||
s1 = mark_safe('Password')
|
s1 = mark_safe('Password')
|
||||||
s2 = mark_safe('May')
|
s2 = mark_safe('May')
|
||||||
with translation.override('de', deactivate=True):
|
with translation.override('de', deactivate=True):
|
||||||
self.assertIs(type(gettext(s1)), SafeText)
|
self.assertIs(type(gettext(s1)), SafeString)
|
||||||
self.assertIs(type(pgettext('month name', s2)), SafeText)
|
self.assertIs(type(pgettext('month name', s2)), SafeString)
|
||||||
self.assertEqual('aPassword', SafeText('a') + s1)
|
self.assertEqual('aPassword', SafeString('a') + s1)
|
||||||
self.assertEqual('Passworda', s1 + SafeText('a'))
|
self.assertEqual('Passworda', s1 + SafeString('a'))
|
||||||
self.assertEqual('Passworda', s1 + mark_safe('a'))
|
self.assertEqual('Passworda', s1 + mark_safe('a'))
|
||||||
self.assertEqual('aPassword', mark_safe('a') + s1)
|
self.assertEqual('aPassword', mark_safe('a') + s1)
|
||||||
self.assertEqual('as', mark_safe('a') + mark_safe('s'))
|
self.assertEqual('as', mark_safe('a') + mark_safe('s'))
|
||||||
|
@ -1532,7 +1532,7 @@ class TestModels(TestCase):
|
||||||
|
|
||||||
def test_safestr(self):
|
def test_safestr(self):
|
||||||
c = Company(cents_paid=12, products_delivered=1)
|
c = Company(cents_paid=12, products_delivered=1)
|
||||||
c.name = SafeText('Iñtërnâtiônàlizætiøn1')
|
c.name = SafeString('Iñtërnâtiônàlizætiøn1')
|
||||||
c.save()
|
c.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class SafeStringTest(SimpleTestCase):
|
||||||
|
|
||||||
def test_mark_safe_str(self):
|
def test_mark_safe_str(self):
|
||||||
"""
|
"""
|
||||||
Calling str() on a SafeText instance doesn't lose the safe status.
|
Calling str() on a SafeString instance doesn't lose the safe status.
|
||||||
"""
|
"""
|
||||||
s = mark_safe('a&b')
|
s = mark_safe('a&b')
|
||||||
self.assertIsInstance(str(s), type(s))
|
self.assertIsInstance(str(s), type(s))
|
||||||
|
|
Loading…
Reference in New Issue