diff --git a/docs/internals/contributing/writing-code/submitting-patches.txt b/docs/internals/contributing/writing-code/submitting-patches.txt index 8f8ddddab44..7ded57487ae 100644 --- a/docs/internals/contributing/writing-code/submitting-patches.txt +++ b/docs/internals/contributing/writing-code/submitting-patches.txt @@ -158,6 +158,70 @@ been discussed on `django-developers`_. If you're not sure whether your patch should be considered non-trivial, just ask. +Deprecating a feature +--------------------- + +There are a couple reasons that code in Django might be deprecated: + +* If a feature has been improved or modified in a backwards-incompatible way, + the old feature or behavior will be deprecated. + +* Sometimes Django will include a backport of a Python library that's not + included in a version of Python that Django currently supports. When Django + no longer needs to support the older version of Python that doesn't include + the library, the library will be deprecated in Django. + +As the :ref:`deprecation policy` describes, +the first release of Django that deprecates a feature (``A.B``) should raise a +``PendingDeprecationWarning`` when the deprecated feature is invoked. Assuming +we have a good test coverage, these warnings will be shown by the test suite +when :ref:`running it ` with warnings enabled: +``python -Wall runtests.py``. This is annoying and the output of the test suite +should remain clean. Thus, when adding a ``PendingDeprecationWarning`` you need +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. +Next you can silence warnings in tests that actually test the deprecated +behavior in one of two ways: + +#) In a particular test:: + + import warnings + + def test_foo(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + # invoke deprecated behavior + # go ahead with the rest of the test + +#) For an entire test case, ``django.test.utils`` contains three helpful + mixins to silence warnings: ``IgnorePendingDeprecationWarningsMixin``, + ``IgnoreDeprecationWarningsMixin``, and + ``IgnoreAllDeprecationWarningsMixin``. For example:: + + from django.test.utils import IgnorePendingDeprecationWarningsMixin + + class MyDeprecatedTests(IgnorePendingDeprecationWarningsMixin, unittest.TestCase): + ... + +Finally, there are a couple of updates to Django's documentation to make: + +#) If the existing feature is documented, mark it deprecated in documentation + using the ``.. deprecated:: A.B`` annotation. Include a short description + and a note about the upgrade path if applicable. + +#) Add a description of the deprecated behavior, and the upgrade path if + applicable, to the current release notes (``docs/releases/A.B.txt``) under + the "Features deprecated in A.B" heading. + +#) Add an entry in the deprecation timeline (``docs/internals/deprecation.txt``) + under the ``A.B+2`` version describing what code will be removed. + +Once you have completed these steps, you are finished with the deprecation. +In each minor release, all ``PendingDeprecationWarning``\s are promoted to +``DeprecationWarning``\s and any features marked with ``DeprecationWarning`` +are removed. + Javascript patches ------------------