development.txt
310 lines
| 11.8 KiB
| text/plain
|
TextLexer
Brian E Granger
|
r1256 | .. _development: | ||
Fernando Perez
|
r1725 | ============================== | ||
Brian E Granger
|
r1256 | IPython development guidelines | ||
Fernando Perez
|
r1725 | ============================== | ||
Brian E Granger
|
r1256 | |||
Overview | ||||
======== | ||||
Brian Granger
|
r1789 | This document describes IPython from the perspective of developers. Most | ||
importantly, it gives information for people who want to contribute to the | ||||
development of IPython. So if you want to help out, read on! | ||||
How to contribute to IPython | ||||
============================ | ||||
IPython development is done using Bazaar [Bazaar]_ and Launchpad [Launchpad]_. | ||||
This makes it easy for people to contribute to the development of IPython. | ||||
Here is a sketch of how to get going. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | Install Bazaar and create a Launchpad account | ||
--------------------------------------------- | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | First make sure you have installed Bazaar (see their `website | ||
<http://bazaar-vcs.org/>`_). To see that Bazaar is installed and knows about | ||||
you, try the following:: | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | $ bzr whoami | ||
Joe Coder <jcoder@gmail.com> | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | This should display your name and email. Next, you will want to create an | ||
account on the `Launchpad website <http://www.launchpad.net>`_ and setup your | ||||
ssh keys. For more information of setting up your ssh keys, see `this link | ||||
<https://help.launchpad.net/YourAccount/CreatingAnSSHKeyPair>`_. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | Get the main IPython branch from Launchpad | ||
------------------------------------------ | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | Now, you can get a copy of the main IPython development branch (we call this | ||
the "trunk"):: | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1555 | $ bzr branch lp:ipython | ||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | Create a working branch | ||
----------------------- | ||||
When working on IPython, you won't actually make edits directly to the | ||||
:file:`lp:ipython` branch. Instead, you will create a separate branch for your | ||||
changes. For now, let's assume you want to do your work in a branch named | ||||
"ipython-mybranch". Create this branch by doing:: | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1555 | $ bzr branch ipython ipython-mybranch | ||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | When you actually create a branch, you will want to give it a name that | ||
reflects the nature of the work that you will be doing in it, like | ||||
"install-docs-update". | ||||
Make edits in your working branch | ||||
--------------------------------- | ||||
Now you are ready to actually make edits in your :file:`ipython-mybranch` | ||||
branch. Before doing this, it is helpful to install this branch so you can | ||||
test your changes as you work. This is easiest if you have setuptools | ||||
installed. Then, just do:: | ||||
$ cd ipython-mybranch | ||||
$ python setupegg.py develop | ||||
Now, make some changes. After a while, you will want to commit your changes. | ||||
This let's Bazaar know that you like the changes you have made and gives you | ||||
an opportunity to keep a nice record of what you have done. This looks like | ||||
this:: | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1555 | $ ...do work in ipython-mybranch... | ||
Brian Granger
|
r1789 | $ bzr commit -m "the commit message goes here" | ||
Brian E Granger
|
r1269 | |||
Fernando Perez
|
r1697 | Please note that since we now don't use an old-style linear ChangeLog (that | ||
tends to cause problems with distributed version control systems), you should | ||||
ensure that your log messages are reasonably detailed. Use a docstring-like | ||||
approach in the commit messages (including the second line being left | ||||
*blank*):: | ||||
Fernando Perez
|
r1270 | |||
Single line summary of changes being committed. | ||||
Brian Granger
|
r1789 | * more details when warranted ... | ||
* including crediting outside contributors if they sent the | ||||
Fernando Perez
|
r1270 | code/bug/idea! | ||
Brian Granger
|
r1789 | As you work, you will repeat this edit/commit cycle many times. If you work on | ||
your branch for a long time, you will also want to get the latest changes from | ||||
the :file:`lp:ipython` branch. This can be done with the following sequence of | ||||
commands:: | ||||
Fernando Perez
|
r1270 | |||
Brian Granger
|
r1789 | $ ls | ||
ipython | ||||
ipython-mybranch | ||||
Brian Granger
|
r1555 | |||
Brian Granger
|
r1789 | $ cd ipython | ||
$ bzr pull | ||||
$ cd ../ipython-mybranch | ||||
$ bzr merge ../ipython | ||||
$ bzr commit -m "Merging changes from trunk" | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | Along the way, you should also run the IPython test suite. You can do this using the :command:`iptest` command:: | ||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | $ cd | ||
$ iptest | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | The :command:`iptest` command will also pick up and run any tests you have written. | ||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | Post your branch and request a code review | ||
------------------------------------------ | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | Once you are done with your edits, you should post your branch on Launchpad so | ||
that other IPython developers can review the changes and help you merge your | ||||
changes into the main development branch. To post your branch on Launchpad, | ||||
do:: | ||||
$ cd ipython-mybranch | ||||
$ bzr push lp:~yourusername/ipython/ipython-mybranch | ||||
Then, go to the `IPython Launchpad site <www.launchpad.net/ipython>`_, and you | ||||
should see your branch under the "Code" tab. If you click on your branch, you | ||||
can provide a short description of the branch as well as mark its status. Most | ||||
importantly, you should click the link that reads "Propose for merging into | ||||
another branch". What does this do? | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | This let's the other IPython developers know that your branch is ready to be | ||
reviewed and merged into the main development branch. During this review | ||||
process, other developers will give you feedback and help you get your code | ||||
ready to be merged. What types of things will we be looking for: | ||||
Brian E Granger
|
r1269 | |||
Brian Granger
|
r1789 | * All code is documented. | ||
* All code has tests. | ||||
* The entire IPython test suite passes. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | Once your changes have been reviewed and approved, someone will merge them | ||
into the main development branch. | ||||
Brian E Granger
|
r1256 | |||
Documentation | ||||
============= | ||||
Standalone documentation | ||||
------------------------ | ||||
Fernando Perez
|
r1697 | All standalone documentation should be written in plain text (``.txt``) files | ||
Brian Granger
|
r1789 | using reStructuredText [reStructuredText]_ for markup and formatting. All such | ||
documentation should be placed in directory :file:`docs/source` of the IPython | ||||
source tree. The documentation in this location will serve as the main source | ||||
for IPython documentation and all existing documentation should be converted | ||||
to this format. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | To build the final documentation, we use Sphinx [Sphinx]_. Once you have Sphinx installed, you can build the html docs yourself by doing:: | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | $ cd ipython-mybranch/docs | ||
$ make html | ||||
Brian E Granger
|
r1256 | |||
Docstring format | ||||
---------------- | ||||
Brian Granger
|
r1789 | Good docstrings are very important. All new code should have docstrings that | ||
are formatted using reStructuredText for markup and formatting, since it is | ||||
understood by a wide variety of tools. Details about using reStructuredText | ||||
for docstrings can be found `here | ||||
Brian E Granger
|
r1256 | <http://epydoc.sourceforge.net/manual-othermarkup.html>`_. | ||
Additional PEPs of interest regarding documentation of code: | ||||
Brian Granger
|
r1789 | * `Docstring Conventions <http://www.python.org/peps/pep-0257.html>`_ | ||
* `Docstring Processing System Framework <http://www.python.org/peps/pep-0256.html>`_ | ||||
* `Docutils Design Specification <http://www.python.org/peps/pep-0258.html>`_ | ||||
Brian E Granger
|
r1256 | |||
Coding conventions | ||||
================== | ||||
General | ||||
------- | ||||
Fernando Perez
|
r1697 | In general, we'll try to follow the standard Python style conventions as | ||
described here: | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | * `Style Guide for Python Code <http://www.python.org/peps/pep-0008.html>`_ | ||
Brian E Granger
|
r1256 | |||
Other comments: | ||||
Brian Granger
|
r1789 | * In a large file, top level classes and functions should be | ||
Brian E Granger
|
r1256 | separated by 2-3 lines to make it easier to separate them visually. | ||
Brian Granger
|
r1789 | * Use 4 spaces for indentation. | ||
* Keep the ordering of methods the same in classes that have the same | ||||
methods. This is particularly true for classes that implement an interface. | ||||
Brian E Granger
|
r1256 | |||
Naming conventions | ||||
------------------ | ||||
Fernando Perez
|
r1697 | In terms of naming conventions, we'll follow the guidelines from the `Style | ||
Guide for Python Code`_. | ||||
Brian E Granger
|
r1256 | |||
For all new IPython code (and much existing code is being refactored), we'll use: | ||||
Brian Granger
|
r1789 | * All ``lowercase`` module names. | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | * ``CamelCase`` for class names. | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | * ``lowercase_with_underscores`` for methods, functions, variables and | ||
Fernando Perez
|
r1697 | attributes. | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | There are, however, some important exceptions to these rules. In some cases, | ||
Fernando Perez
|
r1697 | IPython code will interface with packages (Twisted, Wx, Qt) that use other | ||
Brian Granger
|
r1789 | conventions. At some level this makes it impossible to adhere to our own | ||
standards at all times. In particular, when subclassing classes that use other | ||||
naming conventions, you must follow their naming conventions. To deal with | ||||
Fernando Perez
|
r1697 | cases like this, we propose the following policy: | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | * If you are subclassing a class that uses different conventions, use its | ||
Fernando Perez
|
r1697 | naming conventions throughout your subclass. Thus, if you are creating a | ||
Twisted Protocol class, used Twisted's | ||||
``namingSchemeForMethodsAndAttributes.`` | ||||
Brian Granger
|
r1789 | * All IPython's official interfaces should use our conventions. In some cases | ||
Fernando Perez
|
r1697 | this will mean that you need to provide shadow names (first implement | ||
``fooBar`` and then ``foo_bar = fooBar``). We want to avoid this at all | ||||
costs, but it will probably be necessary at times. But, please use this | ||||
sparingly! | ||||
Implementation-specific *private* methods will use | ||||
Brian Granger
|
r1789 | ``_single_underscore_prefix``. Names with a leading double underscore will | ||
Fernando Perez
|
r1697 | *only* be used in special cases, as they makes subclassing difficult (such | ||
names are not easily seen by child classes). | ||||
Occasionally some run-in lowercase names are used, but mostly for very short | ||||
names or where we are implementing methods very similar to existing ones in a | ||||
base class (like ``runlines()`` where ``runsource()`` and ``runcode()`` had | ||||
established precedent). | ||||
Brian E Granger
|
r1256 | |||
The old IPython codebase has a big mix of classes and modules prefixed with an | ||||
Fernando Perez
|
r1697 | explicit ``IP``. In Python this is mostly unnecessary, redundant and frowned | ||
upon, as namespaces offer cleaner prefixing. The only case where this approach | ||||
is justified is for classes which are expected to be imported into external | ||||
namespaces and a very generic name (like Shell) is too likely to clash with | ||||
something else. We'll need to revisit this issue as we clean up and refactor | ||||
the code, but in general we should remove as many unnecessary ``IP``/``ip`` | ||||
prefixes as possible. However, if a prefix seems absolutely necessary the more | ||||
specific ``IPY`` or ``ipy`` are preferred. | ||||
Brian E Granger
|
r1256 | |||
.. _devel_testing: | ||||
Testing system | ||||
============== | ||||
Brian Granger
|
r1789 | It is extremely important that all code contributed to IPython has tests. | ||
Tests should be written as unittests, doctests or as entities that the Nose | ||||
[Nose]_ testing package will find. Regardless of how the tests are written, we | ||||
will use Nose for discovering and running the tests. Nose will be required to | ||||
run the IPython test suite, but will not be required to simply use IPython. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | Tests of Twisted using code need to follow two additional guidelines: | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | 1. Twisted using tests should be written by subclassing the :class:`TestCase` | ||
class that comes with :mod:`twisted.trial.unittest`. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | 2. All :class:`Deferred` instances that are created in the test must be | ||
properly chained and the final one *must* be the return value of the test | ||||
method. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | When these two things are done, Nose will be able to run the tests and the | ||
twisted reactor will be handled correctly. | ||||
Each subpackage in IPython should have its own :file:`tests` directory that | ||||
Fernando Perez
|
r1697 | contains all of the tests for that subpackage. This allows each subpackage to | ||
be self-contained. If a subpackage has any dependencies beyond the Python | ||||
standard library, the tests for that subpackage should be skipped if the | ||||
dependencies are not found. This is very important so users don't get tests | ||||
failing simply because they don't have dependencies. | ||||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | To run the IPython test suite, use the :command:`iptest` command that is installed with IPython:: | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | $ iptest | ||
Brian E Granger
|
r1256 | |||
Brian Granger
|
r1789 | This command runs Nose with the proper options and extensions. | ||
Fernando Perez
|
r1725 | |||
Brian Granger
|
r1789 | .. _devel_config: | ||
Fernando Perez
|
r1725 | |||
Release checklist | ||||
================= | ||||
Most of the release process is automated by the :file:`release` script in the | ||||
:file:`tools` directory. This is just a handy reminder for the release manager. | ||||
#. Run the release script, which makes the tar.gz, eggs and Win32 .exe | ||||
installer. It posts them to the site and registers the release with PyPI. | ||||
Brian Granger
|
r1789 | #. Updating the website with announcements and links to the updated | ||
changes.txt in html form. Remember to put a short note both on the news | ||||
page of the site and on Launcphad. | ||||
Fernando Perez
|
r1725 | |||
#. Drafting a short release announcement with i) highlights and ii) a link to | ||||
the html changes.txt. | ||||
#. Make sure that the released version of the docs is live on the site. | ||||
#. Celebrate! | ||||
Brian Granger
|
r1789 | |||
.. [Bazaar] Bazaar. http://bazaar-vcs.org/ | ||||
.. [Launchpad] Launchpad. http://www.launchpad.net/ipython | ||||
.. [reStructuredText] reStructuredText. http://docutils.sourceforge.net/rst.html | ||||
.. [Sphinx] Sphinx. http://sphinx.pocoo.org/ | ||||
.. [Nose] Nose: a discovery based unittest extension. http://code.google.com/p/python-nose/ | ||||