Fixed #23923 -- Promoted Django's deprecation warnings to errors in runtests.py
This commit is contained in:
parent
860eb01d17
commit
3131e9cef5
|
@ -176,12 +176,11 @@ There are a couple reasons that code in Django might be deprecated:
|
||||||
As the :ref:`deprecation policy<internal-release-deprecation-policy>` describes,
|
As the :ref:`deprecation policy<internal-release-deprecation-policy>` describes,
|
||||||
the first release of Django that deprecates a feature (``A.B``) should raise a
|
the first release of Django that deprecates a feature (``A.B``) should raise a
|
||||||
``RemovedInDjangoXXWarning`` (where XX is the Django version where the feature
|
``RemovedInDjangoXXWarning`` (where XX is the Django version where the feature
|
||||||
will be removed) when the deprecated feature is invoked. Assuming
|
will be removed) when the deprecated feature is invoked. Assuming we have good
|
||||||
we have a good test coverage, these warnings will be shown by the test suite
|
test coverage, these warnings are converted to errors when :ref:`running the
|
||||||
when :ref:`running it <running-unit-tests>` with warnings enabled:
|
test suite <running-unit-tests>` with warnings enabled:
|
||||||
``python -Wall runtests.py``. This is annoying and the output of the test suite
|
``python -Wall runtests.py``. Thus, when adding a ``RemovedInDjangoXXWarning``
|
||||||
should remain clean. Thus, when adding a ``RemovedInDjangoXXWarning`` you need
|
you need to eliminate or silence any warnings generated when running the tests.
|
||||||
to eliminate or silence any warnings generated when running the tests.
|
|
||||||
|
|
||||||
The first step is to remove any use of the deprecated behavior by Django itself.
|
The first step is to remove any use of the deprecated behavior by Django itself.
|
||||||
Next you can silence warnings in tests that actually test the deprecated
|
Next you can silence warnings in tests that actually test the deprecated
|
||||||
|
@ -191,9 +190,11 @@ behavior in one of two ways:
|
||||||
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
from django.utils.deprecation import RemovedInDjangoXXWarning
|
||||||
|
|
||||||
def test_foo(self):
|
def test_foo(self):
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("always")
|
warnings.simplefilter("ignore", category=RemovedInDjangoXXWarning)
|
||||||
# invoke deprecated behavior
|
# invoke deprecated behavior
|
||||||
# go ahead with the rest of the test
|
# go ahead with the rest of the test
|
||||||
|
|
||||||
|
@ -207,6 +208,20 @@ behavior in one of two ways:
|
||||||
class MyDeprecatedTests(IgnorePendingDeprecationWarningsMixin, unittest.TestCase):
|
class MyDeprecatedTests(IgnorePendingDeprecationWarningsMixin, unittest.TestCase):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
You can also add a test for the deprecation warning. You'll have to disable the
|
||||||
|
"warning as error" behavior in your test by doing::
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
def test_foo_deprecation_warning(self):
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always') # prevent warnings from appearing as errors
|
||||||
|
# invoke deprecated behavior
|
||||||
|
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
msg = str(warns[0].message)
|
||||||
|
self.assertEqual(msg, 'Expected deprecation message')
|
||||||
|
|
||||||
Finally, there are a couple of updates to Django's documentation to make:
|
Finally, there are a couple of updates to Django's documentation to make:
|
||||||
|
|
||||||
#) If the existing feature is documented, mark it deprecated in documentation
|
#) If the existing feature is documented, mark it deprecated in documentation
|
||||||
|
|
|
@ -416,6 +416,7 @@ class TestInlineAdminForm(TestCase):
|
||||||
iaf2 = InlineAdminForm(None, None, {}, {}, poll)
|
iaf2 = InlineAdminForm(None, None, {}, {}, poll)
|
||||||
poll_ct = ContentType.objects.get_for_model(Poll)
|
poll_ct = ContentType.objects.get_for_model(Poll)
|
||||||
with warnings.catch_warnings(record=True) as recorded:
|
with warnings.catch_warnings(record=True) as recorded:
|
||||||
|
warnings.filterwarnings('always')
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
iaf.original_content_type_id
|
iaf.original_content_type_id
|
||||||
msg = force_text(recorded.pop().message)
|
msg = force_text(recorded.pop().message)
|
||||||
|
|
|
@ -64,7 +64,8 @@ full_decorator = compose(
|
||||||
)
|
)
|
||||||
|
|
||||||
# suppress the deprecation warning of memoize
|
# suppress the deprecation warning of memoize
|
||||||
with warnings.catch_warnings(record=True):
|
with warnings.catch_warnings():
|
||||||
|
warnings.filterwarnings('ignore')
|
||||||
fully_decorated = memoize(fully_decorated, {}, 1)
|
fully_decorated = memoize(fully_decorated, {}, 1)
|
||||||
|
|
||||||
fully_decorated = full_decorator(fully_decorated)
|
fully_decorated = full_decorator(fully_decorated)
|
||||||
|
|
|
@ -238,6 +238,7 @@ class DeprecatingSimpleTestCaseUrls(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
with warnings.catch_warnings(record=True) as recorded:
|
with warnings.catch_warnings(record=True) as recorded:
|
||||||
|
warnings.filterwarnings('always')
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(TempTestCase)
|
suite = unittest.TestLoader().loadTestsFromTestCase(TempTestCase)
|
||||||
with open(os.devnull, 'w') as devnull:
|
with open(os.devnull, 'w') as devnull:
|
||||||
unittest.TextTestRunner(stream=devnull, verbosity=2).run(suite)
|
unittest.TextTestRunner(stream=devnull, verbosity=2).run(suite)
|
||||||
|
|
|
@ -62,6 +62,8 @@ class FormMixinTests(TestCase):
|
||||||
|
|
||||||
def test_get_form_missing_form_class_default_value(self):
|
def test_get_form_missing_form_class_default_value(self):
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
warnings.filterwarnings('always')
|
||||||
|
|
||||||
class MissingDefaultValue(FormMixin):
|
class MissingDefaultValue(FormMixin):
|
||||||
request = RequestFactory().get('/')
|
request = RequestFactory().get('/')
|
||||||
form_class = forms.Form
|
form_class = forms.Form
|
||||||
|
|
|
@ -3,13 +3,14 @@ import warnings
|
||||||
|
|
||||||
from django.conf.urls.i18n import i18n_patterns
|
from django.conf.urls.i18n import i18n_patterns
|
||||||
from django.http import HttpResponse, StreamingHttpResponse
|
from django.http import HttpResponse, StreamingHttpResponse
|
||||||
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
# test deprecated version of i18_patterns() function (with prefix). Remove it
|
# test deprecated version of i18n_patterns() function (with prefix). Remove it
|
||||||
# and convert to list of urls() in Django 2.0
|
# and convert to list of urls() in Django 2.0
|
||||||
with warnings.catch_warnings(record=True):
|
with warnings.catch_warnings():
|
||||||
warnings.filterwarnings('ignore', module='django.conf.urls.18n')
|
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
|
||||||
|
|
||||||
urlpatterns = i18n_patterns('',
|
urlpatterns = i18n_patterns('',
|
||||||
(r'^simple/$', lambda r: HttpResponse()),
|
(r'^simple/$', lambda r: HttpResponse()),
|
||||||
|
|
|
@ -101,6 +101,7 @@ class WarningLoggerTests(TestCase):
|
||||||
# undocumented and (I assume) brittle.
|
# undocumented and (I assume) brittle.
|
||||||
self._old_capture_state = bool(getattr(logging, '_warnings_showwarning', False))
|
self._old_capture_state = bool(getattr(logging, '_warnings_showwarning', False))
|
||||||
logging.captureWarnings(True)
|
logging.captureWarnings(True)
|
||||||
|
warnings.filterwarnings('always')
|
||||||
|
|
||||||
# this convoluted setup is to avoid printing this deprecation to
|
# this convoluted setup is to avoid printing this deprecation to
|
||||||
# stderr during test running - as the test runner forces deprecations
|
# stderr during test running - as the test runner forces deprecations
|
||||||
|
|
|
@ -20,8 +20,8 @@ from django.utils._os import upath
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
|
|
||||||
warnings.simplefilter("default", RemovedInDjango19Warning)
|
warnings.simplefilter("error", RemovedInDjango19Warning)
|
||||||
warnings.simplefilter("default", RemovedInDjango20Warning)
|
warnings.simplefilter("error", RemovedInDjango20Warning)
|
||||||
|
|
||||||
CONTRIB_MODULE_PATH = 'django.contrib'
|
CONTRIB_MODULE_PATH = 'django.contrib'
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
# Test deprecated behavior of passing strings as view to url().
|
# Test deprecated behavior of passing strings as view to url().
|
||||||
# Some of these can be removed in Django 2.0 as they aren't convertable to
|
# Some of these can be removed in Django 2.0 as they aren't convertable to
|
||||||
# callabls.
|
# callables.
|
||||||
with warnings.catch_warnings(record=True):
|
with warnings.catch_warnings():
|
||||||
warnings.filterwarnings('ignore', module='django.conf.urls')
|
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# View has erroneous import
|
# View has erroneous import
|
||||||
url(r'erroneous_inner/$', views.erroneous_view),
|
url(r'erroneous_inner/$', views.erroneous_view),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.conf.urls import patterns, url, include
|
from django.conf.urls import patterns, url, include
|
||||||
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
|
|
||||||
from .namespace_urls import URLObject
|
from .namespace_urls import URLObject
|
||||||
from .views import view_class_instance
|
from .views import view_class_instance
|
||||||
|
@ -9,8 +10,8 @@ from .views import view_class_instance
|
||||||
testobj3 = URLObject('testapp', 'test-ns3')
|
testobj3 = URLObject('testapp', 'test-ns3')
|
||||||
|
|
||||||
# test deprecated patterns() function. convert to list of urls() in Django 2.0
|
# test deprecated patterns() function. convert to list of urls() in Django 2.0
|
||||||
with warnings.catch_warnings(record=True) as w:
|
with warnings.catch_warnings():
|
||||||
warnings.filterwarnings('ignore', module='django.conf.urls')
|
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
|
||||||
|
|
||||||
urlpatterns = patterns('urlpatterns_reverse.views',
|
urlpatterns = patterns('urlpatterns_reverse.views',
|
||||||
url(r'^normal/$', 'empty_view', name='inc-normal-view'),
|
url(r'^normal/$', 'empty_view', name='inc-normal-view'),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.conf.urls import patterns, url, include
|
from django.conf.urls import patterns, url, include
|
||||||
|
from django.utils.deprecation import RemovedInDjango20Warning
|
||||||
|
|
||||||
from .views import (
|
from .views import (
|
||||||
absolute_kwargs_view, defaults_view, empty_view, empty_view_partial,
|
absolute_kwargs_view, defaults_view, empty_view, empty_view_partial,
|
||||||
|
@ -14,8 +15,8 @@ other_patterns = [
|
||||||
]
|
]
|
||||||
|
|
||||||
# test deprecated patterns() function. convert to list of urls() in Django 2.0
|
# test deprecated patterns() function. convert to list of urls() in Django 2.0
|
||||||
with warnings.catch_warnings(record=True):
|
with warnings.catch_warnings():
|
||||||
warnings.filterwarnings('ignore', module='django.conf.urls')
|
warnings.filterwarnings('ignore', category=RemovedInDjango20Warning)
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^places/([0-9]+)/$', empty_view, name='places'),
|
url(r'^places/([0-9]+)/$', empty_view, name='places'),
|
||||||
|
|
Loading…
Reference in New Issue