From 407f62fd31689b6158902d3ffdcde64aa27679a7 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Fri, 27 May 2011 10:49:47 +0000 Subject: [PATCH] Fixed #15796 -- Restructured the contributing documentation and added note about newly added Trac abilities. Many thanks to Julien Phalip. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16284 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/howto/contribute.txt | 321 ---- docs/howto/index.txt | 1 - docs/index.txt | 4 +- docs/internals/committers.txt | 2 + docs/internals/contributing.txt | 1377 ----------------- .../contributing/bugs-and-features.txt | 181 +++ .../contributing/committing-code.txt | 133 ++ docs/internals/contributing/index.txt | 48 + .../contributing/new-contributors.txt | 137 ++ docs/internals/contributing/translations.txt | 60 + .../contributing/triaging-tickets.txt | 389 +++++ .../writing-code/branch-policy.txt | 180 +++ .../writing-code/coding-style.txt | 190 +++ .../contributing/writing-code/index.txt | 15 + .../writing-code/submitting-patches.txt | 160 ++ .../contributing/writing-code/unit-tests.txt | 167 ++ .../writing-documentation.txt} | 186 ++- docs/internals/index.txt | 5 +- 18 files changed, 1806 insertions(+), 1750 deletions(-) delete mode 100644 docs/howto/contribute.txt delete mode 100644 docs/internals/contributing.txt create mode 100644 docs/internals/contributing/bugs-and-features.txt create mode 100644 docs/internals/contributing/committing-code.txt create mode 100644 docs/internals/contributing/index.txt create mode 100644 docs/internals/contributing/new-contributors.txt create mode 100644 docs/internals/contributing/translations.txt create mode 100644 docs/internals/contributing/triaging-tickets.txt create mode 100644 docs/internals/contributing/writing-code/branch-policy.txt create mode 100644 docs/internals/contributing/writing-code/coding-style.txt create mode 100644 docs/internals/contributing/writing-code/index.txt create mode 100644 docs/internals/contributing/writing-code/submitting-patches.txt create mode 100644 docs/internals/contributing/writing-code/unit-tests.txt rename docs/internals/{documentation.txt => contributing/writing-documentation.txt} (51%) diff --git a/docs/howto/contribute.txt b/docs/howto/contribute.txt deleted file mode 100644 index 5d17ae69aa..0000000000 --- a/docs/howto/contribute.txt +++ /dev/null @@ -1,321 +0,0 @@ -=========================== -How to contribute to Django -=========================== - -Django is developed 100% by the community, and the more people that are actively -involved in the code the better Django will be. We recognize that contributing -to Django can be daunting at first and sometimes confusing even to -veterans. While we have our official "Contributing to Django" documentation -which spells out the technical details of triaging tickets and submitting -patches, it leaves a lot of room for interpretation. This guide aims to offer -more general advice on issues such as how to interpret the various stages and -flags in Trac, and how new contributors can get started. - -.. seealso:: - - This guide is meant to answer the most common questions about - contributing to Django, however it is no substitute for the - :doc:`/internals/contributing` reference. Please make sure to - read that document to understand the specific details - involved in reporting issues and submitting patches. - -.. _the-spirit-of-contributing: - -"The Spirit of Contributing" -============================ - -Django uses Trac_ for managing our progress, and Trac is a community-tended -garden of the bugs people have found and the features people would like to see -added. As in any garden, sometimes there are weeds to be pulled and sometimes -there are flowers and vegetables that need picking. We need your help to sort -out one from the other, and in the end we all benefit together. - -Like all gardens, we can aspire to perfection but in reality there's no such -thing. Even in the most pristine garden there are still snails and insects. In a -community garden there are also helpful people who--with the best of -intentions--fertilize the weeds and poison the roses. It's the job of the -community as a whole to self-manage, keep the problems to a minimum, and educate -those coming into the community so that they can become valuable contributing -members. - -Similarly, while we aim for Trac to be a perfect representation of the state of -Django's progress, we acknowledge that this simply will not happen. By -distributing the load of Trac maintenance to the community, we accept that there -will be mistakes. Trac is "mostly accurate", and we give allowances for the fact -that sometimes it will be wrong. That's okay. We're perfectionists with -deadlines. - -We rely on the community to keep participating, keep tickets as accurate as -possible, and raise issues for discussion on our mailing lists when there is -confusion or disagreement. - -Django is a community project, and every contribution helps. We can't do this -without YOU! - -.. _Trac: http://code.djangoproject.com/ - -Understanding Trac -================== - -Trac is Django's sole official issue tracker. All known bugs, desired features -and ideas for changes are logged there. - -However, Trac can be quite confusing even to veteran contributors. Having to -look at both flags and triage stages isn't immediately obvious, and the stages -themselves can be misinterpreted. - -.. _triage-stages-explained: - -What Django's triage stages "really mean" ------------------------------------------ - -Unreviewed -~~~~~~~~~~ - -The ticket has not been reviewed by anyone who felt qualified to make a judgment -about whether the ticket contained a valid issue, a viable feature, or ought to -be closed for any of the various reasons. - -Accepted -~~~~~~~~ - -The big grey area! The absolute meaning of "accepted" is that the issue -described in the ticket is valid and is in some stage of being worked on. Beyond -that there are several considerations - - -* **Accepted + No Flags** - - The ticket is valid, but no one has submitted a patch for it yet. Often this - means you could safely start writing a patch for it. - -* **Accepted + Has Patch** - - The ticket is waiting for people to review the supplied patch. This means - downloading the patch and trying it out, verifying that it contains tests and - docs, running the test suite with the included patch, and leaving feedback on - the ticket. - - -* **Accepted + Has Patch + (any other flag)** - - This means the ticket has been reviewed, and has been found to need further - work. "Needs tests" and "Needs documentation" are self-explanatory. "Patch - needs improvement" will generally be accompanied by a comment on the ticket - explaining what is needed to improve the code. - -Design Decision Needed -~~~~~~~~~~~~~~~~~~~~~~ - -This stage is for issues which may be contentious, may be backwards -incompatible, or otherwise involve high-level design decisions. These decisions -are generally made by the core committers, however that is not a -requirement. See the FAQ below for "My ticket has been in DDN forever! What -should I do?" - -Ready For Checkin -~~~~~~~~~~~~~~~~~ - -The ticket was reviewed by any member of the community other than the person who -supplied the patch and found to meet all the requirements for a commit-ready -patch. A core committer now needs to give the patch a final review prior to -being committed. See the FAQ below for "My ticket has been in RFC forever! What -should I do?" - -Someday/Maybe? -~~~~~~~~~~~~~~ - -Generally only used for vague/high-level features or design ideas. These tickets -are uncommon and overall less useful since they don't describe concrete -actionable issues. - -Fixed on a branch -~~~~~~~~~~~~~~~~~ - -Used to indicate that a ticket is resolved as part of a major body of work that -will eventually be merged to trunk. Tickets in this stage generally don't need -further work. This may happen in the case of major features/refactors in each -release cycle, or as part of the annual Google Summer of Code efforts. - -.. _closing-tickets: - -Closing Tickets ---------------- - -When a ticket has completed its useful lifecycle, it's time for it to be closed. -Closing a ticket is a big responsibility, though. You have to be sure that -the issue is really resolved, and you need to keep in mind that the reporter -of the ticket may not be happy to have their ticket closed (unless it's fixed, -of course). If you're not certain about closing a ticket, just leave a comment -with your thoughts instead. - -If you do close a ticket, you should always make sure of the following: - - * Be certain that the issue is resolved. - - * Leave a comment explaining the decision to close the ticket. - - * If there is a way they can improve the ticket to reopen it, let them know. - - * If the ticket is a duplicate, reference the original ticket. - - * **Be polite.** No one likes having their ticket closed. It can be - frustrating or even discouraging. The best way to avoid turning people - off from contributing to Django is to be polite and friendly and to offer - suggestions for how they could improve this ticket and other tickets in the - future. - -.. seealso:: - - The :ref:`contributing reference ` contains a - description of each of the available resolutions in Trac. - -Example Trac workflow ---------------------- - -Here we see the life-cycle of an average ticket: - -* Alice creates a ticket, and uploads an incomplete patch (no tests, incorrect - implementation). - -* Bob reviews the patch, marks it "Accepted", "needs tests", and "patch needs - improvement", and leaves a comment telling Alice how the patch could be - improved. - -* Alice updates the patch, adding tests (but not changing the - implementation). She removes the two flags. - -* Charlie reviews the patch and resets the "patch needs improvement" flag with - another comment about improving the implementation. - -* Alice updates the patch, fixing the implementation. She removes the "patch - needs improvement" flag. - -* Daisy reviews the patch, and marks it RFC. - -* Jacob reviews the RFC patch, applies it to his checkout, and commits it. - -Some tickets require much less feedback than this, but then again some tickets -require much much more. - -Advice for new contributors -=========================== - -New contributor and not sure what to do? Want to help but just don't know how to -get started? This is the section for you. - -* **Pick a subject area that you care about, that you are familiar with, or that - you want to learn about.** - - You don't already have to be an expert on the area you want to work on; you - become an expert through your ongoing contributions to the code. - -* **Triage tickets.** - - If a ticket is unreviewed and reports a bug, try and duplicate it. If you can - duplicate it and it seems valid, make a note that you confirmed the bug and - accept the ticket. Make sure the ticket is filed under the correct component - area. Consider writing a patch that adds a test for the bug's behavior, even - if you don't fix the bug itself. - -* **Look for tickets that are accepted and review patches to build familiarity - with the codebase and the process.** - - Mark the appropriate flags if a patch needs docs or tests. Look through the - changes a patch makes, and keep an eye out for syntax that is incompatible - with older but still supported versions of Python. Run the tests and make sure - they pass on your system. Where possible and relevant, try them out on a - database other than SQLite. Leave comments and feedback! - -* **Keep old patches up to date.** - - Oftentimes the codebase will change between a patch being submitted and the - time it gets reviewed. Make sure it still applies cleanly and functions as - expected. Simply updating a patch is both useful and important! - -* **Trac isn't an absolute; the context is just as important as the words.** - - When reading Trac, you need to take into account who says things, and when - they were said. Support for an idea two years ago doesn't necessarily mean - that the idea will still have support. You also need to pay attention to who - *hasn't* spoken -- for example, if a core team member hasn't been recently - involved in a discussion, then a ticket may not have the support required to - get into trunk. - -* **Start small.** - - It's easier to get feedback on a little issue than on a big one. - -* **If you're going to engage in a big task, make sure that your idea has - support first.** - - This means getting someone else to confirm that a bug is real before you fix - the issue, and ensuring that the core team supports a proposed feature before - you go implementing it. - -* **Be bold! Leave feedback!** - - Sometimes it can be scary to put your opinion out to the world and say "this - ticket is correct" or "this patch needs work", but it's the only way the - project moves forward. The contributions of the broad Django community - ultimately have a much greater impact than that of the core developers. We - can't do it without YOU! - -* **Err on the side of caution when marking things Ready For Check-in.** - - If you're really not certain if a ticket is ready, don't mark it as - such. Leave a comment instead, letting others know your thoughts. If you're - mostly certain, but not completely certain, you might also try asking on IRC - to see if someone else can confirm your suspicions. - -* **Wait for feedback, and respond to feedback that you receive.** - - Focus on one or two tickets, see them through from start to finish, and - repeat. The shotgun approach of taking on lots of tickets and letting some - fall by the wayside ends up doing more harm than good. - -* **Be rigorous.** - - When we say ":pep:`8`, and must have docs and tests", we mean it. If a patch - doesn't have docs and tests, there had better be a good reason. Arguments like - "I couldn't find any existing tests of this feature" don't carry much - weight--while it may be true, that means you have the extra-important job of - writing the very first tests for that feature, not that you get a pass from - writing tests altogether. - -.. note:: - - The `Reports page`_ contains links to many useful Trac queries, including - several that are useful for triaging tickets and reviewing patches as - suggested above. - - .. _Reports page: http://code.djangoproject.com/wiki/Reports - - -FAQs -==== - -**This ticket I care about has been ignored for days/weeks/months! What can I do -to get it committed?** - -* First off, it's not personal. Django is entirely developed by volunteers (even - the core devs), and sometimes folks just don't have time. The best thing to do - is to send a gentle reminder to the Django Developers mailing list asking for - review on the ticket, or to bring it up in the #django-dev IRC channel. - - -**I'm sure my ticket is absolutely 100% perfect, can I mark it as RFC myself?** - -* Short answer: No. It's always better to get another set of eyes on a - ticket. If you're having trouble getting that second set of eyes, see question - 1, above. - - -**My ticket has been in DDN forever! What should I do?** - -* Design Decision Needed requires consensus about the right solution. At the - very least it needs consensus among the core developers, and ideally it has - consensus from the community as well. The best way to accomplish this is to - start a thread on the Django Developers mailing list, and for very complex - issues to start a wiki page summarizing the problem and the possible - solutions. diff --git a/docs/howto/index.txt b/docs/howto/index.txt index 7ce7d26ceb..49d0644034 100644 --- a/docs/howto/index.txt +++ b/docs/howto/index.txt @@ -11,7 +11,6 @@ you quickly accomplish common tasks. apache-auth auth-remote-user - contribute custom-management-commands custom-model-fields custom-template-tags diff --git a/docs/index.txt b/docs/index.txt index 8b4ae53bc2..2c090d98c5 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -200,7 +200,7 @@ The Django open-source project ============================== * **Community:** - :doc:`How to get involved ` | + :doc:`How to get involved ` | :doc:`The release process ` | :doc:`Team of committers ` | :doc:`The Django source code repository ` @@ -209,7 +209,7 @@ The Django open-source project :doc:`Overview ` * **Documentation:** - :doc:`About this documentation ` + :doc:`About this documentation ` * **Third-party distributions:** :doc:`Overview ` diff --git a/docs/internals/committers.txt b/docs/internals/committers.txt index ab102156e7..7b727d6cfd 100644 --- a/docs/internals/committers.txt +++ b/docs/internals/committers.txt @@ -58,6 +58,8 @@ Current developers Currently, Django is led by a team of volunteers from around the globe. +.. _django-bdfls: + BDFLs ----- diff --git a/docs/internals/contributing.txt b/docs/internals/contributing.txt deleted file mode 100644 index 4e2bad91ad..0000000000 --- a/docs/internals/contributing.txt +++ /dev/null @@ -1,1377 +0,0 @@ -====================== -Contributing to Django -====================== - -If you think working *with* Django is fun, wait until you start working *on* -it. We're passionate about helping Django users make the jump to contributing -members of the community, so there are many ways you can help Django's -development: - - * Blog about Django. We syndicate all the Django blogs we know about on - the `community page`_; contact jacob@jacobian.org if you've got a blog - you'd like to see on that page. - - * Report bugs and request features in our `ticket tracker`_. Please read - `Reporting bugs`_, below, for the details on how we like our bug reports - served up. - - * Submit patches for new and/or fixed behavior. Please read `Submitting - patches`_, below, for details on how to submit a patch. If you're looking - for an easy way to start contributing to Django have a look at the - `easy-pickings`_ tickets. - - * Join the `django-developers`_ mailing list and share your ideas for how - to improve Django. We're always open to suggestions, although we're - likely to be skeptical of large-scale suggestions without some code to - back it up. - - * Triage patches that have been submitted by other users. Please read - `Ticket triage`_ below, for details on the triage process. - -That's all you need to know if you'd like to join the Django development -community. The rest of this document describes the details of how our community -works and how it handles bugs, mailing lists, and all the other minutiae of -Django development. - -.. seealso:: - - This document contains specific details for contributing to - Django. However, many new contributors find this guide confusing - or intimidating at first. For a simpler introduction - to becoming a contributor please see the :doc:`/howto/contribute` guide. - -.. _reporting-bugs: - -Reporting bugs -============== - -Well-written bug reports are *incredibly* helpful. However, there's a certain -amount of overhead involved in working with any bug tracking system so your -help in keeping our ticket tracker as useful as possible is appreciated. In -particular: - - * **Do** read the :doc:`FAQ ` to see if your issue might - be a well-known question. - - * **Do** `search the tracker`_ to see if your issue has already been filed. - - * **Do** ask on `django-users`_ *first* if you're not sure if what you're - seeing is a bug. - - * **Do** write complete, reproducible, specific bug reports. Include as - much information as you possibly can, complete with code snippets, test - cases, etc. This means including a clear, concise description of the - problem, and a clear set of instructions for replicating the problem. - A minimal example that illustrates the bug in a nice small test case - is the best possible bug report. - - * **Don't** use the ticket system to ask support questions. Use the - `django-users`_ list, or the `#django`_ IRC channel for that. - - * **Don't** use the ticket system to make large-scale feature requests. - We like to discuss any big changes to Django's core on the - `django-developers`_ list before actually working on them. - - * **Don't** reopen issues that have been marked "wontfix". This mark - means that the decision has been made that we can't or won't fix - this particular issue. If you're not sure why, please ask - on `django-developers`_. - - * **Don't** use the ticket tracker for lengthy discussions, because they're - likely to get lost. If a particular ticket is controversial, please move - discussion to `django-developers`_. - - * **Don't** post to django-developers just to announce that you have filed - a bug report. All the tickets are mailed to another list - (`django-updates`_), which is tracked by developers and interested - community members; we see them as they are filed. - -.. _django-updates: http://groups.google.com/group/django-updates - -.. _reporting-security-issues: - -Reporting security issues -========================= - -Report security issues to security@djangoproject.com. This is a private list -only open to long-time, highly trusted Django developers, and its archives are -not publicly readable. - -In the event of a confirmed vulnerability in Django itself, we will take the -following actions: - - * Acknowledge to the reporter that we've received the report and that a - fix is forthcoming. We'll give a rough timeline and ask the reporter - to keep the issue confidential until we announce it. - - * Focus on developing a fix as quickly as possible and produce patches - against the current and two previous releases. - - * Determine a go-public date for announcing the vulnerability and the fix. - To try to mitigate a possible "arms race" between those applying the - patch and those trying to exploit the hole, we will not announce - security problems immediately. - - * Pre-notify third-party distributors of Django ("vendors"). We will send - these vendor notifications through private email which will include - documentation of the vulnerability, links to the relevant patch(es), and a - request to keep the vulnerability confidential until the official - go-public date. - - * Publicly announce the vulnerability and the fix on the pre-determined - go-public date. This will probably mean a new release of Django, but - in some cases it may simply be patches against current releases. - -Submitting patches -================== - -We're always grateful for patches to Django's code. Indeed, bug reports -with associated patches will get fixed *far* more quickly than those -without patches. - -"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: - - * `Create an account`_ to use in our ticket system. - - * 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 "Assigned to" section of the ticket. - If it's assigned to "nobody," then it's available to be claimed. - Otherwise, somebody else is working on this ticket, and you either find - another bug/feature to work on, or contact the developer working on the - ticket to offer your help. - - * Log into your account, if you haven't already, by clicking "Login" in the - upper right of the ticket page. - - * Claim the ticket by clicking the radio button next to "Accept ticket" - near the bottom of the page, then clicking "Submit changes." - -If you have an account but have forgotten your password, you can reset it -using the `password reset page`_. - -.. _Create an account: http://www.djangoproject.com/accounts/register/ -.. _password reset page: http://www.djangoproject.com/accounts/password/reset/ - -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? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Of course, 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. Just submit your patch and be done with -it. - -Patch style ------------ - - * Make sure your code matches our `coding style`_. - - * Submit patches in the format returned by the ``svn diff`` command. - An exception is for code changes that are described more clearly in - plain English than in code. Indentation is the most common example; it's - hard to read patches when the only difference in code is that it's - indented. - - Patches in ``git diff`` format are also acceptable. - - * When creating patches, always run ``svn diff`` from the top-level - ``trunk`` directory -- i.e., the one that contains ``django``, ``docs``, - ``tests``, ``AUTHORS``, etc. This makes it easy for other people to - apply your patches. - - * 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. - - * Check the "Has patch" box on the ticket details. This will make it - obvious that the ticket includes a patch, and it will add the ticket to - the `list of tickets with patches`_. - - * The code required to fix a problem or add a feature is an essential part - of a patch, but it is not the only part. A good patch should also include - a regression test to validate the behavior that has been fixed - (and prevent the problem from arising again). - - * If the code associated with a patch adds a new feature, or modifies - behavior of an existing feature, the patch should also contain - documentation. - -Non-trivial patches -------------------- - -A "non-trivial" patch is one that is more than a simple bug fix. It's a patch -that introduces Django functionality and makes some sort of design decision. - -If you provide a non-trivial patch, include evidence that alternatives have -been discussed on `django-developers`_. If you're not sure whether your patch -should be considered non-trivial, just ask. - -Ticket triage -============= - -Unfortunately, not all bug reports in the `ticket tracker`_ provide all -the `required details`_. A number of tickets have patches, but those patches -don't meet all the requirements of a `good patch`_. - -One way to help out is to *triage* bugs that have been reported by other -users. The core team--as well as many community members--work on this -regularly, but more help is always appreciated. - -Most of the workflow is based around the concept of a ticket's "triage stage". -This stage describes where in its lifetime a given ticket is at any time. -Along with a handful of flags, this field easily tells us what and who each -ticket is waiting on. - -Since a picture is worth a thousand words, let's start there: - -.. image:: _images/djangotickets.png - :height: 451 - :width: 590 - :alt: Django's ticket workflow - -We've got two roles in this diagram: - - * Core developers: people with commit access who are responsible for - making the big decisions, writing large portions of the code and - integrating the contributions of the community. - - * Ticket triagers: anyone in the Django community who chooses to - become involved in Django's development process. Our Trac installation - is :ref:`intentionally left open to the public - `, and anyone can triage tickets. - Django is a community project, and we encourage `triage by the - community`_. - -Triage stages -------------- - -Second, note the five triage stages: - - 1. A ticket starts as **Unreviewed**, meaning that nobody has examined - the ticket. - - 2. **Design decision needed** means "this concept requires a design - decision," which should be discussed either in the ticket comments or on - `django-developers`_. The "Design decision needed" step will generally - only be used for feature requests. It can also be used for issues - that *might* be bugs, depending on opinion or interpretation. Obvious - bugs (such as crashes, incorrect query results, or non-compliance with a - standard) skip this step and move straight to "Accepted". - - 3. Once a ticket is ruled to be approved for fixing, it's moved into the - **Accepted** stage. This stage is where all the real work gets done. - - 4. In some cases, a ticket might get moved to the **Someday/Maybe** state. - This means the ticket is an enhancement request that we might consider - adding to the framework if an excellent patch is submitted. These - tickets are not a high priority. - - 5. If a ticket has an associated patch (see below), it will be reviewed - by the community. If the patch is complete, it'll be marked as **Ready - for checkin** so that a core developer knows to review and commit the - patch. - -The second part of this workflow involves a set of flags the describe what the -ticket has or needs in order to be "ready for checkin": - - "Has patch" - This means the ticket has an associated patch_. These will be - reviewed to see if the patch is "good". - - "Needs documentation" - This flag is used for tickets with patches that need associated - documentation. Complete documentation of features is a prerequisite - before we can check them into the codebase. - - "Needs tests" - This flags the patch as needing associated unit tests. Again, this is a - required part of a valid patch. - - "Patch needs improvement" - This flag means that although the ticket *has* a patch, it's not quite - ready for checkin. This could mean the patch no longer applies - cleanly, there is a flaw in the implementation, or that the code - doesn't meet our standards. - -.. seealso:: - - The :ref:`contributing howto guide ` has a detailed - explanation of each of the triage stages and how the triage process works in - Trac. - -.. _ticket-resolutions: - -Ticket Resolutions ------------------- - -A ticket can be resolved in a number of ways: - - "fixed" - Used by the core developers once a patch has been rolled into - Django and the issue is fixed. - - "invalid" - Used if the ticket is found to be incorrect. This means that the - issue in the ticket is actually the result of a user error, or - describes a problem with something other than Django, or isn't - a bug report or feature request at all (for example, some new users - submit support queries as tickets). - - "wontfix" - Used when a core developer decides that this request is not - appropriate for consideration in Django. This is usually chosen after - discussion in the ``django-developers`` mailing list. Feel free to - start or join in discussions of "wontfix" tickets on the mailing list, - but please do not reopen tickets closed as "wontfix" by core - developers. - - "duplicate" - Used when another ticket covers the same issue. By closing duplicate - tickets, we keep all the discussion in one place, which helps everyone. - - "worksforme" - Used when the ticket doesn't contain enough detail to replicate - the original bug. - - "needsinfo" - Used when the ticket does not contain enough information to replicate - the reported issue but is potentially still valid. The ticket - should be reopened when more information is supplied. - -If you believe that the ticket was closed in error -- because you're -still having the issue, or it's popped up somewhere else, or the triagers have -made a mistake -- please reopen the ticket and provide further information. -Please do not reopen tickets that have been marked as "wontfix" by core -developers. - -.. seealso:: - - For more information on what to do when closing a ticket, please see the - :ref:`contributing howto guide `. - -.. _required details: `Reporting bugs`_ -.. _good patch: `Patch style`_ -.. _triage by the community: `Triage by the general community`_ -.. _patch: `Submitting patches`_ - -Triage by the general community -------------------------------- - -Although the core developers make the big decisions in the ticket triage -process, there's a lot that general community members can do to help the -triage process. In particular, you can help out by: - - * Closing "Unreviewed" tickets as "invalid", "worksforme" or "duplicate." - - * Promoting "Unreviewed" tickets to "Design decision needed" if a design - decision needs to be made, or "Accepted" in case of obvious bugs. - - * Correcting the "Needs tests", "Needs documentation", or "Has patch" - flags for tickets where they are incorrectly set. - - * Adding the `easy-pickings`_ keyword to tickets that are small and - relatively straightforward. - - * Checking that old tickets are still valid. If a ticket hasn't seen - any activity in a long time, it's possible that the problem has been - fixed but the ticket hasn't yet been closed. - - * Contacting the owners of tickets that have been claimed but have not - seen any recent activity. If the owner doesn't respond after a week - or so, remove the owner's claim on the ticket. - - * Identifying trends and themes in the tickets. If there a lot of bug - reports about a particular part of Django, it may indicate we should - consider refactoring that part of the code. If a trend is emerging, - you should raise it for discussion (referencing the relevant tickets) - on `django-developers`_. - -However, we do ask the following of all general community members working in -the ticket database: - - * Please **don't** close tickets as "wontfix." The core developers will - make the final determination of the fate of a ticket, usually after - consultation with the community. - - * Please **don't** promote your own tickets to "Ready for checkin". You - may mark other people's tickets which you've reviewed as "Ready for - checkin", but you should get at minimum one other community member to - review a patch that you submit. - - * Please **don't** reverse a decision that has been made by a core - developer. If you disagree with a decision that has been made, - please post a message to `django-developers`_. - - * If you're unsure if you should be making a change, don't make the change - but instead leave a comment with your concerns on the ticket, or - post a message to `django-developers`_. It's okay to be unsure, but - your input is still valuable. - -.. _contributing-translations: - -Submitting and maintaining translations -======================================= - -Various parts of Django, such as the admin site and validation error messages, -are internationalized. This means they display different text depending on a -user's language setting. For this, Django uses the same internationalization -infrastructure available to Django applications described in the -:doc:`i18n documentation`. - -These translations are contributed by Django users worldwide. If you find an -incorrect translation or want to discuss specific translations, go to the -`translation team`_ page for that language. If you would like to help out -with translating or add a language that isn't yet translated, here's what -to do: - - * Join the `Django i18n mailing list`_ and introduce yourself. - - * Make sure you read the notes about :ref:`specialties-of-django-i18n`. - - * Signup at `Transifex`_ and visit the `Django project page`_. - - * On the "`Translation Teams`_" page, choose the language team you want - to work with, **or** -- in case the language team doesn't exist yet -- - request a new team by clicking on the "Request a new team" button - and select the appropriate language. - - * Then, click the "Join this Team" button to become a member of this team. - Every team has at least one coordinator who is responsible to review - your membership request. You can of course also contact the team - coordinator to clarify procedural problems and handle the actual - translation process. - - * Once you are a member of a team choose the translation resource you - want update on the team page. For example the "core" resource refers - to the translation catalogue that contains all non-app translations. - Each of the contrib apps also have a resource (prefixed with "contrib-"). - - .. note:: - For more information about how to use Transifex, see the - `Transifex Help`_ - - * Optionally, review and update the ``conf/locale//formats.py`` - file to describe the date, time and numbers formatting particularities - of your locale. These files aren't covered by the use of Transifex and - require a patch against the Django source tree, just as a code change - would: - - * Create a diff against the current Subversion trunk. - - * Open a ticket in Django's ticket system, set its ``Component`` field - to ``Translations``, and attach the patch to it. See - :ref:`format-localization` for details. - -.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/ -.. _Transifex: http://www.transifex.net/ -.. _Django project page: http://www.transifex.net/projects/p/django/ -.. _translation teams: http://www.transifex.net/projects/p/django/teams/ -.. _translation team: http://www.transifex.net/projects/p/django/teams/ -.. _Transifex Help: http://help.transifex.net/ - -Submitting javascript patches -============================= - -.. versionadded:: 1.2 - -Django's admin system leverages the jQuery framework to increase the -capabilities of the admin interface. In conjunction, there is an emphasis on -admin javascript performance and minimizing overall admin media file size. -Serving compressed or "minified" versions of javascript files is considered -best practice in this regard. - -To that end, patches for javascript files should include both the original -code for future development (e.g. "foo.js"), and a compressed version for -production use (e.g. "foo.min.js"). Any links to the file in the codebase -should point to the compressed version. - -To simplify the process of providing optimized javascript code, Django -includes a handy script which should be used to create a "minified" version. -This script is located at ``/contrib/admin/media/js/compress.py``. - -Behind the scenes, ``compress.py`` is a front-end for Google's -`Closure Compiler`_ which is written in Java. However, the Closure Compiler -library is not bundled with Django directly, so those wishing to contribute -complete javascript patches will need to download and install the library -independently. - -The Closure Compiler library requires Java version 6 or higher (Java 1.6 or -higher on Mac OS X). Note that Mac OS X 10.5 and earlier did not ship with Java -1.6 by default, so it may be necessary to upgrade your Java installation before -the tool will be functional. Also note that even after upgrading Java, the -default `/usr/bin/java` command may remain linked to the previous Java -binary, so relinking that command may be necessary as well. - -Please don't forget to run ``compress.py`` and include the ``diff`` of the -minified scripts when submitting patches for Django's javascript. - -.. _Closure Compiler: http://code.google.com/closure/compiler/ - -Django conventions -================== - -Various Django-specific code issues are detailed in this section. - -Use of ``django.conf.settings`` -------------------------------- - -Modules should not in general use settings stored in ``django.conf.settings`` -at the top level (i.e. evaluated when the module is imported). The explanation -for this is as follows: - -Manual configuration of settings (i.e. not relying on the -``DJANGO_SETTINGS_MODULE`` environment variable) is allowed and possible as -follows:: - - from django.conf import settings - - settings.configure({}, SOME_SETTING='foo') - -However, if any setting is accessed before the ``settings.configure`` line, -this will not work. (Internally, ``settings`` is a ``LazyObject`` which -configures itself automatically when the settings are accessed if it has not -already been configured). - -So, if there is a module containing some code as follows:: - - from django.conf import settings - from django.core.urlresolvers import get_callable - - default_foo_view = get_callable(settings.FOO_VIEW) - -...then importing this module will cause the settings object to be configured. -That means that the ability for third parties to import the module at the top -level is incompatible with the ability to configure the settings object -manually, or makes it very difficult in some circumstances. - -Instead of the above code, a level of laziness or indirection must be used, -such as `django.utils.functional.LazyObject``, ``django.utils.functional.lazy`` -or ``lambda``. - -Coding style -============ - -Please follow these coding standards when writing code for inclusion in Django: - - * Unless otherwise specified, follow :pep:`8`. - - You could use a tool like `pep8.py`_ to check for some problems in this - area, but remember that PEP 8 is only a guide, so respect the style of - the surrounding code as a primary goal. - - * Use four spaces for indentation. - - * Use underscores, not camelCase, for variable, function and method names - (i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``). - - * Use ``InitialCaps`` for class names (or for factory functions that - return classes). - - * Mark all strings for internationalization; see the :doc:`i18n - documentation ` for details. - - * In docstrings, use "action words" such as:: - - def foo(): - """ - Calculates something and returns the result. - """ - pass - - Here's an example of what not to do:: - - def foo(): - """ - Calculate something and return the result. - """ - pass - - * Please don't put your name in the code you contribute. Our policy is to - keep contributors' names in the ``AUTHORS`` file distributed with Django - -- not scattered throughout the codebase itself. Feel free to include a - change to the ``AUTHORS`` file in your patch if you make more than a - single trivial change. - -Template style --------------- - - * In Django template code, put one (and only one) space between the curly - brackets and the tag contents. - - Do this: - - .. code-block:: html+django - - {{ foo }} - - Don't do this: - - .. code-block:: html+django - - {{foo}} - -View style ----------- - - * In Django views, the first parameter in a view function should be called - ``request``. - - Do this:: - - def my_view(request, foo): - # ... - - Don't do this:: - - def my_view(req, foo): - # ... - -Model style ------------ - - * Field names should be all lowercase, using underscores instead of - camelCase. - - Do this:: - - class Person(models.Model): - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=40) - - Don't do this:: - - class Person(models.Model): - FirstName = models.CharField(max_length=20) - Last_Name = models.CharField(max_length=40) - - * The ``class Meta`` should appear *after* the fields are defined, with - a single blank line separating the fields and the class definition. - - Do this:: - - class Person(models.Model): - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=40) - - class Meta: - verbose_name_plural = 'people' - - Don't do this:: - - class Person(models.Model): - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=40) - class Meta: - verbose_name_plural = 'people' - - Don't do this, either:: - - class Person(models.Model): - class Meta: - verbose_name_plural = 'people' - - first_name = models.CharField(max_length=20) - last_name = models.CharField(max_length=40) - - * The order of model inner classes and standard methods should be as - follows (noting that these are not all required): - - * All database fields - * Custom manager attributes - * ``class Meta`` - * ``def __unicode__()`` - * ``def __str__()`` - * ``def save()`` - * ``def get_absolute_url()`` - * Any custom methods - - * If ``choices`` is defined for a given model field, define the choices as - a tuple of tuples, with an all-uppercase name, either near the top of the - model module or just above the model class. Example:: - - GENDER_CHOICES = ( - ('M', 'Male'), - ('F', 'Female'), - ) - -Documentation style -=================== - -We place a high importance on consistency and readability of documentation. -(After all, Django was created in a journalism environment!) - -How to document new features ----------------------------- - -We treat our documentation like we treat our code: we aim to improve it as -often as possible. This section explains how writers can craft their -documentation changes in the most useful and least error-prone ways. - -Documentation changes come in two forms: - - * General improvements -- Typo corrections, error fixes and better - explanations through clearer writing and more examples. - - * New features -- Documentation of features that have been added to the - framework since the last release. - -Our policy is: - - **All documentation of new features should be written in a way that clearly - designates the features are only available in the Django development - version. Assume documentation readers are using the latest release, not the - development version.** - -Our preferred way for marking new features is by prefacing the features' -documentation with: ".. versionadded:: X.Y", followed by an optional one line -comment and a mandatory blank line. - -General improvements, or other changes to the APIs that should be emphasized -should use the ".. versionchanged:: X.Y" directive (with the same format as the -``versionadded`` mentioned above. - -There's a full page of information about the :doc:`Django documentation -system ` that you should read prior to working on the -documentation. - -Guidelines for reST files -------------------------- - -These guidelines regulate the format of our reST documentation: - - * In section titles, capitalize only initial words and proper nouns. - - * Wrap the documentation at 80 characters wide, unless a code example - is significantly less readable when split over two lines, or for another - good reason. - -Commonly used terms -------------------- - -Here are some style guidelines on commonly used terms throughout the -documentation: - - * **Django** -- when referring to the framework, capitalize Django. It is - lowercase only in Python code and in the djangoproject.com logo. - - * **email** -- no hyphen. - - * **MySQL** - - * **PostgreSQL** - - * **Python** -- when referring to the language, capitalize Python. - - * **realize**, **customize**, **initialize**, etc. -- use the American - "ize" suffix, not "ise." - - * **SQLite** - - * **subclass** -- it's a single word without a hyphen, both as a verb - ("subclass that model") and as a noun ("create a subclass"). - - * **Web**, **World Wide Web**, **the Web** -- note Web is always - capitalized when referring to the World Wide Web. - - * **Web site** -- use two words, with Web capitalized. - -Django-specific terminology ---------------------------- - - * **model** -- it's not capitalized. - - * **template** -- it's not capitalized. - - * **URLconf** -- use three capitalized letters, with no space before - "conf." - - * **view** -- it's not capitalized. - -Committing code -=============== - -Please follow these guidelines when committing code to Django's Subversion -repository: - - * For any medium-to-big changes, where "medium-to-big" is according to your - judgment, please bring things up on the `django-developers`_ mailing list - before making the change. - - If you bring something up on `django-developers`_ and nobody responds, - please don't take that to mean your idea is great and should be - implemented immediately because nobody contested it. Django's lead - developers don't have a lot of time to read mailing-list discussions - immediately, so you may have to wait a couple of days before getting a - response. - - * Write detailed commit messages in the past tense, not present tense. - - * Good: "Fixed Unicode bug in RSS API." - * Bad: "Fixes Unicode bug in RSS API." - * Bad: "Fixing Unicode bug in RSS API." - - * For commits to a branch, prefix the commit message with the branch name. - For example: "magic-removal: Added support for mind reading." - - * Limit commits to the most granular change that makes sense. This means, - use frequent small commits rather than infrequent large commits. For - example, if implementing feature X requires a small change to library Y, - first commit the change to library Y, then commit feature X in a separate - commit. This goes a *long way* in helping all core Django developers - follow your changes. - - * Separate bug fixes from feature changes. - - Bug fixes need to be added to the current bugfix branch (e.g. the - ``1.0.X`` branch) as well as the current trunk. - - * If your commit closes a ticket in the Django `ticket tracker`_, begin - your commit message with the text "Fixed #abc", where "abc" is the number - of the ticket your commit fixes. Example: "Fixed #123 -- Added support - for foo". We've rigged Subversion and Trac so that any commit message - in that format will automatically close the referenced ticket and post a - comment to it with the full commit message. - - If your commit closes a ticket and is in a branch, use the branch name - first, then the "Fixed #abc." For example: - "magic-removal: Fixed #123 -- Added whizbang feature." - - For the curious: We're using a `Trac post-commit hook`_ for this. - - .. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook - - * If your commit references a ticket in the Django `ticket tracker`_ but - does *not* close the ticket, include the phrase "Refs #abc", where "abc" - is the number of the ticket your commit references. We've rigged - Subversion and Trac so that any commit message in that format will - automatically post a comment to the appropriate ticket. - -Reverting commits ------------------ - -Nobody's perfect; mistakes will be committed. When a mistaken commit is -discovered, please follow these guidelines: - - * Try very hard to ensure that mistakes don't happen. Just because we - have a reversion policy doesn't relax your responsibility to aim for - the highest quality possible. Really: double-check your work before - you commit it in the first place! - - * If possible, have the original author revert his/her own commit. - - * Don't revert another author's changes without permission from the - original author. - - * If the original author can't be reached (within a reasonable amount - of time -- a day or so) and the problem is severe -- crashing bug, - major test failures, etc -- then ask for objections on django-dev - then revert if there are none. - - * If the problem is small (a feature commit after feature freeze, - say), wait it out. - - * If there's a disagreement between the committer and the - reverter-to-be then try to work it out on the `django-developers`_ - mailing list. If an agreement can't be reached then it should - be put to a vote. - - * If the commit introduced a confirmed, disclosed security - vulnerability then the commit may be reverted immediately without - permission from anyone. - - * The release branch maintainer may back out commits to the release - branch without permission if the commit breaks the release branch. - -.. _unit-tests: - -Unit tests -========== - -Django comes with a test suite of its own, in the ``tests`` directory of the -Django tarball. It's our policy to make sure all tests pass at all times. - -The tests cover: - - * Models and the database API (``tests/modeltests/``). - * Everything else in core Django code (``tests/regressiontests``) - * Contrib apps (``django/contrib//tests``, see below) - -We appreciate any and all contributions to the test suite! - -The Django tests all use the testing infrastructure that ships with Django for -testing applications. See :doc:`Testing Django applications ` -for an explanation of how to write new tests. - -.. _running-unit-tests: - -Running the unit tests ----------------------- - -Quickstart -~~~~~~~~~~ - -Running the tests requires a Django settings module that defines the -databases to use. To make it easy to get started. Django provides a -sample settings module that uses the SQLite database. To run the tests -with this sample ``settings`` module, ``cd`` into the Django -``tests/`` directory and run: - -.. code-block:: bash - - ./runtests.py --settings=test_sqlite - -If you get an ``ImportError: No module named django.contrib`` error, -you need to add your install of Django to your ``PYTHONPATH``. For -more details on how to do this, read `Pointing Python at the new -Django version`_ below. - -Using another ``settings`` module -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The included settings module allows you to run the test suite using -SQLite. If you want to test behavior using a different database (and -if you're proposing patches for Django, it's a good idea to test -across databases), you may need to define your own settings file. - -To run the tests with different settings, ``cd`` to the ``tests/`` directory -and type: - -.. code-block:: bash - - ./runtests.py --settings=path.to.django.settings - -The :setting:`DATABASES` setting in this test settings module needs to define -two databases: - - * A ``default`` database. This database should use the backend that - you want to use for primary testing - - * A database with the alias ``other``. The ``other`` database is - used to establish that queries can be directed to different - databases. As a result, this database can use any backend you - want. It doesn't need to use the same backend as the ``default`` - database (although it can use the same backend if you want to). - -If you're using a backend that isn't SQLite, you will need to provide other -details for each database: - - * The :setting:`USER` option for each of your databases needs to - specify an existing user account for the database. - - * The :setting:`PASSWORD` option needs to provide the password for - the :setting:`USER` that has been specified. - - * The :setting:`NAME` option must be the name of an existing database to - which the given user has permission to connect. The unit tests will not - touch this database; the test runner creates a new database whose name is - :setting:`NAME` prefixed with ``test_``, and this test database is - deleted when the tests are finished. This means your user account needs - permission to execute ``CREATE DATABASE``. - -You will also need to ensure that your database uses UTF-8 as the default -character set. If your database server doesn't use UTF-8 as a default charset, -you will need to include a value for ``TEST_CHARSET`` in the settings -dictionary for the applicable database. - -Running only some of the tests -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Django's entire test suite takes a while to run, and running every single test -could be redundant if, say, you just added a test to Django that you want to -run quickly without running everything else. You can run a subset of the unit -tests by appending the names of the test modules to ``runtests.py`` on the -command line. - -For example, if you'd like to run tests only for generic relations and -internationalization, type: - -.. code-block:: bash - - ./runtests.py --settings=path.to.settings generic_relations i18n - -How do you find out the names of individual tests? Look in ``tests/modeltests`` -and ``tests/regressiontests`` -- each directory name there is the name of a -test. - -If you just want to run a particular class of tests, you can specify a list of -paths to individual test classes. For example, to run the ``TranslationTests`` -of the ``i18n`` module, type: - -.. code-block:: bash - - ./runtests.py --settings=path.to.settings i18n.TranslationTests - -Going beyond that, you can specify an individual test method like this: - -.. code-block:: bash - - ./runtests.py --settings=path.to.settings i18n.TranslationTests.test_lazy_objects - -Running all the tests -~~~~~~~~~~~~~~~~~~~~~ - -If you want to run the full suite of tests, you'll need to install a number of -dependencies: - - * PyYAML_ - * Markdown_ - * Textile_ - * Docutils_ - * setuptools_ - * memcached_, plus a :ref:`supported Python binding ` - * gettext_ (:ref:`gettext_on_windows`) - -If you want to test the memcached cache backend, you'll also need to define -a :setting:`CACHES` setting that points at your memcached instance. - -Each of these dependencies is optional. If you're missing any of them, the -associated tests will be skipped. - -.. _PyYAML: http://pyyaml.org/wiki/PyYAML -.. _Markdown: http://pypi.python.org/pypi/Markdown/1.7 -.. _Textile: http://pypi.python.org/pypi/textile -.. _docutils: http://pypi.python.org/pypi/docutils/0.4 -.. _setuptools: http://pypi.python.org/pypi/setuptools/ -.. _memcached: http://www.danga.com/memcached/ -.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html - -Contrib apps ------------- - -Tests for apps in ``django/contrib/`` go in their respective directories under -``django/contrib/``, in a ``tests.py`` file. (You can split the tests over -multiple modules by using a ``tests`` directory in the normal Python way.) - -For the tests to be found, a ``models.py`` file must exist (it doesn't -have to have anything in it). If you have URLs that need to be -mapped, put them in ``tests/urls.py``. - -To run tests for just one contrib app (e.g. ``markup``), use the same -method as above:: - - ./runtests.py --settings=settings markup - -Requesting features -=================== - -We're always trying to make Django better, and your feature requests are a key -part of that. Here are some tips on how to make a request most effectively: - - * Request the feature on `django-developers`_, not in the ticket tracker. - It'll get read more closely if it's on the mailing list. - - * Describe clearly and concisely what the missing feature is and how you'd - like to see it implemented. Include example code (non-functional is OK) - if possible. - - * Explain *why* you'd like the feature. In some cases this is obvious, but - since Django is designed to help real developers get real work done, - you'll need to explain it, if it isn't obvious why the feature would be - useful. - -As with most open-source projects, code talks. If you are willing to write the -code for the feature yourself or if (even better) you've already written it, -it's much more likely to be accepted. If it's a large feature that might need -multiple developers, we're always happy to give you an experimental branch in -our repository; see below. - -Branch policy -============= - -In general, the trunk must be kept stable. People should be able to run -production sites against the trunk at any time. Additionally, commits to trunk -ought to be as atomic as possible -- smaller changes are better. Thus, large -feature changes -- that is, changes too large to be encapsulated in a single -patch, or changes that need multiple eyes on them -- must happen on dedicated -branches. - -This means that if you want to work on a large feature -- anything that would -take more than a single patch, or requires large-scale refactoring -- you need -to do it on a feature branch. Our development process recognizes two options -for feature branches: - - 1. Feature branches using a distributed revision control system like - Git_, Mercurial_, Bazaar_, etc. - - If you're familiar with one of these tools, this is probably your best - option since it doesn't require any support or buy-in from the Django - core developers. - - However, do keep in mind that Django will continue to use Subversion for - the foreseeable future, and this will naturally limit the recognition of - your branch. Further, if your branch becomes eligible for merging to - trunk you'll need to find a core developer familiar with your DVCS of - choice who'll actually perform the merge. - - If you do decided to start a distributed branch of Django and choose to - make it public, please add the branch to the `Django branches`_ wiki - page. - - 2. Feature branches using SVN have a higher bar. If you want a branch - in SVN itself, you'll need a "mentor" among the :doc:`core committers - `. This person is responsible for actually - creating the branch, monitoring your process (see below), and - ultimately merging the branch into trunk. - - If you want a feature branch in SVN, you'll need to ask in - `django-developers`_ for a mentor. - -.. _git: http://git-scm.com/ -.. _mercurial: http://mercurial.selenic.com/ -.. _bazaar: http://bazaar.canonical.com/ -.. _django branches: http://code.djangoproject.com/wiki/DjangoBranches - -Branch rules ------------- - -We've got a few rules for branches born out of experience with what makes a -successful Django branch. - -DVCS branches are obviously not under central control, so we have no way of -enforcing these rules. However, if you're using a DVCS, following these rules -will give you the best chance of having a successful branch (read: merged back -to trunk). - -Developers with branches in SVN, however, **must** follow these rules. The -branch mentor will keep on eye on the branch and **will delete it** if these -rules are broken. - - * Only branch entire copies of the Django tree, even if work is only - happening on part of that tree. This makes it painless to switch to a - branch. - - * Merge changes from trunk no less than once a week, and preferably every - couple-three days. - - In our experience, doing regular trunk merges is often the difference - between a successful branch and one that fizzles and dies. - - If you're working on an SVN branch, you should be using `svnmerge.py`_ - to track merges from trunk. - - * Keep tests passing and documentation up-to-date. As with patches, - we'll only merge a branch that comes with tests and documentation. - -.. _svnmerge.py: http://www.orcaware.com/svn/wiki/Svnmerge.py - -Once the branch is stable and ready to be merged into the trunk, alert -`django-developers`_. - -After a branch has been merged, it should be considered "dead"; write access to -it will be disabled, and old branches will be periodically "trimmed." To keep -our SVN wrangling to a minimum, we won't be merging from a given branch into -the trunk more than once. - -Using branches --------------- - -To use a branch, you'll need to do two things: - - * Get the branch's code through Subversion. - - * Point your Python ``site-packages`` directory at the branch's version of - the ``django`` package rather than the version you already have - installed. - -Getting the code from Subversion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To get the latest version of a branch's code, check it out using Subversion: - -.. code-block:: bash - - svn co http://code.djangoproject.com/svn/django/branches// - -...where ```` is the branch's name. See the `list of branch names`_. - -Alternatively, you can automatically convert an existing directory of the -Django source code as long as you've checked it out via Subversion. To do the -conversion, execute this command from within your ``django`` directory: - -.. code-block:: bash - - svn switch http://code.djangoproject.com/svn/django/branches// - -The advantage of using ``svn switch`` instead of ``svn co`` is that the -``switch`` command retains any changes you might have made to your local copy -of the code. It attempts to merge those changes into the "switched" code. The -disadvantage is that it may cause conflicts with your local changes if the -"switched" code has altered the same lines of code. - -(Note that if you use ``svn switch``, you don't need to point Python at the new -version, as explained in the next section.) - -.. _list of branch names: http://code.djangoproject.com/browser/django/branches - -Pointing Python at the new Django version -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Once you've retrieved the branch's code, you'll need to change your Python -``site-packages`` directory so that it points to the branch version of the -``django`` directory. (The ``site-packages`` directory is somewhere such as -``/usr/lib/python2.4/site-packages`` or -``/usr/local/lib/python2.4/site-packages`` or ``C:\Python\site-packages``.) - -The simplest way to do this is by renaming the old ``django`` directory to -``django.OLD`` and moving the trunk version of the code into the directory -and calling it ``django``. - -Alternatively, you can use a symlink called ``django`` that points to the -location of the branch's ``django`` package. If you want to switch back, just -change the symlink to point to the old code. - -A third option is to use a `path file`_ (``.pth``) which should -work on all systems (including Windows, which doesn't have symlinks -available). First, make sure there are no files, directories or symlinks named -``django`` in your ``site-packages`` directory. Then create a text file named -``django.pth`` and save it to your ``site-packages`` directory. That file -should contain a path to your copy of Django on a single line and optional -comments. Here is an example that points to multiple branches. Just uncomment -the line for the branch you want to use ('Trunk' in this example) and make -sure all other lines are commented:: - - # Trunk is a svn checkout of: - # http://code.djangoproject.com/svn/django/trunk/ - # - /path/to/trunk - - # is a svn checkout of: - # http://code.djangoproject.com/svn/django/branches// - # - #/path/to/ - - # On windows a path may look like this: - # C:/path/to/ - -If you're using Django 0.95 or earlier and installed it using -``python setup.py install``, you'll have a directory called something like -``Django-0.95-py2.4.egg`` instead of ``django``. In this case, edit the file -``setuptools.pth`` and remove the line that references the Django ``.egg`` -file. Then copy the branch's version of the ``django`` directory into -``site-packages``. - -.. _path file: http://docs.python.org/library/site.html - -How we make decisions -===================== - -Whenever possible, we strive for a rough consensus. To that end, we'll often -have informal votes on `django-developers`_ about a feature. In these votes we -follow the voting style invented by Apache and used on Python itself, where -votes are given as +1, +0, -0, or -1. Roughly translated, these votes mean: - - * +1: "I love the idea and I'm strongly committed to it." - - * +0: "Sounds OK to me." - - * -0: "I'm not thrilled, but I won't stand in the way." - - * -1: "I strongly disagree and would be very unhappy to see the idea turn - into reality." - -Although these votes on django-developers are informal, they'll be taken very -seriously. After a suitable voting period, if an obvious consensus arises -we'll follow the votes. - -However, consensus is not always possible. If consensus cannot be reached, or -if the discussion towards a consensus fizzles out without a concrete decision, -we use a more formal process. - -Any core committer (see below) may call for a formal vote using the same -voting mechanism above. A proposition will be considered carried by the core -team if: - - * There are three "+1" votes from members of the core team. - - * There is no "-1" vote from any member of the core team. - - * The BDFLs haven't stepped in and executed their positive or negative - veto. - -When calling for a vote, the caller should specify a deadline by which -votes must be received. One week is generally suggested as the minimum -amount of time. - -Since this process allows any core committer to veto a proposal, any "-1" -votes (or BDFL vetos) should be accompanied by an explanation that explains -what it would take to convert that "-1" into at least a "+0". - -Whenever possible, these formal votes should be announced and held in -public on the `django-developers`_ mailing list. However, overly sensitive -or contentious issues -- including, most notably, votes on new core -committers -- may be held in private. - -Commit access -============= - -Django has two types of committers: - -Core committers - These are people who have a long history of contributions to Django's - codebase, a solid track record of being polite and helpful on the - mailing lists, and a proven desire to dedicate serious time to Django's - development. The bar is high for full commit access. - -Partial committers - These are people who are "domain experts." They have direct check-in access - to the subsystems that fall under their jurisdiction, and they're given a - formal vote in questions that involve their subsystems. This type of access - is likely to be given to someone who contributes a large subframework to - Django and wants to continue to maintain it. - - Partial commit access is granted by the same process as full - committers. However, the bar is set lower; proven expertise in the area - in question is likely to be sufficient. - -Decisions on new committers will follow the process explained above in `how -we make decisions`_. - -To request commit access, please contact an existing committer privately. -Public requests for commit access are potential flame-war starters, and -will be ignored. - -.. _community page: http://www.djangoproject.com/community/ -.. _ticket tracker: http://code.djangoproject.com/newticket -.. _django-developers: http://groups.google.com/group/django-developers -.. _search the tracker: http://code.djangoproject.com/search -.. _django-users: http://groups.google.com/group/django-users -.. _`#django`: irc://irc.freenode.net/django -.. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority -.. _pep8.py: http://pypi.python.org/pypi/pep8/ -.. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n -.. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases -.. _`easy-pickings`: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&keywords=~easy-pickings&order=priority diff --git a/docs/internals/contributing/bugs-and-features.txt b/docs/internals/contributing/bugs-and-features.txt new file mode 100644 index 0000000000..47cb580aff --- /dev/null +++ b/docs/internals/contributing/bugs-and-features.txt @@ -0,0 +1,181 @@ +====================================== +Reporting bugs and requesting features +====================================== + +Before reporting a bug or requesting a new feature please consider these +general points: + +* Check that someone hasn't already filed the bug or feature request by + `searching`_ or running `custom queries`_ in the ticket tracker. + +* Don't use the ticket system to ask support questions. Use the + `django-users`_ list, or the `#django`_ IRC channel for that. + +* Don't reopen issues that have been marked "wontfix" by a core developer. + This mark means that the decision has been made that we can't or won't fix + this particular issue. If you're not sure why, please ask + on `django-developers`_. + +* Don't use the ticket tracker for lengthy discussions, because they're + likely to get lost. If a particular ticket is controversial, please move + discussion to `django-developers`_. + +.. _reporting-bugs: + +Reporting bugs +-------------- + +Well-written bug reports are *incredibly* helpful. However, there's a certain +amount of overhead involved in working with any bug tracking system so your +help in keeping our ticket tracker as useful as possible is appreciated. In +particular: + + * **Do** read the :doc:`FAQ ` to see if your issue might + be a well-known question. + + * **Do** ask on `django-users`_ *first* if you're not sure if what you're + seeing is a bug. + + * **Do** write complete, reproducible, specific bug reports. Include as + much information as you possibly can, complete with code snippets, test + cases, etc. This means including a clear, concise description of the + problem, and a clear set of instructions for replicating the problem. + A minimal example that illustrates the bug in a nice small test case + is the best possible bug report. + + * **Don't** post to django-developers just to announce that you have filed + a bug report. All the tickets are mailed to another list + (`django-updates`_), which is tracked by developers and interested + community members; we see them as they are filed. + +To understand the lifecycle of your ticket once you have created it, refer to +:doc:`triaging-tickets`. + +.. _django-updates: http://groups.google.com/group/django-updates + +.. _reporting-security-issues: + +Reporting security issues +------------------------- + +.. Important:: + + Please report security issues **only** to security@djangoproject.com. + This is a private list only open to long-time, highly trusted Django + developers, and its archives are not publicly readable. + +In the event of a confirmed vulnerability in Django itself, we will take the +following actions: + + * Acknowledge to the reporter that we've received the report and that a + fix is forthcoming. We'll give a rough timeline and ask the reporter + to keep the issue confidential until we announce it. + + * Focus on developing a fix as quickly as possible and produce patches + against the current and two previous releases. + + * Determine a go-public date for announcing the vulnerability and the fix. + To try to mitigate a possible "arms race" between those applying the + patch and those trying to exploit the hole, we will not announce + security problems immediately. + + * Pre-notify third-party distributors of Django ("vendors"). We will send + these vendor notifications through private email which will include + documentation of the vulnerability, links to the relevant patch(es), and + a request to keep the vulnerability confidential until the official + go-public date. + + * Publicly announce the vulnerability and the fix on the pre-determined + go-public date. This will probably mean a new release of Django, but + in some cases it may simply be patches against current releases. + +Requesting features +------------------- + +We're always trying to make Django better, and your feature requests are a key +part of that. Here are some tips on how to make a request most effectively: + + * First request the feature on `django-developers`_, not in the ticket + tracker. It'll get read more closely if it's on the mailing list. + + * Describe clearly and concisely what the missing feature is and how you'd + like to see it implemented. Include example code (non-functional is OK) + if possible. + + * Explain *why* you'd like the feature. In some cases this is obvious, but + since Django is designed to help real developers get real work done, + you'll need to explain it, if it isn't obvious why the feature would be + useful. + + * Don't use the ticket system to make large-scale feature requests. + We like to discuss any big changes to Django's core on the + `django-developers`_ list before actually working on them. + +As with most open-source projects, code talks. If you are willing to write the +code for the feature yourself or if (even better) you've already written it, +it's much more likely to be accepted. If it's a large feature that might need +multiple developers, we're always happy to give you an experimental branch in +our repository; see the :doc:`writing-code/branch-policy`. + +To understand the lifecycle of your ticket once you have created it, refer to +:doc:`triaging-tickets`. + +See also: :ref:`documenting-new-features`. + +.. _how-we-make-decisions: + +How we make decisions +--------------------- + +Whenever possible, we strive for a rough consensus. To that end, we'll often +have informal votes on `django-developers`_ about a feature. In these votes we +follow the voting style invented by Apache and used on Python itself, where +votes are given as +1, +0, -0, or -1. Roughly translated, these votes mean: + + * +1: "I love the idea and I'm strongly committed to it." + + * +0: "Sounds OK to me." + + * -0: "I'm not thrilled, but I won't stand in the way." + + * -1: "I strongly disagree and would be very unhappy to see the idea turn + into reality." + +Although these votes on django-developers are informal, they'll be taken very +seriously. After a suitable voting period, if an obvious consensus arises +we'll follow the votes. + +However, consensus is not always possible. If consensus cannot be reached, or +if the discussion towards a consensus fizzles out without a concrete decision, +we use a more formal process. + +Any :doc:`core committer` may call for a formal vote +using the same voting mechanism above. A proposition will be considered carried +by the core team if: + + * There are three "+1" votes from members of the core team. + + * There is no "-1" vote from any member of the core team. + + * The :ref:`BDFLs` haven't stepped in and executed their + positive or negative veto. + +When calling for a vote, the caller should specify a deadline by which +votes must be received. One week is generally suggested as the minimum +amount of time. + +Since this process allows any core committer to veto a proposal, any "-1" +votes (or BDFL vetos) should be accompanied by an explanation that explains +what it would take to convert that "-1" into at least a "+0". + +Whenever possible, these formal votes should be announced and held in +public on the `django-developers`_ mailing list. However, overly sensitive +or contentious issues -- including, most notably, votes on new core +committers -- may be held in private. + + +.. _searching: http://code.djangoproject.com/search +.. _`custom queries`: https://code.djangoproject.com/query +.. _django-developers: http://groups.google.com/group/django-developers +.. _django-users: http://groups.google.com/group/django-users +.. _`#django`: irc://irc.freenode.net/django diff --git a/docs/internals/contributing/committing-code.txt b/docs/internals/contributing/committing-code.txt new file mode 100644 index 0000000000..601d1a0ef2 --- /dev/null +++ b/docs/internals/contributing/committing-code.txt @@ -0,0 +1,133 @@ +=============== +Committing code +=============== + +This section is addressed to the :doc:`/internals/committers` and to anyone +interested in knowing how code gets committed into Django core. + +Commit access +------------- + +Django has two types of committers: + +Core committers + These are people who have a long history of contributions to Django's + codebase, a solid track record of being polite and helpful on the + mailing lists, and a proven desire to dedicate serious time to Django's + development. The bar is high for full commit access. + +Partial committers + These are people who are "domain experts." They have direct check-in + access to the subsystems that fall under their jurisdiction, and they're + given a formal vote in questions that involve their subsystems. This type + of access is likely to be given to someone who contributes a large + subframework to Django and wants to continue to maintain it. + + Partial commit access is granted by the same process as full + committers. However, the bar is set lower; proven expertise in the area + in question is likely to be sufficient. + +Decisions on new committers will follow the process explained in +:ref:`how-we-make-decisions`. + +To request commit access, please contact an existing committer privately. +Public requests for commit access are potential flame-war starters, and +will be ignored. + +Committing guidelines +--------------------- + +Please follow these guidelines when committing code to Django's Subversion +repository: + + * For any medium-to-big changes, where "medium-to-big" is according to + your judgment, please bring things up on the `django-developers`_ + mailing list before making the change. + + If you bring something up on `django-developers`_ and nobody responds, + please don't take that to mean your idea is great and should be + implemented immediately because nobody contested it. Django's lead + developers don't have a lot of time to read mailing-list discussions + immediately, so you may have to wait a couple of days before getting a + response. + + * Write detailed commit messages in the past tense, not present tense. + + * Good: "Fixed Unicode bug in RSS API." + * Bad: "Fixes Unicode bug in RSS API." + * Bad: "Fixing Unicode bug in RSS API." + + * For commits to a branch, prefix the commit message with the branch name. + For example: "magic-removal: Added support for mind reading." + + * Limit commits to the most granular change that makes sense. This means, + use frequent small commits rather than infrequent large commits. For + example, if implementing feature X requires a small change to library Y, + first commit the change to library Y, then commit feature X in a + separate commit. This goes a *long way* in helping all core Django + developers follow your changes. + + * Separate bug fixes from feature changes. + + Bug fixes need to be added to the current bugfix branch (e.g. the + ``1.0.X`` branch) as well as the current trunk. + + * If your commit closes a ticket in the Django `ticket tracker`_, begin + your commit message with the text "Fixed #abc", where "abc" is the + number of the ticket your commit fixes. Example: "Fixed #123 -- Adde + support for foo". We've rigged Subversion and Trac so that any commit + message in that format will automatically close the referenced ticket + and post a comment to it with the full commit message. + + If your commit closes a ticket and is in a branch, use the branch name + first, then the "Fixed #abc." For example: + "magic-removal: Fixed #123 -- Added whizbang feature." + + For the curious: We're using a `Trac post-commit hook`_ for this. + + .. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook + + * If your commit references a ticket in the Django `ticket tracker`_ but + does *not* close the ticket, include the phrase "Refs #abc", where "abc" + is the number of the ticket your commit references. We've rigged + Subversion and Trac so that any commit message in that format will + automatically post a comment to the appropriate ticket. + +Reverting commits +----------------- + +Nobody's perfect; mistakes will be committed. When a mistaken commit is +discovered, please follow these guidelines: + + * Try very hard to ensure that mistakes don't happen. Just because we + have a reversion policy doesn't relax your responsibility to aim for + the highest quality possible. Really: double-check your work before + you commit it in the first place! + + * If possible, have the original author revert his/her own commit. + + * Don't revert another author's changes without permission from the + original author. + + * If the original author can't be reached (within a reasonable amount + of time -- a day or so) and the problem is severe -- crashing bug, + major test failures, etc -- then ask for objections on django-dev + then revert if there are none. + + * If the problem is small (a feature commit after feature freeze, + say), wait it out. + + * If there's a disagreement between the committer and the + reverter-to-be then try to work it out on the `django-developers`_ + mailing list. If an agreement can't be reached then it should + be put to a vote. + + * If the commit introduced a confirmed, disclosed security + vulnerability then the commit may be reverted immediately without + permission from anyone. + + * The release branch maintainer may back out commits to the release + branch without permission if the commit breaks the release branch. + +.. _django-developers: http://groups.google.com/group/django-developers +.. _ticket tracker: http://code.djangoproject.com/newticket diff --git a/docs/internals/contributing/index.txt b/docs/internals/contributing/index.txt new file mode 100644 index 0000000000..b326ad90b9 --- /dev/null +++ b/docs/internals/contributing/index.txt @@ -0,0 +1,48 @@ +====================== +Contributing to Django +====================== + +If you think working *with* Django is fun, wait until you start working *on* +it. We're passionate about helping Django users make the jump to contributing +members of the community, so there are several ways you can help Django's +development: + + * Blog about Django. We syndicate all the Django blogs we know about on + the `community page`_; if you'd like to see your blog on that page you + can `register it here`_. + + * :doc:`Report bugs and request features` in our + `ticket tracker`_. + + * Join the `django-developers`_ mailing list and share your ideas for how + to improve Django. We're always open to suggestions. + + * :doc:`Submit patches` for new and/or + fixed behavior. If you're looking for an easy way to start contributing + to Django have a look at the `easy pickings`_ tickets. + + * :doc:`Improve the documentation` or + :doc:`write unit tests`. + + * :doc:`Triage tickets` that have been created by other + users. + +... and many more ways! Really, **ANYONE** can do something to help make +Django better and greater. Browse the following sections to find out how: + +.. toctree:: + :maxdepth: 2 + + new-contributors + bugs-and-features + triaging-tickets + writing-code/index + writing-documentation + translations + committing-code + +.. _django-developers: http://groups.google.com/group/django-developers +.. _ticket tracker: http://code.djangoproject.com/newticket +.. _community page: http://www.djangoproject.com/community/ +.. _`easy pickings`: http://code.djangoproject.com/query?status=!closed&easy=1 +.. _`register it here`: http://www.djangoproject.com/community/add/blogs/ diff --git a/docs/internals/contributing/new-contributors.txt b/docs/internals/contributing/new-contributors.txt new file mode 100644 index 0000000000..f1673b3618 --- /dev/null +++ b/docs/internals/contributing/new-contributors.txt @@ -0,0 +1,137 @@ +=========================== +Advice for new contributors +=========================== + +New contributor and not sure what to do? Want to help but just don't know how +to get started? This is the section for you. + +* **Pick a subject area that you care about, that you are familiar with, or + that you want to learn about** + + You don't already have to be an expert on the area you want to work on; you + become an expert through your ongoing contributions to the code. + +* **Triage tickets** + + If a ticket is unreviewed and reports a bug, try and reproduce it. If you + can reproduce it and it seems valid, make a note that you confirmed the bug + and accept the ticket. Make sure the ticket is filed under the correct + component area. Consider writing a patch that adds a test for the bug's + behavior, even if you don't fix the bug itself. See more at + :ref:`how-can-i-help-with-triaging` + +* **Look for tickets that are accepted and review patches to build familiarity + with the codebase and the process** + + Mark the appropriate flags if a patch needs docs or tests. Look through the + changes a patch makes, and keep an eye out for syntax that is incompatible + with older but still supported versions of Python. Run the tests and make + sure they pass on your system. Where possible and relevant, try them out on + a database other than SQLite. Leave comments and feedback! + +* **Keep old patches up to date** + + Oftentimes the codebase will change between a patch being submitted and the + time it gets reviewed. Make sure it still applies cleanly and functions as + expected. Simply updating a patch is both useful and important! See more on + :doc:`writing-code/submitting-patches`. + +* **Write some documentation** + + Django's documentation is great but it can always be improved. Did you find + a typo? Do you think that something should be clarified? Go ahead and + suggest a documentation patch! See also the guide on + :doc:`writing-documentation`, in particular the tips for + :ref:`improving-the-documentation`. + +* **Analyze the ticket's context and history** + + Trac isn't an absolute; the context is just as important as the words. + When reading Trac, you need to take into account who says things, and when + they were said. Support for an idea two years ago doesn't necessarily mean + that the idea will still have support. You also need to pay attention to who + *hasn't* spoken -- for example, if a core team member hasn't been recently + involved in a discussion, then a ticket may not have the support required to + get into trunk. + +* **Start small** + + It's easier to get feedback on a little issue than on a big one. See the + `easy pickings`_. + +* **If you're going to engage in a big task, make sure that your idea has + support first** + + This means getting someone else to confirm that a bug is real before you fix + the issue, and ensuring that the core team supports a proposed feature + before you go implementing it. + +* **Be bold! Leave feedback!** + + Sometimes it can be scary to put your opinion out to the world and say "this + ticket is correct" or "this patch needs work", but it's the only way the + project moves forward. The contributions of the broad Django community + ultimately have a much greater impact than that of the core developers. We + can't do it without YOU! + +* **Err on the side of caution when marking things Ready For Check-in** + + If you're really not certain if a ticket is ready, don't mark it as + such. Leave a comment instead, letting others know your thoughts. If you're + mostly certain, but not completely certain, you might also try asking on IRC + to see if someone else can confirm your suspicions. + +* **Wait for feedback, and respond to feedback that you receive** + + Focus on one or two tickets, see them through from start to finish, and + repeat. The shotgun approach of taking on lots of tickets and letting some + fall by the wayside ends up doing more harm than good. + +* **Be rigorous** + + When we say ":pep:`8`, and must have docs and tests", we mean it. If a patch + doesn't have docs and tests, there had better be a good reason. Arguments + like "I couldn't find any existing tests of this feature" don't carry much + weight--while it may be true, that means you have the extra-important job of + writing the very first tests for that feature, not that you get a pass from + writing tests altogether. + +.. note:: + + The `Reports page`_ contains links to many useful Trac queries, including + several that are useful for triaging tickets and reviewing patches as + suggested above. + + .. _Reports page: http://code.djangoproject.com/wiki/Reports + +.. _new-contributors-faq: + +FAQ +--- + +1. **This ticket I care about has been ignored for days/weeks/months! What can + I do to get it committed?** + + First off, it's not personal. Django is entirely developed by volunteers + (even the core developers), and sometimes folks just don't have time. The + best thing to do is to send a gentle reminder to the Django Developers + mailing list asking for review on the ticket, or to bring it up in the + #django-dev IRC channel. + +2. **I'm sure my ticket is absolutely 100% perfect, can I mark it as RFC + myself?** + + Short answer: No. It's always better to get another set of eyes on a + ticket. If you're having trouble getting that second set of eyes, see + question 1, above. + +3. **My ticket has been in DDN forever! What should I do?** + + Design Decision Needed requires consensus about the right solution. At the + very least it needs consensus among the core developers, and ideally it has + consensus from the community as well. The best way to accomplish this is to + start a thread on the Django Developers mailing list, and for very complex + issues to start a wiki page summarizing the problem and the possible + solutions. + +.. _`easy pickings`: http://code.djangoproject.com/query?status=!closed&easy=1 diff --git a/docs/internals/contributing/translations.txt b/docs/internals/contributing/translations.txt new file mode 100644 index 0000000000..ade04e6c3c --- /dev/null +++ b/docs/internals/contributing/translations.txt @@ -0,0 +1,60 @@ +======================================= +Submitting and maintaining translations +======================================= + +Various parts of Django, such as the admin site and validation error messages, +are internationalized. This means they display different text depending on a +user's language setting. For this, Django uses the same internationalization +infrastructure available to Django applications described in the +:doc:`i18n documentation`. + +These translations are contributed by Django users worldwide. If you find an +incorrect translation or want to discuss specific translations, go to the +`translation team`_ page for that language. If you would like to help out +with translating or add a language that isn't yet translated, here's what +to do: + + * Join the `Django i18n mailing list`_ and introduce yourself. + + * Make sure you read the notes about :ref:`specialties-of-django-i18n`. + + * Signup at `Transifex`_ and visit the `Django project page`_. + + * On the "`Translation Teams`_" page, choose the language team you want + to work with, **or** -- in case the language team doesn't exist yet -- + request a new team by clicking on the "Request a new team" button + and select the appropriate language. + + * Then, click the "Join this Team" button to become a member of this team. + Every team has at least one coordinator who is responsible to review + your membership request. You can of course also contact the team + coordinator to clarify procedural problems and handle the actual + translation process. + + * Once you are a member of a team choose the translation resource you + want to update on the team page. For example the "core" resource refers + to the translation catalogue that contains all non-contrib translations. + Each of the contrib apps also have a resource (prefixed with "contrib"). + + .. note:: + For more information about how to use Transifex, see the + `Transifex Help`_ + + * Optionally, review and update the ``conf/locale//formats.py`` + file to describe the date, time and numbers formatting particularities + of your locale. These files aren't covered by the use of Transifex and + require a patch against the Django source tree, just as a code change + would: + + * Create a diff against the current Subversion trunk. + + * Open a ticket in Django's ticket system, set its ``Component`` field + to ``Translations``, and attach the patch to it. See + :ref:`format-localization` for details. + +.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/ +.. _Transifex: http://www.transifex.net/ +.. _Django project page: http://www.transifex.net/projects/p/django/ +.. _translation teams: http://www.transifex.net/projects/p/django/teams/ +.. _translation team: http://www.transifex.net/projects/p/django/teams/ +.. _Transifex Help: http://help.transifex.net/ diff --git a/docs/internals/contributing/triaging-tickets.txt b/docs/internals/contributing/triaging-tickets.txt new file mode 100644 index 0000000000..a59d01b22f --- /dev/null +++ b/docs/internals/contributing/triaging-tickets.txt @@ -0,0 +1,389 @@ +================ +Triaging tickets +================ + +Django uses Trac_ for managing our progress, and Trac is a community-tended +garden of the bugs people have found and the features people would like to see +added. As in any garden, sometimes there are weeds to be pulled and sometimes +there are flowers and vegetables that need picking. We need your help to sort +out one from the other, and in the end we all benefit together. + +Like all gardens, we can aspire to perfection but in reality there's no such +thing. Even in the most pristine garden there are still snails and insects. +In a community garden there are also helpful people who--with the best of +intentions--fertilize the weeds and poison the roses. It's the job of the +community as a whole to self-manage, keep the problems to a minimum, and +educate those coming into the community so that they can become valuable +contributing members. + +Similarly, while we aim for Trac to be a perfect representation of the state +of Django's progress, we acknowledge that this simply will not happen. By +distributing the load of Trac maintenance to the community, we accept that +there will be mistakes. Trac is "mostly accurate", and we give allowances for +the fact that sometimes it will be wrong. That's okay. We're perfectionists +with deadlines. + +We rely on the community to keep participating, keep tickets as accurate as +possible, and raise issues for discussion on our mailing lists when there is +confusion or disagreement. + +Django is a community project, and every contribution helps. We can't do this +without YOU! + +Triage workflow +--------------- + +Unfortunately, not all bug reports and feature requests in the ticket tracker +provide all the :doc:`required details`. A number of +tickets have patches, but those patches don't meet all the requirements of a +:ref:`good patch`. + +One way to help out is to *triage* tickets that have been created by other +users. The core team--as well as many community members--work on this +regularly, but more help is always appreciated. + +Most of the workflow is based around the concept of a ticket's +:ref:`triage stages `. Each stage describes where in its +lifetime a given ticket is at any time. Along with a handful of flags, this +attribute easily tells us what and who each ticket is waiting on. + +Since a picture is worth a thousand words, let's start there: + +.. image:: /internals/_images/djangotickets.png + :height: 451 + :width: 590 + :alt: Django's ticket triage workflow + +We've got two roles in this diagram: + + * :doc:`Committers` (also called core developers): + people with commit access who are responsible for making the big + decisions, writing large portions of the code and integrating the + contributions of the community. + + * Ticket triagers: anyone in the Django community who chooses to + become involved in Django's development process. Our Trac installation + is intentionally left open to the public, and anyone can triage tickets. + Django is a community project, and we encourage :ref:`triage by the + community`. + +By way of example, here we see the lifecycle of an average ticket: + +* Alice creates a ticket, and uploads an incomplete patch (no tests, incorrect + implementation). + +* Bob reviews the patch, marks it "Accepted", "needs tests", and "patch needs + improvement", and leaves a comment telling Alice how the patch could be + improved. + +* Alice updates the patch, adding tests (but not changing the + implementation). She removes the two flags. + +* Charlie reviews the patch and resets the "patch needs improvement" flag with + another comment about improving the implementation. + +* Alice updates the patch, fixing the implementation. She removes the "patch + needs improvement" flag. + +* Daisy reviews the patch, and marks it RFC. + +* Jacob, a core developer, reviews the RFC patch, applies it to his checkout, + and commits it. + +Some tickets require much less feedback than this, but then again some tickets +require much much more. + +.. _triage-stages: + +Triage stages +------------- + +Below we describe in more detail the various stages that a ticket may flow +through during its lifetime. + +Unreviewed +~~~~~~~~~~ + +The ticket has not been reviewed by anyone who felt qualified to make a +judgment about whether the ticket contained a valid issue, a viable feature, +or ought to be closed for any of the various reasons. + +Accepted +~~~~~~~~ + +The big grey area! The absolute meaning of "accepted" is that the issue +described in the ticket is valid and is in some stage of being worked on. +Beyond that there are several considerations: + +* **Accepted + No Flags** + + The ticket is valid, but no one has submitted a patch for it yet. Often this + means you could safely start writing a patch for it. + +* **Accepted + Has Patch** + + The ticket is waiting for people to review the supplied patch. This means + downloading the patch and trying it out, verifying that it contains tests + and docs, running the test suite with the included patch, and leaving + feedback on the ticket. + +* **Accepted + Has Patch + (any other flag)** + + This means the ticket has been reviewed, and has been found to need further + work. "Needs tests" and "Needs documentation" are self-explanatory. "Patch + needs improvement" will generally be accompanied by a comment on the ticket + explaining what is needed to improve the code. + +Design Decision Needed +~~~~~~~~~~~~~~~~~~~~~~ + +This stage is for issues which may be contentious, may be backwards +incompatible, or otherwise involve high-level design decisions. These issues +should be discussed either in the ticket comments or on `django-developers`_. + +If a ticket has been marked as "DDN", decisions are generally eventually +made by the core committers, however that is not a requirement. See the +:ref:`New contributors' FAQ` for "My ticket has been in +DDN forever! What should I do?" + +This stage will generally only be used for feature +requests. It can also be used for issues that *might* be bugs, depending on +opinion or interpretation. Obvious bugs (such as crashes, incorrect query +results, or non-compliance with a standard) skip this stage and move straight +to "Accepted". + +Ready For Checkin +~~~~~~~~~~~~~~~~~ + +The ticket was reviewed by any member of the community other than the person +who supplied the patch and found to meet all the requirements for a +commit-ready patch. A core committer now needs to give the patch a final +review prior to being committed. See the +:ref:`New contributors' FAQ` for "My ticket has been in +RFC forever! What should I do?" + +Someday/Maybe +~~~~~~~~~~~~~ + +Generally only used for vague/high-level features or design ideas. These +tickets are uncommon and overall less useful since they don't describe +concrete actionable issues. They are enhancement requests that we might +consider adding someday to the framework if an excellent patch is submitted. +These tickets are not a high priority. + +Fixed on a branch +~~~~~~~~~~~~~~~~~ + +Used to indicate that a ticket is resolved as part of a major body of work +that will eventually be merged to trunk. Tickets in this stage generally +don't need further work. This may happen in the case of major +features/refactors in each release cycle, or as part of the annual Google +Summer of Code efforts. + +Other triage attributes +----------------------- + +A number of flags, appearing as checkboxes in Trac, can be set on a ticket: + + * Has patch + This means the ticket has an associated + :doc:`patch`. These will be reviewed + to see if the patch is "good". + * Needs documentation: + This flag is used for tickets with patches that need associated + documentation. Complete documentation of features is a prerequisite + before we can check them into the codebase. + * Needs tests + This flags the patch as needing associated unit tests. Again, this + is a required part of a valid patch. + * Patch needs improvement + This flag means that although the ticket *has* a patch, it's not quite + ready for checkin. This could mean the patch no longer applies + cleanly, there is a flaw in the implementation, or that the code + doesn't meet our standards." + * Easy pickings + Tickets that would require small, easy, patches. + +Tickets should be categorized by *type* between: + + * New Feature + For adding something new. + + * Bug + For when an existing thing is broken or not behaving as expected. + + * Cleanup/optimization + For when nothing is broken but something could be made cleaner, + better, faster, stronger. + +Tickets should also be classified into *components* indicating which area of +the Django codebase they belong to. This makes tickets better organized and +easier to find. + +The *severity* attribute is used to identify blockers, that is, issues which +should get fixed before releasing the next version of Django. Typically those +issues are bugs causing regressions from earlier versions or potentially +causing severe data losses. This attribute is quite rarely used and the vast +majority of tickets have a severity of "Normal". + +Finally, it is possible to use the *version* attribute to indicate in which +version the reported bug was identified. + +.. _closing-tickets: + +Closing Tickets +--------------- + +When a ticket has completed its useful lifecycle, it's time for it to be +closed. Closing a ticket is a big responsibility, though. You have to be sure +that the issue is really resolved, and you need to keep in mind that the +reporter of the ticket may not be happy to have their ticket closed (unless +it's fixed, of course). If you're not certain about closing a ticket, just +leave a comment with your thoughts instead. + +If you do close a ticket, you should always make sure of the following: + + * Be certain that the issue is resolved. + + * Leave a comment explaining the decision to close the ticket. + + * If there is a way they can improve the ticket to reopen it, let them know. + + * If the ticket is a duplicate, reference the original ticket. Also + cross-reference the closed ticket by living a comment in the original one + -- this allows to access more related information about the reported bug + or requested feature. + + * **Be polite.** No one likes having their ticket closed. It can be + frustrating or even discouraging. The best way to avoid turning people + off from contributing to Django is to be polite and friendly and to offer + suggestions for how they could improve this ticket and other tickets in + the future. + +A ticket can be resolved in a number of ways: + + * fixed + Used by the core developers once a patch has been rolled into + Django and the issue is fixed. + + * invalid + Used if the ticket is found to be incorrect. This means that the + issue in the ticket is actually the result of a user error, or + describes a problem with something other than Django, or isn't + a bug report or feature request at all (for example, some new users + submit support queries as tickets). + + * wontfix + Used when a core developer decides that this request is not + appropriate for consideration in Django. This is usually chosen after + discussion in the `django-developers`_ mailing list. Feel free to + start or join in discussions of "wontfix" tickets on the + django-developers_ mailing list, but please do not reopen tickets + closed as "wontfix" by core developers. + + * duplicate + Used when another ticket covers the same issue. By closing duplicate + tickets, we keep all the discussion in one place, which helps + everyone. + + * worksforme + Used when the ticket doesn't contain enough detail to replicate + the original bug. + + * needsinfo + Used when the ticket does not contain enough information to replicate + the reported issue but is potentially still valid. The ticket + should be reopened when more information is supplied. + +If you believe that the ticket was closed in error -- because you're +still having the issue, or it's popped up somewhere else, or the triagers have +made a mistake -- please reopen the ticket and provide further information. +Again, please do not reopen tickets that have been marked as "wontfix" by core +developers and bring the issue to django-developers_ instead. + +.. _how-can-i-help-with-triaging: + +How can I help with triaging? +----------------------------- + +Although the core developers make the big decisions in the ticket triage +process, there's a lot that general community members can do to help the +triage process. Really, **ANYONE** can help. + +Start by `creating an account on Trac`_. If you have an account but have +forgotten your password, you can reset it using the `password reset page`_. + +Then, you can help out by: + + * Closing "Unreviewed" tickets as "invalid", "worksforme" or "duplicate." + + * Promoting "Unreviewed" tickets to "Design decision needed" if a design + decision needs to be made, or "Accepted" in case of obvious bugs or + sensible, clearly defined, feature requests. + + * Correcting the "Needs tests", "Needs documentation", or "Has patch" + flags for tickets where they are incorrectly set. + + * Setting the "`Easy pickings`_" flag for tickets that are small and + relatively straightforward. + + * Checking that old tickets are still valid. If a ticket hasn't seen + any activity in a long time, it's possible that the problem has been + fixed but the ticket hasn't yet been closed. + + * Contacting the owners of tickets that have been claimed but have not + seen any recent activity. If the owner doesn't respond after a week + or so, remove the owner's claim on the ticket. + + * Identifying trends and themes in the tickets. If there a lot of bug + reports about a particular part of Django, it may indicate we should + consider refactoring that part of the code. If a trend is emerging, + you should raise it for discussion (referencing the relevant tickets) + on `django-developers`_. + + * Set the *type* of tickets that are still uncategorized. + + * Verify if patches submitted by other users are correct. If they do and + also contain appropriate documentation and tests then move them to the + "Ready for Checkin" stage. If they don't then leave a comment to explain + why and set the corresponding flags ("Patch needs improvement", + "Needs tests" etc.). + +.. note:: + + The `Reports page`_ contains links to many useful Trac queries, including + several that are useful for triaging tickets and reviewing patches as + suggested above. + + You can also find more :doc:`new-contributors`. + + .. _Reports page: http://code.djangoproject.com/wiki/Reports + +However, we do ask the following of all general community members working in +the ticket database: + + * Please **don't** close tickets as "wontfix." The core developers will + make the final determination of the fate of a ticket, usually after + consultation with the community. + + * Please **don't** promote your own tickets to "Ready for checkin". You + may mark other people's tickets which you've reviewed as "Ready for + checkin", but you should get at minimum one other community member to + review a patch that you submit. + + * Please **don't** reverse a decision that has been made by a core + developer. If you disagree with a decision that has been made, + please post a message to `django-developers`_. + + * If you're unsure if you should be making a change, don't make the + change but instead leave a comment with your concerns on the ticket, + or post a message to `django-developers`_. It's okay to be unsure, + but your input is still valuable. + +.. _Trac: http://code.djangoproject.com/ +.. _django-developers: http://groups.google.com/group/django-developers +.. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n +.. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases +.. _`easy pickings`: http://code.djangoproject.com/query?status=!closed&easy=1 +.. _`creating an account on Trac`: http://www.djangoproject.com/accounts/register/ +.. _password reset page: http://www.djangoproject.com/accounts/password/reset/ diff --git a/docs/internals/contributing/writing-code/branch-policy.txt b/docs/internals/contributing/writing-code/branch-policy.txt new file mode 100644 index 0000000000..08dfe8bc76 --- /dev/null +++ b/docs/internals/contributing/writing-code/branch-policy.txt @@ -0,0 +1,180 @@ +============= +Branch policy +============= + +In general, the trunk must be kept stable. People should be able to run +production sites against the trunk at any time. Additionally, commits to trunk +ought to be as atomic as possible -- smaller changes are better. Thus, large +feature changes -- that is, changes too large to be encapsulated in a single +patch, or changes that need multiple eyes on them -- must happen on dedicated +branches. + +This means that if you want to work on a large feature -- anything that would +take more than a single patch, or requires large-scale refactoring -- you need +to do it on a feature branch. Our development process recognizes two options +for feature branches: + + 1. Feature branches using a distributed revision control system like + Git_, Mercurial_, Bazaar_, etc. + + If you're familiar with one of these tools, this is probably your best + option since it doesn't require any support or buy-in from the Django + core developers. + + However, do keep in mind that Django will continue to use Subversion + for the foreseeable future, and this will naturally limit the + recognition of your branch. Further, if your branch becomes eligible + for merging to trunk you'll need to find a core developer familiar + with your DVCS of choice who'll actually perform the merge. + + If you do decided to start a distributed branch of Django and choose to + make it public, please add the branch to the `Django branches`_ wiki + page. + + 2. Feature branches using SVN have a higher bar. If you want a branch + in SVN itself, you'll need a "mentor" among the :doc:`core committers + `. This person is responsible for actually + creating the branch, monitoring your process (see below), and + ultimately merging the branch into trunk. + + If you want a feature branch in SVN, you'll need to ask in + `django-developers`_ for a mentor. + +.. _git: http://git-scm.com/ +.. _mercurial: http://mercurial.selenic.com/ +.. _bazaar: http://bazaar.canonical.com/ +.. _django branches: http://code.djangoproject.com/wiki/DjangoBranches + +Branch rules +------------ + +We've got a few rules for branches born out of experience with what makes a +successful Django branch. + +DVCS branches are obviously not under central control, so we have no way of +enforcing these rules. However, if you're using a DVCS, following these rules +will give you the best chance of having a successful branch (read: merged back +to trunk). + +Developers with branches in SVN, however, **must** follow these rules. The +branch mentor will keep on eye on the branch and **will delete it** if these +rules are broken. + + * Only branch entire copies of the Django tree, even if work is only + happening on part of that tree. This makes it painless to switch to a + branch. + + * Merge changes from trunk no less than once a week, and preferably every + couple-three days. + + In our experience, doing regular trunk merges is often the difference + between a successful branch and one that fizzles and dies. + + If you're working on an SVN branch, you should be using `svnmerge.py`_ + to track merges from trunk. + + * Keep tests passing and documentation up-to-date. As with patches, + we'll only merge a branch that comes with tests and documentation. + +.. _svnmerge.py: http://www.orcaware.com/svn/wiki/Svnmerge.py + +Once the branch is stable and ready to be merged into the trunk, alert +`django-developers`_. + +After a branch has been merged, it should be considered "dead"; write access +to it will be disabled, and old branches will be periodically "trimmed." +To keep our SVN wrangling to a minimum, we won't be merging from a given +branch into the trunk more than once. + +Using branches +-------------- + +To use a branch, you'll need to do two things: + + * Get the branch's code through Subversion. + + * Point your Python ``site-packages`` directory at the branch's version of + the ``django`` package rather than the version you already have + installed. + +Getting the code from Subversion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To get the latest version of a branch's code, check it out using Subversion: + +.. code-block:: bash + + svn co http://code.djangoproject.com/svn/django/branches// + +...where ```` is the branch's name. See the `list of branch names`_. + +Alternatively, you can automatically convert an existing directory of the +Django source code as long as you've checked it out via Subversion. To do the +conversion, execute this command from within your ``django`` directory: + +.. code-block:: bash + + svn switch http://code.djangoproject.com/svn/django/branches// + +The advantage of using ``svn switch`` instead of ``svn co`` is that the +``switch`` command retains any changes you might have made to your local copy +of the code. It attempts to merge those changes into the "switched" code. The +disadvantage is that it may cause conflicts with your local changes if the +"switched" code has altered the same lines of code. + +(Note that if you use ``svn switch``, you don't need to point Python at the +new version, as explained in the next section.) + +.. _list of branch names: http://code.djangoproject.com/browser/django/branches + +.. _pointing-python-at-the-new-django-version: + +Pointing Python at the new Django version +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you've retrieved the branch's code, you'll need to change your Python +``site-packages`` directory so that it points to the branch version of the +``django`` directory. (The ``site-packages`` directory is somewhere such as +``/usr/lib/python2.4/site-packages`` or +``/usr/local/lib/python2.4/site-packages`` or ``C:\Python\site-packages``.) + +The simplest way to do this is by renaming the old ``django`` directory to +``django.OLD`` and moving the trunk version of the code into the directory +and calling it ``django``. + +Alternatively, you can use a symlink called ``django`` that points to the +location of the branch's ``django`` package. If you want to switch back, just +change the symlink to point to the old code. + +A third option is to use a `path file`_ (``.pth``) which should +work on all systems (including Windows, which doesn't have symlinks +available). First, make sure there are no files, directories or symlinks named +``django`` in your ``site-packages`` directory. Then create a text file named +``django.pth`` and save it to your ``site-packages`` directory. That file +should contain a path to your copy of Django on a single line and optional +comments. Here is an example that points to multiple branches. Just uncomment +the line for the branch you want to use ('Trunk' in this example) and make +sure all other lines are commented:: + + # Trunk is a svn checkout of: + # http://code.djangoproject.com/svn/django/trunk/ + # + /path/to/trunk + + # is a svn checkout of: + # http://code.djangoproject.com/svn/django/branches// + # + #/path/to/ + + # On windows a path may look like this: + # C:/path/to/ + +If you're using Django 0.95 or earlier and installed it using +``python setup.py install``, you'll have a directory called something like +``Django-0.95-py2.4.egg`` instead of ``django``. In this case, edit the file +``setuptools.pth`` and remove the line that references the Django ``.egg`` +file. Then copy the branch's version of the ``django`` directory into +``site-packages``. + +.. _path file: http://docs.python.org/library/site.html +.. _django-developers: http://groups.google.com/group/django-developers diff --git a/docs/internals/contributing/writing-code/coding-style.txt b/docs/internals/contributing/writing-code/coding-style.txt new file mode 100644 index 0000000000..616550dcef --- /dev/null +++ b/docs/internals/contributing/writing-code/coding-style.txt @@ -0,0 +1,190 @@ +============ +Coding Style +============ + +Please follow these coding standards when writing code for inclusion in Django. + +Python style +------------ + + * Unless otherwise specified, follow :pep:`8`. + + You could use a tool like `pep8.py`_ to check for some problems in this + area, but remember that PEP 8 is only a guide, so respect the style of + the surrounding code as a primary goal. + + * Use four spaces for indentation. + + * Use underscores, not camelCase, for variable, function and method names + (i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``). + + * Use ``InitialCaps`` for class names (or for factory functions that + return classes). + + * In docstrings, use "action words" such as:: + + def foo(): + """ + Calculates something and returns the result. + """ + pass + + Here's an example of what not to do:: + + def foo(): + """ + Calculate something and return the result. + """ + pass + +Template style +-------------- + + * In Django template code, put one (and only one) space between the curly + brackets and the tag contents. + + Do this: + + .. code-block:: html+django + + {{ foo }} + + Don't do this: + + .. code-block:: html+django + + {{foo}} + +View style +---------- + + * In Django views, the first parameter in a view function should be called + ``request``. + + Do this:: + + def my_view(request, foo): + # ... + + Don't do this:: + + def my_view(req, foo): + # ... + +Model style +----------- + + * Field names should be all lowercase, using underscores instead of + camelCase. + + Do this:: + + class Person(models.Model): + first_name = models.CharField(max_length=20) + last_name = models.CharField(max_length=40) + + Don't do this:: + + class Person(models.Model): + FirstName = models.CharField(max_length=20) + Last_Name = models.CharField(max_length=40) + + * The ``class Meta`` should appear *after* the fields are defined, with + a single blank line separating the fields and the class definition. + + Do this:: + + class Person(models.Model): + first_name = models.CharField(max_length=20) + last_name = models.CharField(max_length=40) + + class Meta: + verbose_name_plural = 'people' + + Don't do this:: + + class Person(models.Model): + first_name = models.CharField(max_length=20) + last_name = models.CharField(max_length=40) + class Meta: + verbose_name_plural = 'people' + + Don't do this, either:: + + class Person(models.Model): + class Meta: + verbose_name_plural = 'people' + + first_name = models.CharField(max_length=20) + last_name = models.CharField(max_length=40) + + * The order of model inner classes and standard methods should be as + follows (noting that these are not all required): + + * All database fields + * Custom manager attributes + * ``class Meta`` + * ``def __unicode__()`` + * ``def __str__()`` + * ``def save()`` + * ``def get_absolute_url()`` + * Any custom methods + + * If ``choices`` is defined for a given model field, define the choices as + a tuple of tuples, with an all-uppercase name, either near the top of + the model module or just above the model class. Example:: + + GENDER_CHOICES = ( + ('M', 'Male'), + ('F', 'Female'), + ) + +Use of ``django.conf.settings`` +------------------------------- + +Modules should not in general use settings stored in ``django.conf.settings`` +at the top level (i.e. evaluated when the module is imported). The explanation +for this is as follows: + +Manual configuration of settings (i.e. not relying on the +``DJANGO_SETTINGS_MODULE`` environment variable) is allowed and possible as +follows:: + + from django.conf import settings + + settings.configure({}, SOME_SETTING='foo') + +However, if any setting is accessed before the ``settings.configure`` line, +this will not work. (Internally, ``settings`` is a ``LazyObject`` which +configures itself automatically when the settings are accessed if it has not +already been configured). + +So, if there is a module containing some code as follows:: + + from django.conf import settings + from django.core.urlresolvers import get_callable + + default_foo_view = get_callable(settings.FOO_VIEW) + +...then importing this module will cause the settings object to be configured. +That means that the ability for third parties to import the module at the top +level is incompatible with the ability to configure the settings object +manually, or makes it very difficult in some circumstances. + +Instead of the above code, a level of laziness or indirection must be used, +such as `django.utils.functional.LazyObject``, ``django.utils.functional.lazy`` +or ``lambda``. + +Miscellaneous +------------- + + * Mark all strings for internationalization; see the :doc:`i18n + documentation ` for details. + + * Please don't put your name in the code you contribute. Our policy is to + keep contributors' names in the ``AUTHORS`` file distributed with Django + -- not scattered throughout the codebase itself. Feel free to include a + change to the ``AUTHORS`` file in your patch if you make more than a + single trivial change. + +.. _pep8.py: http://pypi.python.org/pypi/pep8/ diff --git a/docs/internals/contributing/writing-code/index.txt b/docs/internals/contributing/writing-code/index.txt new file mode 100644 index 0000000000..bd9b2a346a --- /dev/null +++ b/docs/internals/contributing/writing-code/index.txt @@ -0,0 +1,15 @@ +============ +Writing code +============ + +So you'd like to write some code to improve Django. Awesome! Browse the +following sections to find out how to give your code patches the best +chances to be included in Django core: + +.. toctree:: + :maxdepth: 1 + + coding-style + unit-tests + submitting-patches + branch-policy diff --git a/docs/internals/contributing/writing-code/submitting-patches.txt b/docs/internals/contributing/writing-code/submitting-patches.txt new file mode 100644 index 0000000000..4eb74e1b1e --- /dev/null +++ b/docs/internals/contributing/writing-code/submitting-patches.txt @@ -0,0 +1,160 @@ +================== +Submitting patches +================== + +We're always grateful for patches to Django's code. Indeed, bug reports +with associated patches will get fixed *far* more quickly than those +without patches. + +"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: + + * `Create an account`_ to use 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 "Assigned to" section of the ticket. + If it's assigned to "nobody," then it's available to be claimed. + Otherwise, somebody else is working on this ticket, and you either find + another bug/feature to work on, or contact the developer working on the + ticket to offer your help. + + * Log into your account, if you haven't already, by clicking "Login" in + the upper right of the ticket page. + + * Claim the ticket by clicking the radio button next to "Accept ticket" + near the bottom of the page, then clicking "Submit changes." + +.. _Create an account: https://www.djangoproject.com/accounts/register/ +.. _password reset page: https://www.djangoproject.com/accounts/password/reset/ + +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? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Of course, 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. Just submit your patch and be done with +it. + +.. _patch-style: + +Patch style +----------- + + * Make sure your code matches our :doc:`coding-style`. + + * Submit patches in the format returned by the ``svn diff`` command. + An exception is for code changes that are described more clearly in + plain English than in code. Indentation is the most common example; it's + hard to read patches when the only difference in code is that it's + indented. + + Patches in ``git diff`` format are also acceptable. + + * When creating patches, always run ``svn diff`` from the top-level + ``trunk`` directory -- i.e., the one that contains ``django``, ``docs``, + ``tests``, ``AUTHORS``, etc. This makes it easy for other people to + apply your patches. + + * 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. + + * Check the "Has patch" box on the ticket details. This will make it + obvious that the ticket includes a patch, and it will add the ticket to + the `list of tickets with patches`_. + + * The code required to fix a problem or add a feature is an essential part + of a patch, but it is not the only part. A good patch should also + include a regression test to validate the behavior that has been fixed + (and prevent the problem from arising again). + + * If the code associated with a patch adds a new feature, or modifies + behavior of an existing feature, the patch should also contain + documentation. + +Non-trivial patches +------------------- + +A "non-trivial" patch is one that is more than a simple bug fix. It's a patch +that introduces Django functionality and makes some sort of design decision. + +If you provide a non-trivial patch, include evidence that alternatives have +been discussed on `django-developers`_. If you're not sure whether your patch +should be considered non-trivial, just ask. + +Javascript patches +------------------ + +.. versionadded:: 1.2 + +Django's admin system leverages the jQuery framework to increase the +capabilities of the admin interface. In conjunction, there is an emphasis on +admin javascript performance and minimizing overall admin media file size. +Serving compressed or "minified" versions of javascript files is considered +best practice in this regard. + +To that end, patches for javascript files should include both the original +code for future development (e.g. "foo.js"), and a compressed version for +production use (e.g. "foo.min.js"). Any links to the file in the codebase +should point to the compressed version. + +To simplify the process of providing optimized javascript code, Django +includes a handy script which should be used to create a "minified" version. +This script is located at ``/contrib/admin/media/js/compress.py``. + +Behind the scenes, ``compress.py`` is a front-end for Google's +`Closure Compiler`_ which is written in Java. However, the Closure Compiler +library is not bundled with Django directly, so those wishing to contribute +complete javascript patches will need to download and install the library +independently. + +The Closure Compiler library requires Java version 6 or higher (Java 1.6 or +higher on Mac OS X). Note that Mac OS X 10.5 and earlier did not ship with +Java 1.6 by default, so it may be necessary to upgrade your Java installation +before the tool will be functional. Also note that even after upgrading Java, +the default `/usr/bin/java` command may remain linked to the previous Java +binary, so relinking that command may be necessary as well. + +Please don't forget to run ``compress.py`` and include the ``diff`` of the +minified scripts when submitting patches for Django's javascript. + +.. _Closure Compiler: http://code.google.com/closure/compiler/ +.. _django-developers: http://groups.google.com/group/django-developers +.. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority +.. _ticket tracker: http://code.djangoproject.com/newticket diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt new file mode 100644 index 0000000000..fd9024e1a9 --- /dev/null +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -0,0 +1,167 @@ +========== +Unit tests +========== + +Django comes with a test suite of its own, in the ``tests`` directory of the +Django tarball. It's our policy to make sure all tests pass at all times. + +The tests cover: + + * Models and the database API (``tests/modeltests/``). + * Everything else in core Django code (``tests/regressiontests``) + * Contrib apps (``django/contrib//tests``, see below) + +We appreciate any and all contributions to the test suite! + +The Django tests all use the testing infrastructure that ships with Django for +testing applications. See :doc:`Testing Django applications ` +for an explanation of how to write new tests. + +.. _running-unit-tests: + +Running the unit tests +---------------------- + +Quickstart +~~~~~~~~~~ + +Running the tests requires a Django settings module that defines the +databases to use. To make it easy to get started. Django provides a +sample settings module that uses the SQLite database. To run the tests +with this sample ``settings`` module, ``cd`` into the Django +``tests/`` directory and run: + +.. code-block:: bash + + ./runtests.py --settings=test_sqlite + +If you get an ``ImportError: No module named django.contrib`` error, +you need to add your install of Django to your ``PYTHONPATH``. For +more details on how to do this, read +:ref:`pointing-python-at-the-new-django-version`. + +Using another ``settings`` module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The included settings module allows you to run the test suite using +SQLite. If you want to test behavior using a different database (and +if you're proposing patches for Django, it's a good idea to test +across databases), you may need to define your own settings file. + +To run the tests with different settings, ``cd`` to the ``tests/`` directory +and type: + +.. code-block:: bash + + ./runtests.py --settings=path.to.django.settings + +The :setting:`DATABASES` setting in this test settings module needs to define +two databases: + + * A ``default`` database. This database should use the backend that + you want to use for primary testing + + * A database with the alias ``other``. The ``other`` database is + used to establish that queries can be directed to different + databases. As a result, this database can use any backend you + want. It doesn't need to use the same backend as the ``default`` + database (although it can use the same backend if you want to). + +If you're using a backend that isn't SQLite, you will need to provide other +details for each database: + + * The :setting:`USER` option for each of your databases needs to + specify an existing user account for the database. + + * The :setting:`PASSWORD` option needs to provide the password for + the :setting:`USER` that has been specified. + + * The :setting:`NAME` option must be the name of an existing database to + which the given user has permission to connect. The unit tests will not + touch this database; the test runner creates a new database whose name + is :setting:`NAME` prefixed with ``test_``, and this test database is + deleted when the tests are finished. This means your user account needs + permission to execute ``CREATE DATABASE``. + +You will also need to ensure that your database uses UTF-8 as the default +character set. If your database server doesn't use UTF-8 as a default charset, +you will need to include a value for ``TEST_CHARSET`` in the settings +dictionary for the applicable database. + +Running only some of the tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Django's entire test suite takes a while to run, and running every single test +could be redundant if, say, you just added a test to Django that you want to +run quickly without running everything else. You can run a subset of the unit +tests by appending the names of the test modules to ``runtests.py`` on the +command line. + +For example, if you'd like to run tests only for generic relations and +internationalization, type: + +.. code-block:: bash + + ./runtests.py --settings=path.to.settings generic_relations i18n + +How do you find out the names of individual tests? Look in +``tests/modeltests`` and ``tests/regressiontests`` -- each directory name +there is the name of a test. + +If you just want to run a particular class of tests, you can specify a list of +paths to individual test classes. For example, to run the ``TranslationTests`` +of the ``i18n`` module, type: + +.. code-block:: bash + + ./runtests.py --settings=path.to.settings i18n.TranslationTests + +Going beyond that, you can specify an individual test method like this: + +.. code-block:: bash + + ./runtests.py --settings=path.to.settings i18n.TranslationTests.test_lazy_objects + +Running all the tests +~~~~~~~~~~~~~~~~~~~~~ + +If you want to run the full suite of tests, you'll need to install a number of +dependencies: + + * PyYAML_ + * Markdown_ + * Textile_ + * Docutils_ + * setuptools_ + * memcached_, plus a :ref:`supported Python binding ` + * gettext_ (:ref:`gettext_on_windows`) + +If you want to test the memcached cache backend, you'll also need to define +a :setting:`CACHES` setting that points at your memcached instance. + +Each of these dependencies is optional. If you're missing any of them, the +associated tests will be skipped. + +.. _PyYAML: http://pyyaml.org/wiki/PyYAML +.. _Markdown: http://pypi.python.org/pypi/Markdown/1.7 +.. _Textile: http://pypi.python.org/pypi/textile +.. _docutils: http://pypi.python.org/pypi/docutils/0.4 +.. _setuptools: http://pypi.python.org/pypi/setuptools/ +.. _memcached: http://www.danga.com/memcached/ +.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html + +Contrib apps +------------ + +Tests for apps in ``django/contrib/`` go in their respective directories under +``django/contrib/``, in a ``tests.py`` file. (You can split the tests over +multiple modules by using a ``tests`` directory in the normal Python way.) + +For the tests to be found, a ``models.py`` file must exist (it doesn't +have to have anything in it). If you have URLs that need to be +mapped, put them in ``tests/urls.py``. + +To run tests for just one contrib app (e.g. ``markup``), use the same +method as above:: + + ./runtests.py --settings=settings markup diff --git a/docs/internals/documentation.txt b/docs/internals/contributing/writing-documentation.txt similarity index 51% rename from docs/internals/documentation.txt rename to docs/internals/contributing/writing-documentation.txt index a0dd17fbc2..39723057dd 100644 --- a/docs/internals/documentation.txt +++ b/docs/internals/contributing/writing-documentation.txt @@ -1,10 +1,28 @@ -How the Django documentation works -================================== +===================== +Writing documentation +===================== -\... and how to contribute. +We place a high importance on consistency and readability of documentation. +After all, Django was created in a journalism environment! So we treat our +documentation like we treat our code: we aim to improve it as often as +possible. -Django's documentation uses the Sphinx__ documentation system, which in turn is -based on docutils__. The basic idea is that lightly-formatted plain-text +Documentation changes generally come in two forms: + + * General improvements -- Typo corrections, error fixes and better + explanations through clearer writing and more examples. + + * New features -- Documentation of features that have been added to the + framework since the last release. + +This section explains how writers can craft their documentation changes +in the most useful and least error-prone ways. + +Getting started with Sphinx +--------------------------- + +Django's documentation uses the Sphinx__ documentation system, which in turn +is based on docutils__. The basic idea is that lightly-formatted plain-text documentation is transformed into HTML, PDF, and any other output format. __ http://sphinx.pocoo.org/ @@ -22,7 +40,8 @@ Sphinx -- ``easy_install Sphinx`` should do the trick. __ http://pygments.org -Then, building the HTML is easy; just ``make html`` from the ``docs`` directory. +Then, building the HTML is easy; just ``make html`` from the ``docs`` +directory. To get started contributing, you'll want to read the `reStructuredText Primer`__. After that, you'll want to read about the `Sphinx-specific markup`__ @@ -31,23 +50,78 @@ that's used to manage metadata, indexing, and cross-references. __ http://sphinx.pocoo.org/rest.html __ http://sphinx.pocoo.org/markup/ -The main thing to keep in mind as you write and edit docs is that the more -semantic markup you can add the better. So:: +Commonly used terms +------------------- - Add ``django.contrib.auth`` to your ``INSTALLED_APPS``... +Here are some style guidelines on commonly used terms throughout the +documentation: -Isn't nearly as helpful as:: + * **Django** -- when referring to the framework, capitalize Django. It is + lowercase only in Python code and in the djangoproject.com logo. - Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`... + * **email** -- no hyphen. -This is because Sphinx will generate proper links for the latter, which greatly -helps readers. There's basically no limit to the amount of useful markup you can -add. + * **MySQL** + + * **PostgreSQL** + + * **Python** -- when referring to the language, capitalize Python. + + * **realize**, **customize**, **initialize**, etc. -- use the American + "ize" suffix, not "ise." + + * **SQLite** + + * **subclass** -- it's a single word without a hyphen, both as a verb + ("subclass that model") and as a noun ("create a subclass"). + + * **Web**, **World Wide Web**, **the Web** -- note Web is always + capitalized when referring to the World Wide Web. + + * **Web site** -- use two words, with Web capitalized. + +Django-specific terminology +--------------------------- + + * **model** -- it's not capitalized. + + * **template** -- it's not capitalized. + + * **URLconf** -- use three capitalized letters, with no space before + "conf." + + * **view** -- it's not capitalized. + +Guidelines for reStructuredText files +------------------------------------- + +These guidelines regulate the format of our reST (reStructuredText) +documentation: + + * In section titles, capitalize only initial words and proper nouns. + + * Wrap the documentation at 80 characters wide, unless a code example + is significantly less readable when split over two lines, or for another + good reason. + + * The main thing to keep in mind as you write and edit docs is that the + more semantic markup you can add the better. So:: + + Add ``django.contrib.auth`` to your ``INSTALLED_APPS``... + + Isn't nearly as helpful as:: + + Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`... + + This is because Sphinx will generate proper links for the latter, which + greatly helps readers. There's basically no limit to the amount of + useful markup you can add. Django-specific markup ---------------------- -Besides the `Sphinx built-in markup`__, Django's docs defines some extra description units: +Besides the `Sphinx built-in markup`__, Django's docs defines some extra +description units: __ http://sphinx.pocoo.org/markup/desc.html @@ -87,6 +161,26 @@ __ http://sphinx.pocoo.org/markup/desc.html To link, use ``:djadminopt:`--traceback```. +.. _documenting-new-features: + +Documenting new features +------------------------ + +Our policy for new features is: + + **All documentation of new features should be written in a way that + clearly designates the features are only available in the Django + development version. Assume documentation readers are using the latest + release, not the development version.** + +Our preferred way for marking new features is by prefacing the features' +documentation with: "``.. versionadded:: X.Y``", followed by an optional one +line comment and a mandatory blank line. + +General improvements, or other changes to the APIs that should be emphasized +should use the "``.. versionchanged:: X.Y``" directive (with the same format +as the ``versionadded`` mentioned above. + An example ---------- @@ -127,7 +221,8 @@ example: `. For a list of deprecated settings see :ref:`deprecated-settings`. - You can find both in the :doc:`settings reference document `. + You can find both in the :doc:`settings reference document + `. We use the Sphinx doc_ cross reference element when we want to link to another document as a whole and the ref_ element when we want to link to @@ -147,31 +242,34 @@ example: Default: ``()`` (Empty tuple) - Used for admin-site settings modules, this should be a tuple of settings - modules (in the format ``'foo.bar.baz'``) for which this site is an - admin. + Used for admin-site settings modules, this should be a tuple of + settings modules (in the format ``'foo.bar.baz'``) for which this site + is an admin. The admin site uses this in its automatically-introspected documentation of models, views and template tags. This marks up the following header as the "canonical" target for the - setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``, I - can reference it using ``:setting:`ADMIN_FOR```. + setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``, + I can reference it using ``:setting:`ADMIN_FOR```. That's basically how everything fits together. -TODO ----- +.. _improving-the-documentation: -The work is mostly done, but here's what's left, in rough order of priority. +Improving the documentation +--------------------------- + +A few small improvements can be made to make the documentation read and +look better: * Most of the various ``index.txt`` documents have *very* short or even - non-existent intro text. Each of those documents needs a good short intro - the content below that point. + non-existent intro text. Each of those documents needs a good short + intro the content below that point. * The glossary is very perfunctory. It needs to be filled out. - * Add more metadata targets: there's lots of places that look like:: + * Add more metadata targets. Lots of places look like:: ``File.close()`` ~~~~~~~~~~~~~~~~ @@ -194,28 +292,24 @@ The work is mostly done, but here's what's left, in rough order of priority. __ http://sphinx.pocoo.org/markup/desc.html#info-field-lists + * Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead + of ````ADMIN_FOR````. + + * Use directives where appropriate. Some directives + (e.g. ``.. setting::``) are prefix-style directives; they go *before* + the unit they're describing. These are known as "crossref" directives. + Others (e.g. ``.. class::``) generate their own markup; these should go + inside the section they're describing. These are called + "description units". + + You can tell which are which by looking at in + :file:`_ext/djangodocs.py`; it registers roles as one of the other. + * Add ``.. code-block:: `` to literal blocks so that they get highlighted. -Hints ------ - -Some hints for making things look/read better: - - * Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead of - ````ADMIN_FOR````. - - * Some directives (``.. setting::``, for one) are prefix-style directives; - they go *before* the unit they're describing. These are known as - "crossref" directives. Others (``.. class::``, e.g.) generate their own - markup; these should go inside the section they're describing. These are - called "description units". - - You can tell which are which by looking at in :file:`_ext/djangodocs.py`; - it registers roles as one of the other. - - * When referring to classes/functions/modules, etc., you'll want to use the - fully-qualified name of the target + * When referring to classes/functions/modules, etc., you'll want to use + the fully-qualified name of the target (``:class:`django.contrib.contenttypes.models.ContentType```). Since this doesn't look all that awesome in the output -- it shows the diff --git a/docs/internals/index.txt b/docs/internals/index.txt index 26c941a096..991236bb3e 100644 --- a/docs/internals/index.txt +++ b/docs/internals/index.txt @@ -14,10 +14,9 @@ the hood". these internals if we must. .. toctree:: - :maxdepth: 1 + :maxdepth: 2 - contributing - documentation + contributing/index committers release-process deprecation