1
0
mirror of https://github.com/django/django.git synced 2025-06-06 12:09:11 +00:00

Fixed #35998 -- Added caching to django.utils.html.urlize().

This commit is contained in:
Sarah Boyce 2024-10-11 13:44:12 +02:00
parent d206d4c200
commit b721f12760
2 changed files with 45 additions and 6 deletions

View File

@ -317,18 +317,20 @@ class Urlizer:
safe_input = isinstance(text, SafeData) safe_input = isinstance(text, SafeData)
words = self.word_split_re.split(str(text)) words = self.word_split_re.split(str(text))
return "".join( local_cache = {}
[ urlized_words = []
self.handle_word( for word in words:
if (urlized_word := local_cache.get(word)) is None:
urlized_word = self.handle_word(
word, word,
safe_input=safe_input, safe_input=safe_input,
trim_url_limit=trim_url_limit, trim_url_limit=trim_url_limit,
nofollow=nofollow, nofollow=nofollow,
autoescape=autoescape, autoescape=autoescape,
) )
for word in words local_cache[word] = urlized_word
] urlized_words.append(urlized_word)
) return "".join(urlized_words)
def handle_word( def handle_word(
self, self,

View File

@ -1,6 +1,9 @@
from unittest import mock
from django.template.defaultfilters import urlize from django.template.defaultfilters import urlize
from django.test import SimpleTestCase from django.test import SimpleTestCase
from django.utils.functional import lazy from django.utils.functional import lazy
from django.utils.html import Urlizer
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from ..utils import setup from ..utils import setup
@ -467,3 +470,37 @@ class FunctionTests(SimpleTestCase):
urlize(prepend_www("google.com")), urlize(prepend_www("google.com")),
'<a href="http://www.google.com" rel="nofollow">www.google.com</a>', '<a href="http://www.google.com" rel="nofollow">www.google.com</a>',
) )
@mock.patch.object(Urlizer, "handle_word", return_value="test")
def test_caching_repeated_words(self, mock_handle_word):
urlize("test test test test")
common_handle_word_args = {
"safe_input": False,
"trim_url_limit": None,
"nofollow": True,
"autoescape": True,
}
self.assertEqual(
mock_handle_word.mock_calls,
[
mock.call("test", **common_handle_word_args),
mock.call(" ", **common_handle_word_args),
],
)
@mock.patch.object(Urlizer, "handle_word", return_value="test")
def test_caching_repeated_calls(self, mock_handle_word):
urlize("test")
handle_word_test = mock.call(
"test",
safe_input=False,
trim_url_limit=None,
nofollow=True,
autoescape=True,
)
self.assertEqual(mock_handle_word.mock_calls, [handle_word_test])
urlize("test")
self.assertEqual(
mock_handle_word.mock_calls, [handle_word_test, handle_word_test]
)