Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #20503 - Moved doctest utilities in with the rest of the deprec…

…ated test code.

The ``DocTestRunner`` and ``OutputChecker`` were formerly in
``django.test.testcases``, now they are in ``django.test.simple``. This avoids
triggering the ``django.test._doctest`` deprecation message with any import
from ``django.test``. Since these utility classes are undocumented internal
API, they can be moved without a separate deprecation process.

Also removed the deprecation warnings specific to these classes, as they are
now covered by the module-level warning in ``django.test.simple``.

Thanks Anssi for the report.

Refs #17365.
  • Loading branch information...
commit cd79f337233be3f2dfa22316314c9d4834093e31 1 parent 0027f13
@carljm carljm authored
View
70 django/test/simple.py
@@ -3,14 +3,15 @@
version 1.8.
"""
-
+import json
+import re
import unittest as real_unittest
import warnings
from django.db.models import get_app, get_apps
from django.test import _doctest as doctest
from django.test import runner
-from django.test.testcases import OutputChecker, DocTestRunner
+from django.test.utils import compare_xml, strip_quotes
from django.utils import unittest
from django.utils.importlib import import_module
from django.utils.module_loading import module_has_submodule
@@ -25,6 +26,71 @@
# The module name for tests outside models.py
TEST_MODULE = 'tests'
+
+normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
+normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)",
+ lambda m: "Decimal(\"%s\")" % m.groups()[0], s)
+
+
+class OutputChecker(doctest.OutputChecker):
+ def check_output(self, want, got, optionflags):
+ """
+ The entry method for doctest output checking. Defers to a sequence of
+ child checkers
+ """
+ checks = (self.check_output_default,
+ self.check_output_numeric,
+ self.check_output_xml,
+ self.check_output_json)
+ for check in checks:
+ if check(want, got, optionflags):
+ return True
+ return False
+
+ def check_output_default(self, want, got, optionflags):
+ """
+ The default comparator provided by doctest - not perfect, but good for
+ most purposes
+ """
+ return doctest.OutputChecker.check_output(self, want, got, optionflags)
+
+ def check_output_numeric(self, want, got, optionflags):
+ """Doctest does an exact string comparison of output, which means that
+ some numerically equivalent values aren't equal. This check normalizes
+ * long integers (22L) so that they equal normal integers. (22)
+ * Decimals so that they are comparable, regardless of the change
+ made to __repr__ in Python 2.6.
+ """
+ return doctest.OutputChecker.check_output(self,
+ normalize_decimals(normalize_long_ints(want)),
+ normalize_decimals(normalize_long_ints(got)),
+ optionflags)
+
+ def check_output_xml(self, want, got, optionsflags):
+ try:
+ return compare_xml(want, got)
+ except Exception:
+ return False
+
+ def check_output_json(self, want, got, optionsflags):
+ """
+ Tries to compare want and got as if they were JSON-encoded data
+ """
+ want, got = strip_quotes(want, got)
+ try:
+ want_json = json.loads(want)
+ got_json = json.loads(got)
+ except Exception:
+ return False
+ return want_json == got_json
+
+
+class DocTestRunner(doctest.DocTestRunner):
+ def __init__(self, *args, **kwargs):
+ doctest.DocTestRunner.__init__(self, *args, **kwargs)
+ self.optionflags = doctest.ELLIPSIS
+
+
doctestOutputChecker = OutputChecker()
View
79 django/test/testcases.py
@@ -30,12 +30,11 @@
from django.db import connection, connections, DEFAULT_DB_ALIAS, transaction
from django.forms.fields import CharField
from django.http import QueryDict
-from django.test import _doctest as doctest
from django.test.client import Client
from django.test.html import HTMLParseError, parse_html
from django.test.signals import template_rendered
from django.test.utils import (CaptureQueriesContext, ContextList,
- override_settings, compare_xml, strip_quotes)
+ override_settings, compare_xml)
from django.utils import six, unittest as ut2
from django.utils.encoding import force_text
from django.utils.unittest import skipIf # Imported here for backward compatibility
@@ -43,15 +42,10 @@
from django.views.static import serve
-__all__ = ('DocTestRunner', 'OutputChecker', 'TestCase', 'TransactionTestCase',
+__all__ = ('TestCase', 'TransactionTestCase',
'SimpleTestCase', 'skipIfDBFeature', 'skipUnlessDBFeature')
-normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s)
-normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)",
- lambda m: "Decimal(\"%s\")" % m.groups()[0], s)
-
-
def to_list(value):
"""
Puts value into a list if it's not already one.
@@ -96,75 +90,6 @@ def assert_and_parse_html(self, html, user_msg, msg):
return dom
-class OutputChecker(doctest.OutputChecker):
- def __init__(self):
- warnings.warn(
- "The django.test.testcases.OutputChecker class is deprecated; "
- "use the doctest module from the Python standard library instead.",
- PendingDeprecationWarning)
-
- def check_output(self, want, got, optionflags):
- """
- The entry method for doctest output checking. Defers to a sequence of
- child checkers
- """
- checks = (self.check_output_default,
- self.check_output_numeric,
- self.check_output_xml,
- self.check_output_json)
- for check in checks:
- if check(want, got, optionflags):
- return True
- return False
-
- def check_output_default(self, want, got, optionflags):
- """
- The default comparator provided by doctest - not perfect, but good for
- most purposes
- """
- return doctest.OutputChecker.check_output(self, want, got, optionflags)
-
- def check_output_numeric(self, want, got, optionflags):
- """Doctest does an exact string comparison of output, which means that
- some numerically equivalent values aren't equal. This check normalizes
- * long integers (22L) so that they equal normal integers. (22)
- * Decimals so that they are comparable, regardless of the change
- made to __repr__ in Python 2.6.
- """
- return doctest.OutputChecker.check_output(self,
- normalize_decimals(normalize_long_ints(want)),
- normalize_decimals(normalize_long_ints(got)),
- optionflags)
-
- def check_output_xml(self, want, got, optionsflags):
- try:
- return compare_xml(want, got)
- except Exception:
- return False
-
- def check_output_json(self, want, got, optionsflags):
- """
- Tries to compare want and got as if they were JSON-encoded data
- """
- want, got = strip_quotes(want, got)
- try:
- want_json = json.loads(want)
- got_json = json.loads(got)
- except Exception:
- return False
- return want_json == got_json
-
-
-class DocTestRunner(doctest.DocTestRunner):
- def __init__(self, *args, **kwargs):
- warnings.warn(
- "The django.test.testcases.DocTestRunner class is deprecated; "
- "use the doctest module from the Python standard library instead.",
- PendingDeprecationWarning)
- doctest.DocTestRunner.__init__(self, *args, **kwargs)
- self.optionflags = doctest.ELLIPSIS
-
-
class _AssertNumQueriesContext(CaptureQueriesContext):
def __init__(self, test_case, num, connection):
self.test_case = test_case
View
6 docs/internals/deprecation.txt
@@ -386,10 +386,8 @@ these changes.
``django.test.simple.DjangoTestSuiteRunner`` will be removed. Instead use
``django.test.runner.DiscoverRunner``.
-* The module ``django.test._doctest`` and the classes
- ``django.test.testcases.DocTestRunner`` and
- ``django.test.testcases.OutputChecker`` will be removed. Instead use the
- doctest module from the Python standard library.
+* The module ``django.test._doctest`` will be removed. Instead use the doctest
+ module from the Python standard library.
* The ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting will be removed.
View
18 docs/releases/1.6.txt
@@ -345,21 +345,15 @@ support some types of tests that were supported by the previous runner:
your test suite, follow the `recommendations in the Python documentation`_.
Django bundles a modified version of the :mod:`doctest` module from the Python
-standard library (in ``django.test._doctest``) in order to allow passing in a
-custom ``DocTestRunner`` when instantiating a ``DocTestSuite``, and includes
-some additional doctest utilities (``django.test.testcases.DocTestRunner``
-turns on the ``ELLIPSIS`` option by default, and
-``django.test.testcases.OutputChecker`` provides better matching of XML, JSON,
-and numeric data types).
-
-These utilities are deprecated and will be removed in Django 1.8; doctest
-suites should be updated to work with the standard library's doctest module (or
-converted to unittest-compatible tests).
+standard library (in ``django.test._doctest``) and includes some additional
+doctest utilities. These utilities are deprecated and will be removed in Django
+1.8; doctest suites should be updated to work with the standard library's
+doctest module (or converted to unittest-compatible tests).
If you wish to delay updates to your test suite, you can set your
:setting:`TEST_RUNNER` setting to ``django.test.simple.DjangoTestSuiteRunner``
-to fully restore the old test behavior. ``DjangoTestSuiteRunner`` is
-deprecated but will not be removed from Django until version 1.8.
+to fully restore the old test behavior. ``DjangoTestSuiteRunner`` is deprecated
+but will not be removed from Django until version 1.8.
.. _recommendations in the Python documentation: http://docs.python.org/2/library/doctest.html#unittest-api
Please sign in to comment.
Something went wrong with that request. Please try again.