From f6a198fe60ffd9b6d36380da05fafe48f26ffede Mon Sep 17 00:00:00 2001 From: Keerthi Vasan Date: Fri, 23 Feb 2024 22:29:42 +0530 Subject: [PATCH] fix: apply suggested changes, move to text module --- django/template/defaultfilters.py | 17 ++++++------- django/utils/repr.py | 26 ------------------- django/utils/text.py | 37 ++++++++++++++++++++++++++++ tests/view_tests/tests/test_debug.py | 4 +-- 4 files changed, 47 insertions(+), 37 deletions(-) delete mode 100644 django/utils/repr.py diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index 631dd6908f..efa6627ed2 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -17,9 +17,8 @@ from django.utils.html import avoid_wrapping, conditional_escape, escape, escape from django.utils.html import json_script as _json_script from django.utils.html import linebreaks, strip_tags from django.utils.html import urlize as _urlize -from django.utils.repr import DjangoRepr from django.utils.safestring import SafeData, mark_safe -from django.utils.text import Truncator, normalize_newlines, phone2numeric +from django.utils.text import DebugRepr, Truncator, normalize_newlines, phone2numeric from django.utils.text import slugify as _slugify from django.utils.text import wrap from django.utils.timesince import timesince, timeuntil @@ -975,16 +974,16 @@ def phone2numeric_filter(value): @register.filter(is_safe=True) def pprint(value): - repr_instance = DjangoRepr() - repr_instance.config(limit=EXCEPTION_PRINT_LIMIT) + """A wrapper with custom Repr implementation for debugging.""" + repr_instance = DebugRepr(limit=EXCEPTION_PRINT_LIMIT) try: - if isinstance(v, Sized) and len(v) > EXCEPTION_PRINT_LIMIT: - diff = len(v) - EXCEPTION_PRINT_LIMIT + if isinstance(value, Sized) and len(value) > EXCEPTION_PRINT_LIMIT: + diff = len(value) - EXCEPTION_PRINT_LIMIT repr_instance.fillvalue = "..." % diff - v = repr_instance.repr(v) + value = repr_instance.repr(value) except Exception as e: - v = "Error in formatting: %s: %s" % (e.__class__.__name__, e) + value = "Error in formatting: %s: %s" % (e.__class__.__name__, e) - return v + return value diff --git a/django/utils/repr.py b/django/utils/repr.py deleted file mode 100644 index 07fb4369c4..0000000000 --- a/django/utils/repr.py +++ /dev/null @@ -1,26 +0,0 @@ -import builtins -import reprlib - - -class DjangoRepr(reprlib.Repr): - - def config(self, limit): - """Set maximum print length for all data structures to `limit`.""" - self.limit = limit - for attr in dir(self): - if attr.startswith("max") and attr != "maxlevel": - setattr(self, attr, limit) - - def repr_str(self, x, level): - return "'%s'" % (x[: self.maxstring] + self.gen_trim_msg(len(x))) - - def repr_instance(self, x, level): - s = builtins.repr(x) - if len(s) > self.maxother: - return s[: self.maxother] + self.gen_trim_msg(len(s)) - return s - - def gen_trim_msg(self, length): - if length <= self.limit: - return "" - return "..." % (length - self.limit) diff --git a/django/utils/text.py b/django/utils/text.py index 295f919b51..0974e71c12 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -1,5 +1,7 @@ +import builtins import gzip import re +import reprlib import secrets import unicodedata from gzip import GzipFile @@ -469,3 +471,38 @@ def _format_lazy(format_string, *args, **kwargs): format_lazy = lazy(_format_lazy, str) + + +class DebugRepr(reprlib.Repr): + + def __init__(self, limit): + """Sets maximum print length for all data structures using the given value""" + self.maxlevel = limit + self.maxtuple = limit + self.maxlist = limit + self.maxarray = limit + self.maxdict = limit + self.maxset = limit + self.maxfrozenset = limit + self.maxdeque = limit + self.maxstring = limit + self.maxlong = limit + self.maxother = limit + self.limit = limit + + self.fillvalue = "" + self.indent = 2 + + def repr_str(self, x, level): + return "'%s'" % (x[: self.maxstring] + self.gen_trim_msg(len(x))) + + def repr_instance(self, x, level): + s = builtins.repr(x) + if len(s) > self.maxother: + return s[: self.maxother] + self.gen_trim_msg(len(s)) + return s + + def gen_trim_msg(self, length): + if length <= self.limit: + return "" + return "..." % (length - self.limit) diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 733e273c30..cb7016bc13 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -1037,7 +1037,6 @@ class ExceptionReporterTests(SimpleTestCase): def test_local_variable_escaping(self): """Safe strings in local variables are escaped.""" - try: local = mark_safe("

Local variable

") raise ValueError(local) @@ -1047,7 +1046,8 @@ class ExceptionReporterTests(SimpleTestCase): html = ExceptionReporter(None, exc_type, exc_value, tb).get_traceback_html() self.assertIn( - '
'<p>Local variable</p>'
', + '
'<p>Local variable</p>'
' + "", html, )