summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeryn Knight <keryn@kerynknight.com>2022-01-25 09:53:03 +0000
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-01-29 13:50:34 +0100
commit55022f75c1e76e92206e023a127532d97cedd5b7 (patch)
tree18bf8e2360c74fe8ca5737a901379bd23f148dd7
parent67db54a5a7e0f1c2aa395e1db51214d09ae41f3f (diff)
Fixed #33465 -- Added empty __slots__ to SafeString and SafeData.
Despite inheriting from the str type, every SafeString instance gains an empty __dict__ due to the normal, expected behaviour of type subclassing in Python. Adding __slots__ to SafeData is necessary, because otherwise inheriting from that (as SafeString does) will give it a __dict__ and negate the benefit added by modifying SafeString.
-rw-r--r--django/utils/safestring.py5
-rw-r--r--tests/utils_tests/test_safestring.py14
2 files changed, 18 insertions, 1 deletions
diff --git a/django/utils/safestring.py b/django/utils/safestring.py
index a484f678e2..c061717889 100644
--- a/django/utils/safestring.py
+++ b/django/utils/safestring.py
@@ -9,6 +9,8 @@ from functools import wraps
class SafeData:
+ __slots__ = ()
+
def __html__(self):
"""
Return the html representation of a string for interoperability.
@@ -23,6 +25,9 @@ class SafeString(str, SafeData):
A str subclass that has been specifically marked as "safe" for HTML output
purposes.
"""
+
+ __slots__ = ()
+
def __add__(self, rhs):
"""
Concatenating a safe string with another safe bytestring or
diff --git a/tests/utils_tests/test_safestring.py b/tests/utils_tests/test_safestring.py
index 2eeddb0571..80f31d42ac 100644
--- a/tests/utils_tests/test_safestring.py
+++ b/tests/utils_tests/test_safestring.py
@@ -2,7 +2,7 @@ from django.template import Context, Template
from django.test import SimpleTestCase
from django.utils import html
from django.utils.functional import lazy, lazystr
-from django.utils.safestring import SafeData, mark_safe
+from django.utils.safestring import SafeData, SafeString, mark_safe
class customescape(str):
@@ -98,3 +98,15 @@ class SafeStringTest(SimpleTestCase):
lazy_str = lazy(html_str, str)()
self.assertEqual(mark_safe(lazy_str), html_str())
+
+ def test_default_additional_attrs(self):
+ s = SafeString('a&b')
+ msg = "object has no attribute 'dynamic_attr'"
+ with self.assertRaisesMessage(AttributeError, msg):
+ s.dynamic_attr = True
+
+ def test_default_safe_data_additional_attrs(self):
+ s = SafeData()
+ msg = "object has no attribute 'dynamic_attr'"
+ with self.assertRaisesMessage(AttributeError, msg):
+ s.dynamic_attr = True