diff options
| author | Jon Dufresne <jon.dufresne@gmail.com> | 2019-04-24 04:30:34 -0700 |
|---|---|---|
| committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2019-04-25 15:09:07 +0200 |
| commit | 8d76443aba863b75ad3b1392ca7e1d59bad84dc4 (patch) | |
| tree | 1e550f8ebb06a935bd8a15496d049f54c54eded2 | |
| parent | 28d5262fa3315690395f04e3619ed554dbaf725b (diff) | |
Fixed #30399 -- Changed django.utils.html.escape()/urlize() to use html.escape()/unescape().
| -rw-r--r-- | django/utils/html.py | 26 | ||||
| -rw-r--r-- | docs/intro/tutorial05.txt | 2 | ||||
| -rw-r--r-- | docs/ref/templates/builtins.txt | 2 | ||||
| -rw-r--r-- | docs/ref/templates/language.txt | 2 | ||||
| -rw-r--r-- | docs/ref/utils.txt | 5 | ||||
| -rw-r--r-- | docs/releases/3.0.txt | 4 | ||||
| -rw-r--r-- | tests/admin_docs/test_views.py | 2 | ||||
| -rw-r--r-- | tests/auth_tests/test_forms.py | 2 | ||||
| -rw-r--r-- | tests/forms_tests/tests/test_forms.py | 10 | ||||
| -rw-r--r-- | tests/forms_tests/widget_tests/base.py | 5 | ||||
| -rw-r--r-- | tests/forms_tests/widget_tests/test_clearablefileinput.py | 2 | ||||
| -rw-r--r-- | tests/model_forms/tests.py | 14 | ||||
| -rw-r--r-- | tests/template_tests/filter_tests/test_addslashes.py | 2 | ||||
| -rw-r--r-- | tests/template_tests/filter_tests/test_make_list.py | 2 | ||||
| -rw-r--r-- | tests/template_tests/filter_tests/test_title.py | 2 | ||||
| -rw-r--r-- | tests/template_tests/filter_tests/test_urlize.py | 6 | ||||
| -rw-r--r-- | tests/template_tests/syntax_tests/test_url.py | 2 | ||||
| -rw-r--r-- | tests/utils_tests/test_html.py | 4 | ||||
| -rw-r--r-- | tests/view_tests/tests/test_csrf.py | 8 | ||||
| -rw-r--r-- | tests/view_tests/tests/test_debug.py | 14 |
20 files changed, 57 insertions, 59 deletions
diff --git a/django/utils/html.py b/django/utils/html.py index 9c519978f5..b26cbd16b8 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -1,5 +1,6 @@ """HTML utilities suitable for global use.""" +import html import json import re from html.parser import HTMLParser @@ -24,14 +25,6 @@ word_split_re = re.compile(r'''([\s<>"']+)''') simple_url_re = re.compile(r'^https?://\[?\w', re.IGNORECASE) simple_url_2_re = re.compile(r'^www\.|^(?!http)\w[^@]+\.(com|edu|gov|int|mil|net|org)($|/.*)$', re.IGNORECASE) -_html_escapes = { - ord('&'): '&', - ord('<'): '<', - ord('>'): '>', - ord('"'): '"', - ord("'"): ''', -} - @keep_lazy(str, SafeString) def escape(text): @@ -43,7 +36,7 @@ def escape(text): This may result in double-escaping. If this is a concern, use conditional_escape() instead. """ - return mark_safe(str(text).translate(_html_escapes)) + return mark_safe(html.escape(str(text))) _js_escapes = { @@ -259,15 +252,6 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): return x return '%s…' % x[:max(0, limit - 1)] - def unescape(text): - """ - If input URL is HTML-escaped, unescape it so that it can be safely fed - to smart_urlquote. For example: - http://example.com?x=1&y=<2> => http://example.com?x=1&y=<2> - """ - return text.replace('&', '&').replace('<', '<').replace( - '>', '>').replace('"', '"').replace(''', "'") - def trim_punctuation(lead, middle, trail): """ Trim trailing and wrapping punctuation from `middle`. Return the items @@ -292,7 +276,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): # Trim trailing punctuation (after trimming wrapping punctuation, # as encoded entities contain ';'). Unescape entites to avoid # breaking them by removing ';'. - middle_unescaped = unescape(middle) + middle_unescaped = html.unescape(middle) stripped = middle_unescaped.rstrip(TRAILING_PUNCTUATION_CHARS) if middle_unescaped != stripped: trail = middle[len(stripped):] + trail @@ -329,9 +313,9 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): url = None nofollow_attr = ' rel="nofollow"' if nofollow else '' if simple_url_re.match(middle): - url = smart_urlquote(unescape(middle)) + url = smart_urlquote(html.unescape(middle)) elif simple_url_2_re.match(middle): - url = smart_urlquote('http://%s' % unescape(middle)) + url = smart_urlquote('http://%s' % html.unescape(middle)) elif ':' not in middle and is_email_simple(middle): local, domain = middle.rsplit('@', 1) try: diff --git a/docs/intro/tutorial05.txt b/docs/intro/tutorial05.txt index 42891a6ecd..c59a0db155 100644 --- a/docs/intro/tutorial05.txt +++ b/docs/intro/tutorial05.txt @@ -387,7 +387,7 @@ With that ready, we can ask the client to do some work for us:: >>> response.status_code 200 >>> response.content - b'\n <ul>\n \n <li><a href="/polls/1/">What's up?</a></li>\n \n </ul>\n\n' + b'\n <ul>\n \n <li><a href="/polls/1/">What's up?</a></li>\n \n </ul>\n\n' >>> response.context['latest_question_list'] <QuerySet [<Question: What's up?>]> diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index 9509377a24..cd5476fd6f 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -1603,7 +1603,7 @@ Escapes a string's HTML. Specifically, it makes these replacements: * ``<`` is converted to ``<`` * ``>`` is converted to ``>`` -* ``'`` (single quote) is converted to ``'`` +* ``'`` (single quote) is converted to ``'`` * ``"`` (double quote) is converted to ``"`` * ``&`` is converted to ``&`` diff --git a/docs/ref/templates/language.txt b/docs/ref/templates/language.txt index 1287f012c2..33687fc49d 100644 --- a/docs/ref/templates/language.txt +++ b/docs/ref/templates/language.txt @@ -492,7 +492,7 @@ escaped: * ``<`` is converted to ``<`` * ``>`` is converted to ``>`` -* ``'`` (single quote) is converted to ``'`` +* ``'`` (single quote) is converted to ``'`` * ``"`` (double quote) is converted to ``"`` * ``&`` is converted to ``&`` diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 5f03dc66e4..b36282048f 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -584,6 +584,11 @@ escaping HTML. for use in HTML. The input is first coerced to a string and the output has :func:`~django.utils.safestring.mark_safe` applied. + .. versionchanged:: 3.0 + + In older versions, ``'`` is converted to its decimal code ``'`` + instead of the equivalent hex code ``'``. + .. function:: conditional_escape(text) Similar to ``escape()``, except that it doesn't operate on pre-escaped diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt index b279f9a451..2ee02206a1 100644 --- a/docs/releases/3.0.txt +++ b/docs/releases/3.0.txt @@ -348,6 +348,10 @@ Miscellaneous the session and :func:`django.contrib.auth.logout` no longer preserves the session's language after logout. +* :func:`django.utils.html.escape` now uses :func:`html.escape` to escape HTML. + This converts ``'`` to ``'`` instead of the previous equivalent decimal + code ``'``. + .. _deprecated-features-3.0: Features deprecated in 3.0 diff --git a/tests/admin_docs/test_views.py b/tests/admin_docs/test_views.py index bcadff7d8a..03d38bb2fd 100644 --- a/tests/admin_docs/test_views.py +++ b/tests/admin_docs/test_views.py @@ -199,7 +199,7 @@ class TestModelDetailView(TestDataMixin, AdminDocsTestCase): """ Methods with keyword arguments should have their arguments displayed. """ - self.assertContains(self.response, "<td>suffix='ltd'</td>") + self.assertContains(self.response, '<td>suffix='ltd'</td>') def test_methods_with_multiple_arguments_display_arguments(self): """ diff --git a/tests/auth_tests/test_forms.py b/tests/auth_tests/test_forms.py index e12cf0161f..e36931501e 100644 --- a/tests/auth_tests/test_forms.py +++ b/tests/auth_tests/test_forms.py @@ -236,7 +236,7 @@ class UserCreationFormTest(TestDataMixin, TestCase): form = UserCreationForm() self.assertEqual( form.fields['password1'].help_text, - '<ul><li>Your password can't be too similar to your other personal information.</li></ul>' + '<ul><li>Your password can't be too similar to your other personal information.</li></ul>' ) @override_settings(AUTH_PASSWORD_VALIDATORS=[ diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index edce5e801f..18fb4a94de 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -995,7 +995,7 @@ Java</label></li> self.assertHTMLEqual( f.as_table(), """<tr><th><em>Special</em> Field:</th><td> -<ul class="errorlist"><li>Something's wrong with 'Nothing to escape'</li></ul> +<ul class="errorlist"><li>Something's wrong with 'Nothing to escape'</li></ul> <input type="text" name="special_name" value="Nothing to escape" required></td></tr> <tr><th><em>Special</em> Field:</th><td> <ul class="errorlist"><li>'<b>Nothing to escape</b>' is a safe string</li></ul> @@ -1008,10 +1008,10 @@ Java</label></li> self.assertHTMLEqual( f.as_table(), """<tr><th><em>Special</em> Field:</th><td> -<ul class="errorlist"><li>Something's wrong with 'Should escape < & > and -<script>alert('xss')</script>'</li></ul> +<ul class="errorlist"><li>Something's wrong with 'Should escape < & > and +<script>alert('xss')</script>'</li></ul> <input type="text" name="special_name" -value="Should escape < & > and <script>alert('xss')</script>" required></td></tr> +value="Should escape < & > and <script>alert('xss')</script>" required></td></tr> <tr><th><em>Special</em> Field:</th><td> <ul class="errorlist"><li>'<b><i>Do not escape</i></b>' is a safe string</li></ul> <input type="text" name="special_safe_name" value="<i>Do not escape</i>" required></td></tr>""" @@ -2632,7 +2632,7 @@ Password: <input type="password" name="password" required> t.render(Context({'form': UserRegistration(auto_id=False)})), """<form> <p>Username: <input type="text" name="username" maxlength="10" required><br> -Good luck picking a username that doesn't already exist.</p> +Good luck picking a username that doesn't already exist.</p> <p>Password1: <input type="password" name="password1" required></p> <p>Password2: <input type="password" name="password2" required></p> <input type="submit" required> diff --git a/tests/forms_tests/widget_tests/base.py b/tests/forms_tests/widget_tests/base.py index 7222910479..339d78bc71 100644 --- a/tests/forms_tests/widget_tests/base.py +++ b/tests/forms_tests/widget_tests/base.py @@ -22,7 +22,10 @@ class WidgetTest(SimpleTestCase): if self.jinja2_renderer: output = widget.render(name, value, attrs=attrs, renderer=self.jinja2_renderer, **kwargs) # Django escapes quotes with '"' while Jinja2 uses '"'. - assertEqual(output.replace('"', '"'), html) + output = output.replace('"', '"') + # Django escapes single quotes with ''' while Jinja2 uses '''. + output = output.replace(''', ''') + assertEqual(output, html) output = widget.render(name, value, attrs=attrs, renderer=self.django_renderer, **kwargs) assertEqual(output, html) diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py index 2ba376db8a..ff6a1c74e7 100644 --- a/tests/forms_tests/widget_tests/test_clearablefileinput.py +++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py @@ -46,7 +46,7 @@ class ClearableFileInputTest(WidgetTest): self.check_html(ClearableFileInput(), 'my<div>file', StrangeFieldFile(), html=( """ Currently: <a href="something?chapter=1&sect=2&copy=3&lang=en"> - something<div onclick="alert('oops')">.jpg</a> + something<div onclick="alert('oops')">.jpg</a> <input type="checkbox" name="my<div>file-clear" id="my<div>file-clear_id"> <label for="my<div>file-clear_id">Clear</label><br> Change: <input type="file" name="my<div>file"> diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index e4f24c31ee..3893eb334c 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -1197,7 +1197,7 @@ class ModelFormBasicTests(TestCase): <li>Article: <textarea rows="10" cols="40" name="article" required></textarea></li> <li>Categories: <select multiple name="categories"> <option value="%s" selected>Entertainment</option> -<option value="%s" selected>It's a test</option> +<option value="%s" selected>It's a test</option> <option value="%s">Third test</option> </select></li> <li>Status: <select name="status"> @@ -1239,7 +1239,7 @@ class ModelFormBasicTests(TestCase): <li>Article: <textarea rows="10" cols="40" name="article" required>Hello.</textarea></li> <li>Categories: <select multiple name="categories"> <option value="%s">Entertainment</option> -<option value="%s">It's a test</option> +<option value="%s">It's a test</option> <option value="%s">Third test</option> </select></li> <li>Status: <select name="status"> @@ -1290,7 +1290,7 @@ class ModelFormBasicTests(TestCase): <li><label for="id_categories">Categories:</label> <select multiple name="categories" id="id_categories"> <option value="%d" selected>Entertainment</option> -<option value="%d" selected>It&39;s a test</option> +<option value="%d" selected>It's a test</option> <option value="%d">Third test</option> </select></li>""" % (self.c1.pk, self.c2.pk, self.c3.pk)) @@ -1361,7 +1361,7 @@ class ModelFormBasicTests(TestCase): <tr><th>Article:</th><td><textarea rows="10" cols="40" name="article" required></textarea></td></tr> <tr><th>Categories:</th><td><select multiple name="categories"> <option value="%s">Entertainment</option> -<option value="%s">It's a test</option> +<option value="%s">It's a test</option> <option value="%s">Third test</option> </select></td></tr> <tr><th>Status:</th><td><select name="status"> @@ -1391,7 +1391,7 @@ class ModelFormBasicTests(TestCase): <li>Article: <textarea rows="10" cols="40" name="article" required>Hello.</textarea></li> <li>Categories: <select multiple name="categories"> <option value="%s" selected>Entertainment</option> -<option value="%s">It's a test</option> +<option value="%s">It's a test</option> <option value="%s">Third test</option> </select></li> <li>Status: <select name="status"> @@ -1535,7 +1535,7 @@ class ModelFormBasicTests(TestCase): <li>Article: <textarea rows="10" cols="40" name="article" required></textarea></li> <li>Categories: <select multiple name="categories"> <option value="%s">Entertainment</option> -<option value="%s">It's a test</option> +<option value="%s">It's a test</option> <option value="%s">Third test</option> </select> </li> <li>Status: <select name="status"> @@ -1561,7 +1561,7 @@ class ModelFormBasicTests(TestCase): <li>Article: <textarea rows="10" cols="40" name="article" required></textarea></li> <li>Categories: <select multiple name="categories"> <option value="%s">Entertainment</option> -<option value="%s">It's a test</option> +<option value="%s">It's a test</option> <option value="%s">Third test</option> <option value="%s">Fourth</option> </select></li> diff --git a/tests/template_tests/filter_tests/test_addslashes.py b/tests/template_tests/filter_tests/test_addslashes.py index 9c6abd8684..ede25cfb14 100644 --- a/tests/template_tests/filter_tests/test_addslashes.py +++ b/tests/template_tests/filter_tests/test_addslashes.py @@ -15,7 +15,7 @@ class AddslashesTests(SimpleTestCase): @setup({'addslashes02': '{{ a|addslashes }} {{ b|addslashes }}'}) def test_addslashes02(self): output = self.engine.render_to_string('addslashes02', {"a": "<a>'", "b": mark_safe("<a>'")}) - self.assertEqual(output, r"<a>\' <a>\'") + self.assertEqual(output, r"<a>\' <a>\'") class FunctionTests(SimpleTestCase): diff --git a/tests/template_tests/filter_tests/test_make_list.py b/tests/template_tests/filter_tests/test_make_list.py index 17c4cac480..a3e8535ecb 100644 --- a/tests/template_tests/filter_tests/test_make_list.py +++ b/tests/template_tests/filter_tests/test_make_list.py @@ -19,7 +19,7 @@ class MakeListTests(SimpleTestCase): @setup({'make_list02': '{{ a|make_list }}'}) def test_make_list02(self): output = self.engine.render_to_string('make_list02', {"a": mark_safe("&")}) - self.assertEqual(output, "['&']") + self.assertEqual(output, '['&']') @setup({'make_list03': '{% autoescape off %}{{ a|make_list|stringformat:"s"|safe }}{% endautoescape %}'}) def test_make_list03(self): diff --git a/tests/template_tests/filter_tests/test_title.py b/tests/template_tests/filter_tests/test_title.py index 08a5fb0de4..2eaf4a0219 100644 --- a/tests/template_tests/filter_tests/test_title.py +++ b/tests/template_tests/filter_tests/test_title.py @@ -9,7 +9,7 @@ class TitleTests(SimpleTestCase): @setup({'title1': '{{ a|title }}'}) def test_title1(self): output = self.engine.render_to_string('title1', {'a': 'JOE\'S CRAB SHACK'}) - self.assertEqual(output, 'Joe's Crab Shack') + self.assertEqual(output, 'Joe's Crab Shack') @setup({'title2': '{{ a|title }}'}) def test_title2(self): diff --git a/tests/template_tests/filter_tests/test_urlize.py b/tests/template_tests/filter_tests/test_urlize.py index 649a965203..3843cc3e0a 100644 --- a/tests/template_tests/filter_tests/test_urlize.py +++ b/tests/template_tests/filter_tests/test_urlize.py @@ -52,7 +52,7 @@ class UrlizeTests(SimpleTestCase): @setup({'urlize06': '{{ a|urlize }}'}) def test_urlize06(self): output = self.engine.render_to_string('urlize06', {'a': "<script>alert('foo')</script>"}) - self.assertEqual(output, '<script>alert('foo')</script>') + self.assertEqual(output, '<script>alert('foo')</script>') # mailto: testing for urlize @setup({'urlize07': '{{ a|urlize }}'}) @@ -113,7 +113,7 @@ class FunctionTests(SimpleTestCase): ) self.assertEqual( urlize('www.server.com\'abc'), - '<a href="http://www.server.com" rel="nofollow">www.server.com</a>'abc', + '<a href="http://www.server.com" rel="nofollow">www.server.com</a>'abc', ) self.assertEqual( urlize('www.server.com<abc'), @@ -284,7 +284,7 @@ class FunctionTests(SimpleTestCase): ('<>', ('<', '>')), ('[]', ('[', ']')), ('""', ('"', '"')), - ("''", (''', ''')), + ("''", (''', ''')), ) for wrapping_in, (start_out, end_out) in wrapping_chars: with self.subTest(wrapping_in=wrapping_in): diff --git a/tests/template_tests/syntax_tests/test_url.py b/tests/template_tests/syntax_tests/test_url.py index a6cc2d50a0..bdbc61454d 100644 --- a/tests/template_tests/syntax_tests/test_url.py +++ b/tests/template_tests/syntax_tests/test_url.py @@ -78,7 +78,7 @@ class UrlTagTests(SimpleTestCase): @setup({'url12': '{% url "client_action" id=client.id action="!$&\'()*+,;=~:@," %}'}) def test_url12(self): output = self.engine.render_to_string('url12', {'client': {'id': 1}}) - self.assertEqual(output, '/client/1/!$&'()*+,;=~:@,/') + self.assertEqual(output, '/client/1/!$&'()*+,;=~:@,/') @setup({'url13': '{% url "client_action" id=client.id action=arg|join:"-" %}'}) def test_url13(self): diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py index d87927cdfe..02825f5e1e 100644 --- a/tests/utils_tests/test_html.py +++ b/tests/utils_tests/test_html.py @@ -27,7 +27,7 @@ class TestUtilsHtml(SimpleTestCase): ('<', '<'), ('>', '>'), ('"', '"'), - ("'", '''), + ("'", '''), ) # Substitution patterns for testing the above items. patterns = ("%s", "asdf%sfdsa", "%s1", "1%sb") @@ -70,6 +70,8 @@ class TestUtilsHtml(SimpleTestCase): items = ( ('<p>See: 'é is an apostrophe followed by e acute</p>', 'See: 'é is an apostrophe followed by e acute'), + ('<p>See: 'é is an apostrophe followed by e acute</p>', + 'See: 'é is an apostrophe followed by e acute'), ('<adf>a', 'a'), ('</adf>a', 'a'), ('<asdf><asdf>e', 'e'), diff --git a/tests/view_tests/tests/test_csrf.py b/tests/view_tests/tests/test_csrf.py index 4c20cb897d..77f2373347 100644 --- a/tests/view_tests/tests/test_csrf.py +++ b/tests/view_tests/tests/test_csrf.py @@ -44,22 +44,22 @@ class CsrfViewTests(SimpleTestCase): self.assertContains( response, 'You are seeing this message because this HTTPS site requires a ' - ''Referer header' to be sent by your Web browser, but ' + ''Referer header' to be sent by your Web browser, but ' 'none was sent.', status_code=403, ) self.assertContains( response, - 'If you have configured your browser to disable 'Referer' ' + 'If you have configured your browser to disable 'Referer' ' 'headers, please re-enable them, at least for this site, or for ' - 'HTTPS connections, or for 'same-origin' requests.', + 'HTTPS connections, or for 'same-origin' requests.', status_code=403, ) self.assertContains( response, 'If you are using the <meta name="referrer" ' 'content="no-referrer"> tag or including the ' - ''Referrer-Policy: no-referrer' header, please remove them.', + ''Referrer-Policy: no-referrer' header, please remove them.', status_code=403, ) diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index a61e4b24ff..abe41dc375 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -304,7 +304,7 @@ class ExceptionReporterTests(SimpleTestCase): reporter = ExceptionReporter(request, exc_type, exc_value, tb) html = reporter.get_traceback_html() self.assertInHTML('<h1>ValueError at /test_view/</h1>', html) - self.assertIn('<pre class="exception_value">Can't find my keys</pre>', html) + self.assertIn('<pre class="exception_value">Can't find my keys</pre>', html) self.assertIn('<th>Request Method:</th>', html) self.assertIn('<th>Request URL:</th>', html) self.assertIn('<h3 id="user-info">USER</h3>', html) @@ -325,7 +325,7 @@ class ExceptionReporterTests(SimpleTestCase): reporter = ExceptionReporter(None, exc_type, exc_value, tb) html = reporter.get_traceback_html() self.assertInHTML('<h1>ValueError</h1>', html) - self.assertIn('<pre class="exception_value">Can't find my keys</pre>', html) + self.assertIn('<pre class="exception_value">Can't find my keys</pre>', html) self.assertNotIn('<th>Request Method:</th>', html) self.assertNotIn('<th>Request URL:</th>', html) self.assertNotIn('<h3 id="user-info">USER</h3>', html) @@ -463,7 +463,7 @@ class ExceptionReporterTests(SimpleTestCase): reporter = ExceptionReporter(request, None, "I'm a little teapot", None) html = reporter.get_traceback_html() self.assertInHTML('<h1>Report at /test_view/</h1>', html) - self.assertIn('<pre class="exception_value">I'm a little teapot</pre>', html) + self.assertIn('<pre class="exception_value">I'm a little teapot</pre>', html) self.assertIn('<th>Request Method:</th>', html) self.assertIn('<th>Request URL:</th>', html) self.assertNotIn('<th>Exception Type:</th>', html) @@ -476,7 +476,7 @@ class ExceptionReporterTests(SimpleTestCase): reporter = ExceptionReporter(None, None, "I'm a little teapot", None) html = reporter.get_traceback_html() self.assertInHTML('<h1>Report</h1>', html) - self.assertIn('<pre class="exception_value">I'm a little teapot</pre>', html) + self.assertIn('<pre class="exception_value">I'm a little teapot</pre>', html) self.assertNotIn('<th>Request Method:</th>', html) self.assertNotIn('<th>Request URL:</th>', html) self.assertNotIn('<th>Exception Type:</th>', html) @@ -508,7 +508,7 @@ class ExceptionReporterTests(SimpleTestCase): except Exception: exc_type, exc_value, tb = sys.exc_info() html = ExceptionReporter(None, exc_type, exc_value, tb).get_traceback_html() - self.assertIn('<td class="code"><pre>'<p>Local variable</p>'</pre></td>', html) + self.assertIn('<td class="code"><pre>'<p>Local variable</p>'</pre></td>', html) def test_unprintable_values_handling(self): "Unprintable values should not make the output generation choke." @@ -607,7 +607,7 @@ class ExceptionReporterTests(SimpleTestCase): An exception report can be generated for requests with 'items' in request GET, POST, FILES, or COOKIES QueryDicts. """ - value = '<td>items</td><td class="code"><pre>'Oops'</pre></td>' + value = '<td>items</td><td class="code"><pre>'Oops'</pre></td>' # GET request = self.rf.get('/test_view/?items=Oops') reporter = ExceptionReporter(request, None, None, None) @@ -634,7 +634,7 @@ class ExceptionReporterTests(SimpleTestCase): request = rf.get('/test_view/') reporter = ExceptionReporter(request, None, None, None) html = reporter.get_traceback_html() - self.assertInHTML('<td>items</td><td class="code"><pre>'Oops'</pre></td>', html) + self.assertInHTML('<td>items</td><td class="code"><pre>'Oops'</pre></td>', html) def test_exception_fetching_user(self): """ |
