From b915b9f10f1110bf6b8468060ce9753ff78ffb07 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Wed, 24 Apr 2019 06:10:28 -0700 Subject: [PATCH] Refs #27753 -- Deprecated django.utils.text.unescape_entities(). The function was undocumented and only required for compatibility with Python 2. Code should use Python's html.unescape() that was added in Python 3.4. --- django/http/multipartparser.py | 4 ++-- django/utils/text.py | 7 +++++++ docs/internals/deprecation.txt | 2 ++ docs/releases/3.0.txt | 4 ++++ tests/utils_tests/test_text.py | 12 +++++++++++- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 96e22f69b9..fd8fce8b4d 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -8,6 +8,7 @@ import base64 import binascii import cgi import collections +import html from urllib.parse import unquote from django.conf import settings @@ -19,7 +20,6 @@ from django.core.files.uploadhandler import ( ) from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_str -from django.utils.text import unescape_entities __all__ = ('MultiPartParser', 'MultiPartParserError', 'InputStreamExhausted') @@ -209,7 +209,7 @@ class MultiPartParser: file_name = disposition.get('filename') if file_name: file_name = force_str(file_name, encoding, errors='replace') - file_name = self.IE_sanitize(unescape_entities(file_name)) + file_name = self.IE_sanitize(html.unescape(file_name)) if not file_name: continue diff --git a/django/utils/text.py b/django/utils/text.py index 44007beb0f..e9b7dcc72b 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -1,9 +1,11 @@ import html.entities import re import unicodedata +import warnings from gzip import GzipFile from io import BytesIO +from django.utils.deprecation import RemovedInDjango40Warning from django.utils.functional import SimpleLazyObject, keep_lazy_text, lazy from django.utils.translation import gettext as _, gettext_lazy, pgettext @@ -358,6 +360,11 @@ _entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") @keep_lazy_text def unescape_entities(text): + warnings.warn( + 'django.utils.text.unescape_entities() is deprecated in favor of ' + 'html.unescape().', + RemovedInDjango40Warning, stacklevel=2, + ) return _entity_re.sub(_replace_entity, str(text)) diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 93b6a04594..7020a3341a 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -30,6 +30,8 @@ details on these changes. * ``alias=None`` will be required in the signature of ``django.db.models.Expression.get_group_by_cols()`` subclasses. +* ``django.utils.text.unescape_entities()`` will be removed. + .. _deprecation-removed-in-3.1: 3.1 diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt index 1c222cfe7a..f43a11938a 100644 --- a/docs/releases/3.0.txt +++ b/docs/releases/3.0.txt @@ -411,6 +411,10 @@ Miscellaneous * ``alias=None`` is added to the signature of :meth:`.Expression.get_group_by_cols`. +* ``django.utils.text.unescape_entities()`` is deprecated in favor of + :func:`html.unescape`. Note that unlike ``unescape_entities()``, + ``html.unescape()`` evaluates lazy strings immediately. + .. _removed-features-3.0: Features removed in 3.0 diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py index 2d584c1cdd..ee04f3062c 100644 --- a/tests/utils_tests/test_text.py +++ b/tests/utils_tests/test_text.py @@ -1,8 +1,9 @@ import json import sys -from django.test import SimpleTestCase +from django.test import SimpleTestCase, ignore_warnings from django.utils import text +from django.utils.deprecation import RemovedInDjango40Warning from django.utils.functional import lazystr from django.utils.text import format_lazy from django.utils.translation import gettext_lazy, override @@ -184,6 +185,7 @@ class TestUtilsText(SimpleTestCase): # interning the result may be useful, e.g. when fed to Path. self.assertEqual(sys.intern(text.slugify('a')), 'a') + @ignore_warnings(category=RemovedInDjango40Warning) def test_unescape_entities(self): items = [ ('', ''), @@ -200,6 +202,14 @@ class TestUtilsText(SimpleTestCase): self.assertEqual(text.unescape_entities(value), output) self.assertEqual(text.unescape_entities(lazystr(value)), output) + def test_unescape_entities_deprecated(self): + msg = ( + 'django.utils.text.unescape_entities() is deprecated in favor of ' + 'html.unescape().' + ) + with self.assertWarnsMessage(RemovedInDjango40Warning, msg): + text.unescape_entities('foo') + def test_unescape_string_literal(self): items = [ ('"abc"', 'abc'),