Commit 5be56d0e authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #21024 -- Documented how to deprecate a feature.

parent a772ea81
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -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<internal-release-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 <running-unit-tests>` 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
------------------