mirror of
https://github.com/django/django.git
synced 2025-06-11 06:29:13 +00:00
fix: custom repr implementation for consistency with pprint
This commit is contained in:
parent
2a977f6705
commit
27dc608eb3
13
django/utils/repr.py
Normal file
13
django/utils/repr.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import reprlib
|
||||||
|
|
||||||
|
|
||||||
|
class DjangoRepr(reprlib.Repr):
|
||||||
|
|
||||||
|
def config(self, limit):
|
||||||
|
"""Sets maximum print length for all data structures using the given value"""
|
||||||
|
for attr in dir(self):
|
||||||
|
if attr.startswith("max") and attr != "maxlevel":
|
||||||
|
setattr(self, attr, limit)
|
||||||
|
|
||||||
|
def repr_str(self, x, level):
|
||||||
|
return x[: self.maxstring]
|
@ -2,7 +2,6 @@ import functools
|
|||||||
import inspect
|
import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
import reprlib
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
import warnings
|
import warnings
|
||||||
@ -18,6 +17,7 @@ from django.utils.datastructures import MultiValueDict
|
|||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
from django.utils.regex_helper import _lazy_re_compile
|
from django.utils.regex_helper import _lazy_re_compile
|
||||||
|
from django.utils.repr import DjangoRepr
|
||||||
from django.utils.version import PY311, get_docs_version
|
from django.utils.version import PY311, get_docs_version
|
||||||
from django.views.decorators.debug import coroutine_functions_to_sensitive_variables
|
from django.views.decorators.debug import coroutine_functions_to_sensitive_variables
|
||||||
|
|
||||||
@ -311,16 +311,8 @@ class SafeExceptionReporterFilter:
|
|||||||
class ExceptionReporter:
|
class ExceptionReporter:
|
||||||
"""Organize and coordinate reporting on exceptions."""
|
"""Organize and coordinate reporting on exceptions."""
|
||||||
|
|
||||||
repr_instance = reprlib.Repr()
|
repr_instance = DjangoRepr()
|
||||||
repr_instance.indent = 2
|
PRINT_LIMIT = 4096
|
||||||
repr_instance.maxdeque = 4096
|
|
||||||
repr_instance.maxstring = 4096
|
|
||||||
repr_instance.maxlist = 4096
|
|
||||||
repr_instance.maxset = 4096
|
|
||||||
repr_instance.maxdict = 4096
|
|
||||||
repr_instance.maxfrozenset = 4096
|
|
||||||
repr_instance.maxarray = 4096
|
|
||||||
repr_instance.maxother = 4096
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def html_template_path(self):
|
def html_template_path(self):
|
||||||
@ -342,6 +334,8 @@ class ExceptionReporter:
|
|||||||
self.template_does_not_exist = False
|
self.template_does_not_exist = False
|
||||||
self.postmortem = None
|
self.postmortem = None
|
||||||
|
|
||||||
|
self.repr_instance.config(limit=ExceptionReporter.PRINT_LIMIT)
|
||||||
|
|
||||||
def _get_raw_insecure_uri(self):
|
def _get_raw_insecure_uri(self):
|
||||||
"""
|
"""
|
||||||
Return an absolute URI from variables available in this request. Skip
|
Return an absolute URI from variables available in this request. Skip
|
||||||
@ -364,9 +358,22 @@ class ExceptionReporter:
|
|||||||
if "vars" in frame:
|
if "vars" in frame:
|
||||||
frame_vars = []
|
frame_vars = []
|
||||||
for k, v in frame["vars"]:
|
for k, v in frame["vars"]:
|
||||||
if isinstance(v, Sized) and len(v) > 4096:
|
try:
|
||||||
self.repr_instance.fillvalue = "...%d more" % (len(v) - 4096)
|
# Check if there are any exceptions in __repr__ fn of the object
|
||||||
v = self.repr_instance.repr(v)
|
v = repr(v)
|
||||||
|
|
||||||
|
trim_msg = ""
|
||||||
|
|
||||||
|
if isinstance(v, Sized) and len(v) > 4096:
|
||||||
|
diff = len(v) - 4096
|
||||||
|
trim_msg = "...<trimmed %d bytes string>" % diff
|
||||||
|
|
||||||
|
v = self.repr_instance.repr(v)
|
||||||
|
v += trim_msg
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
v = "Error in formatting: %s: %s" % (e.__class__.__name__, e)
|
||||||
|
print(v)
|
||||||
frame_vars.append((k, v))
|
frame_vars.append((k, v))
|
||||||
frame["vars"] = frame_vars
|
frame["vars"] = frame_vars
|
||||||
frames[i] = frame
|
frames[i] = frame
|
||||||
|
@ -1036,15 +1036,20 @@ class ExceptionReporterTests(SimpleTestCase):
|
|||||||
|
|
||||||
def test_local_variable_escaping(self):
|
def test_local_variable_escaping(self):
|
||||||
"""Safe strings in local variables are escaped."""
|
"""Safe strings in local variables are escaped."""
|
||||||
|
# <p>Local variable</p>\
|
||||||
|
# '<p>Local variable</p>'
|
||||||
try:
|
try:
|
||||||
local = mark_safe("<p>Local variable</p>")
|
local = mark_safe("<p>Local variable</p>")
|
||||||
|
print("safe string:", repr(local))
|
||||||
raise ValueError(local)
|
raise ValueError(local)
|
||||||
except Exception:
|
except Exception:
|
||||||
exc_type, exc_value, tb = sys.exc_info()
|
exc_type, exc_value, tb = sys.exc_info()
|
||||||
|
|
||||||
html = ExceptionReporter(None, exc_type, exc_value, tb).get_traceback_html()
|
html = ExceptionReporter(None, exc_type, exc_value, tb).get_traceback_html()
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
'<td class="code"><pre>'<p>Local variable</p>'</pre>'
|
# <td><pre><p>Local variable</p></pre></td>
|
||||||
"</td>",
|
# <td class="code"><pre><p>Local variable</p></pre></td>
|
||||||
|
'<td class="code"><pre>'<p>Local variable</p>'</pre>',
|
||||||
html,
|
html,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1066,7 +1071,7 @@ class ExceptionReporterTests(SimpleTestCase):
|
|||||||
|
|
||||||
def test_too_large_values_handling(self):
|
def test_too_large_values_handling(self):
|
||||||
"Large values should not create a large HTML."
|
"Large values should not create a large HTML."
|
||||||
large = 256 * 1024
|
large = 5000
|
||||||
repr_of_str_adds = len(repr(""))
|
repr_of_str_adds = len(repr(""))
|
||||||
try:
|
try:
|
||||||
|
|
||||||
@ -1081,9 +1086,10 @@ class ExceptionReporterTests(SimpleTestCase):
|
|||||||
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
|
reporter = ExceptionReporter(None, exc_type, exc_value, tb)
|
||||||
html = reporter.get_traceback_html()
|
html = reporter.get_traceback_html()
|
||||||
self.assertEqual(len(html) // 1024 // 128, 0) # still fit in 128Kb
|
self.assertEqual(len(html) // 1024 // 128, 0) # still fit in 128Kb
|
||||||
self.assertIn(
|
msg = "<trimmed %d bytes string>" % (
|
||||||
"<trimmed %d bytes string>" % (large + repr_of_str_adds,), html
|
large - ExceptionReporter.PRINT_LIMIT + repr_of_str_adds,
|
||||||
)
|
)
|
||||||
|
self.assertIn(msg, html)
|
||||||
|
|
||||||
def test_encoding_error(self):
|
def test_encoding_error(self):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user