123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- ========================
- Submitting contributions
- ========================
- We're always grateful for contributions to Django's code. Indeed, bug reports
- with associated contributions will get fixed *far* more quickly than those
- without a solution.
- .. _trivial-change:
- Typo fixes and trivial documentation changes
- ============================================
- If you are fixing a really trivial issue, for example changing a word in the
- documentation, the preferred way to provide the patch is using GitHub pull
- requests without a Trac ticket.
- See the :doc:`working-with-git` for more details on how to use pull requests.
- "Claiming" tickets
- ==================
- In an open-source project with hundreds of contributors around the world, it's
- important to manage communication efficiently so that work doesn't get
- duplicated and contributors can be as effective as possible.
- Hence, our policy is for contributors to "claim" tickets in order to let other
- developers know that a particular bug or feature is being worked on.
- If you have identified a contribution you want to make and you're capable of
- fixing it (as measured by your coding ability, knowledge of Django internals
- and time availability), claim it by following these steps:
- * `Login using your GitHub account`_ or `create an account`_ in our ticket
- system. If you have an account but have forgotten your password, you can
- reset it using the `password reset page`_.
- * If a ticket for this issue doesn't exist yet, create one in our
- `ticket tracker`_.
- * If a ticket for this issue already exists, make sure nobody else has
- claimed it. To do this, look at the "Owned by" section of the ticket.
- If it's assigned to "nobody," then it's available to be claimed.
- Otherwise, somebody else may be working on this ticket. Either find another
- bug/feature to work on, or contact the developer working on the ticket to
- offer your help. If a ticket has been assigned for weeks or months without
- any activity, it's probably safe to reassign it to yourself.
- * Log into your account, if you haven't already, by clicking "GitHub Login"
- or "DjangoProject Login" in the upper left of the ticket page. Once logged
- in, you can then click the "Modify Ticket" button near the bottom of the
- page.
- * Claim the ticket by clicking the "assign to" radio button in the "Action"
- section. Your username will be filled in the text box by default.
- * Finally click the "Submit changes" button at the bottom to save.
- .. note::
- The Django software foundation requests that anyone contributing more than
- a :ref:`trivial change <trivial-change>`, to Django sign and submit a
- `Contributor License Agreement`_, this ensures that the Django Software
- Foundation has clear license to all contributions allowing for a clear
- license for all users.
- .. _Login using your GitHub account: https://code.djangoproject.com/github/login
- .. _Create an account: https://www.djangoproject.com/accounts/register/
- .. _password reset page: https://www.djangoproject.com/accounts/password/reset/
- .. _Contributor License Agreement: https://www.djangoproject.com/foundation/cla/
- Ticket claimers' responsibility
- -------------------------------
- Once you've claimed a ticket, you have a responsibility to work on that ticket
- in a reasonably timely fashion. If you don't have time to work on it, either
- unclaim it or don't claim it in the first place!
- If there's no sign of progress on a particular claimed ticket for a week or
- two, another developer may ask you to relinquish the ticket claim so that it's
- no longer monopolized and somebody else can claim it.
- If you've claimed a ticket and it's taking a long time (days or weeks) to code,
- keep everybody updated by posting comments on the ticket. If you don't provide
- regular updates, and you don't respond to a request for a progress report,
- your claim on the ticket may be revoked.
- As always, more communication is better than less communication!
- Which tickets should be claimed?
- --------------------------------
- Going through the steps of claiming tickets is overkill in some cases.
- In the case of small changes, such as typos in the documentation or small bugs
- that will only take a few minutes to fix, you don't need to jump through the
- hoops of claiming tickets. Submit your changes directly and you're done!
- It is *always* acceptable, regardless whether someone has claimed it or not, to
- link proposals to a ticket if you happen to have the changes ready.
- .. _patch-style:
- Contribution style
- ==================
- Make sure that any contribution you do fulfills at least the following
- requirements:
- * The code required to fix a problem or add a feature is an essential part
- of a solution, but it is not the only part. A good fix should also include a
- :doc:`regression test <unit-tests>` to validate the behavior that has been
- fixed and to prevent the problem from arising again. Also, if some tickets
- are relevant to the code that you've written, mention the ticket numbers in
- some comments in the test so that one can easily trace back the relevant
- discussions after your patch gets committed, and the tickets get closed.
- * If the code adds a new feature, or modifies the behavior of an existing
- feature, the change should also contain documentation.
- When you think your work is ready to be reviewed, send :doc:`a GitHub pull
- request <working-with-git>`.
- If you can't send a pull request for some reason, you can also use patches in
- Trac. When using this style, follow these guidelines.
- * Submit patches in the format returned by the ``git diff`` command.
- * Attach patches to a ticket in the `ticket tracker`_, using the "attach
- file" button. Please *don't* put the patch in the ticket description
- or comment unless it's a single line patch.
- * Name the patch file with a ``.diff`` extension; this will let the ticket
- tracker apply correct syntax highlighting, which is quite helpful.
- Regardless of the way you submit your work, follow these steps.
- * Make sure your code fulfills the requirements in our :ref:`contribution
- checklist <patch-review-checklist>`.
- * Check the "Has patch" box on the ticket and make sure the "Needs
- documentation", "Needs tests", and "Patch needs improvement" boxes aren't
- checked. This makes the ticket appear in the "Patches needing review" queue
- on the `Development dashboard`_.
- .. _ticket tracker: https://code.djangoproject.com/
- .. _Development dashboard: https://dashboard.djangoproject.com/
- Contributions which require community feedback
- ==============================================
- A wider community discussion is required when a patch introduces new Django
- functionality and makes some sort of design decision. This is especially
- important if the approach involves a :ref:`deprecation <deprecating-a-feature>`
- or introduces breaking changes.
- The following are different approaches for gaining feedback from the community.
- The Django Forum or django-developers mailing list
- --------------------------------------------------
- You can propose a change on the `Django Forum`_ or |django-developers| mailing
- list. You should explain the need for the change, go into details of the
- approach and discuss alternatives.
- Please include a link to such discussions in your contributions.
- Third party package
- -------------------
- Django does not accept experimental features. All features must follow our
- :ref:`deprecation policy <internal-release-deprecation-policy>`. Hence, it can
- take months or years for Django to iterate on an API design.
- If you need user feedback on a public interface, it is better to create a
- third-party package first. You can iterate on the public API much faster, while
- also validating the need for the feature.
- Once this package becomes stable and there are clear benefits of incorporating
- aspects into Django core, starting a discussion on the `Django Forum`_ or
- |django-developers| mailing list would be the next step.
- Django Enhancement Proposal (DEP)
- ---------------------------------
- Similar to Python’s PEPs, Django has `Django Enhancement Proposals`_ or DEPs. A
- DEP is a design document which provides information to the Django community, or
- describes a new feature or process for Django. They provide concise technical
- specifications of features, along with rationales. DEPs are also the primary
- mechanism for proposing and collecting community input on major new features.
- Before considering writing a DEP, it is recommended to first open a discussion
- on the `Django Forum`_ or |django-developers| mailing list. This allows the
- community to provide feedback and helps refine the proposal. Once the DEP is
- ready the :ref:`Steering Council <steering-council>` votes on whether to accept
- it.
- Some examples of DEPs that have been approved and fully implemented:
- * `DEP 181: ORM Expressions <https://github.com/django/deps/blob/main/final/0181-orm-expressions.rst>`_
- * `DEP 182: Multiple Template Engines <https://github.com/django/deps/blob/main/final/0182-multiple-template-engines.rst>`_
- * `DEP 201: Simplified routing syntax <https://github.com/django/deps/blob/main/final/0201-simplified-routing-syntax.rst>`_
- .. _Django Forum: https://forum.djangoproject.com/
- .. _Django Enhancement Proposals: https://github.com/django/deps
- .. _deprecating-a-feature:
- Deprecating a feature
- =====================
- There are a couple of 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
- ``RemovedInDjangoXXWarning`` (where XX is the Django version where the feature
- will be removed) when the deprecated feature is invoked. Assuming we have good
- test coverage, these warnings are converted to errors when :ref:`running the
- test suite <running-unit-tests>` with warnings enabled:
- ``python -Wa runtests.py``. Thus, when adding a ``RemovedInDjangoXXWarning``
- 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 by using the ``ignore_warnings`` decorator, either at the test or class
- level:
- #) In a particular test::
- from django.test import ignore_warnings
- from django.utils.deprecation import RemovedInDjangoXXWarning
- @ignore_warnings(category=RemovedInDjangoXXWarning)
- def test_foo(self): ...
- #) For an entire test case::
- from django.test import ignore_warnings
- from django.utils.deprecation import RemovedInDjangoXXWarning
- @ignore_warnings(category=RemovedInDjangoXXWarning)
- class MyDeprecatedTests(unittest.TestCase): ...
- You should also add a test for the deprecation warning::
- from django.utils.deprecation import RemovedInDjangoXXWarning
- def test_foo_deprecation_warning(self):
- msg = "Expected deprecation message"
- with self.assertWarnsMessage(RemovedInDjangoXXWarning, msg) as ctx:
- # invoke deprecated behavior
- ...
- self.assertEqual(ctx.filename, __file__)
- It's important to include a ``RemovedInDjangoXXWarning`` comment above code
- which has no warning reference, but will need to be changed or removed when the
- deprecation ends. This could include hooks which have been added to keep the
- previous behavior, or standalone items that are unnecessary or unused when the
- deprecation ends. For example::
- import warnings
- from django.utils.deprecation import RemovedInDjangoXXWarning
- # RemovedInDjangoXXWarning.
- def old_private_helper():
- # Helper function that is only used in foo().
- pass
- def foo():
- warnings.warn(
- "foo() is deprecated.",
- category=RemovedInDjangoXXWarning,
- stacklevel=2,
- )
- old_private_helper()
- ...
- 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 appropriate version describing what code will be removed.
- Once you have completed these steps, you are finished with the deprecation.
- In each :term:`feature release <Feature release>`, all
- ``RemovedInDjangoXXWarning``\s matching the new version are removed.
- JavaScript contributions
- ========================
- For information on JavaScript contributions, see the :ref:`javascript-patches`
- documentation.
- Optimization patches
- ====================
- Patches aiming to deliver a performance improvement should provide benchmarks
- showing the before and after impact of the patch and sharing the commands for
- reviewers to reproduce.
- .. _django-asv-benchmarks:
- ``django-asv`` benchmarks
- -------------------------
- `django-asv`_ monitors the performance of Django code over time. These
- benchmarks can be run on a pull request by labeling the pull request with
- ``benchmark``. Adding to these benchmarks is highly encouraged.
- .. _django-asv: https://github.com/django/django-asv/
- .. _patch-review-checklist:
- Contribution checklist
- ======================
- Use this checklist to review a pull request. If this contribution would not be
- :ref:`considered trivial <trivial-change>`, first ensure it has an accepted
- ticket before proceeding with the review.
- If the pull request passes all the criteria below and is not your own, please
- set the "Triage Stage" on the corresponding Trac ticket to "Ready for checkin".
- If you've left comments for improvement on the pull request, please tick the
- appropriate flags on the Trac ticket based on the results of your review:
- "Patch needs improvement", "Needs documentation", and/or "Needs tests". As time
- and interest permits, mergers do final reviews of "Ready for checkin" tickets
- and will either commit the changes or bump it back to "Accepted" if further
- work needs to be done.
- If you're looking to become a member of the `triage & review team
- <https://www.djangoproject.com/foundation/teams/#triage-review-team>`_, doing
- thorough reviews of contributions is a great way to earn trust.
- Looking for a patch to review? Check out the "Patches needing review" section
- of the `Django Development Dashboard <https://dashboard.djangoproject.com/>`_.
- Looking to get your pull request reviewed? Ensure the Trac flags on the ticket
- are set so that the ticket appears in that queue.
- Documentation
- -------------
- * Does the documentation build without any errors (``make html``, or
- ``make.bat html`` on Windows, from the ``docs`` directory)?
- * Does the documentation follow the writing style guidelines in
- :doc:`/internals/contributing/writing-documentation`?
- * Are there any :ref:`spelling errors <documentation-spelling-check>`?
- Bugs
- ----
- * Is there a proper regression test (the test should fail before the fix
- is applied)?
- * If it's a bug that :ref:`qualifies for a backport <supported-versions-policy>`
- to the stable version of Django, is there a release note in
- ``docs/releases/A.B.C.txt``? Bug fixes that will be applied only to the main
- branch don't need a release note.
- New Features
- ------------
- * Are there tests to "exercise" all of the new code?
- * Is there a release note in ``docs/releases/A.B.txt``?
- * Is there documentation for the feature and is it :ref:`annotated
- appropriately <documenting-new-features>` with
- ``.. versionadded:: A.B`` or ``.. versionchanged:: A.B``?
- Deprecating a feature
- ---------------------
- See the :ref:`deprecating-a-feature` guide.
- All code changes
- ----------------
- * Does the :doc:`coding style
- </internals/contributing/writing-code/coding-style>` conform to our
- guidelines? Are there any ``black``, ``blacken-docs``, ``flake8``, or
- ``isort`` errors? You can install the :ref:`pre-commit
- <coding-style-pre-commit>` hooks to automatically catch these errors.
- * If the change is backwards incompatible in any way, is there a note
- in the release notes (``docs/releases/A.B.txt``)?
- * Is Django's test suite passing?
- All tickets
- -----------
- * Is the pull request a single squashed commit with a message that follows our
- :ref:`commit message format <committing-guidelines>`?
- * Are you the patch author and a new contributor? Please add yourself to the
- :source:`AUTHORS` file and submit a `Contributor License Agreement`_.
- * Does this have an accepted ticket on Trac? All contributions require a ticket
- unless the :ref:`change is considered trivial <trivial-change>`.
- .. _Contributor License Agreement: https://www.djangoproject.com/foundation/cla/
|