General information for developers

The PyClaw repository is hosted on Github at http://github.com/clawpack/pyclaw.

Guidelines for contributing

When preparing contributions, please follow the guidelines in Contributing to PyClaw code development. Also:

  • If the planned changes are substantial or will be backward-incompatible, it’s best to discuss them on the claw-dev Google group before starting.

  • Make sure all tests pass and all the built-in examples run correctly.

  • Be verbose and detailed in your commit messages and your pull request.

  • It may be wise to have one of the maintainers look at your changes before they are complete (especially if the changes will necessitate modifications of tests and/or examples).

  • If your changes are not backward-compatible, your pull request should include instructions for users to update their own application codes.

Bugs

If you find a bug, post an issue with as much explanation as possible on the Issue tracker at https://github.com/clawpack/pyclaw/issues. If you’re looking for something useful to do, try tackling one of the issues listed there.

Developer communication

As PyClaw is part of the family of Clawpack codes, developer communication takes place on the google group at http://groups.google.com/group/claw-dev/.

Dependencies

It is almost always okay to add “optional dependencies”, for example, creating an optional feature or application that is only enabled when the software dependencies for that feature are satisfied. petclaw is an example of this, as it provides an optional means of running many PyClaw applications in parallel.

In general, introduction of general dependencies should be avoided. If you wish to make a change that will introduce a new dependency (including depending on a more recent version of a particular package), it should be discussed on the claw-dev Google group first.

New versions of existing dependencies will typically be adopted either when new functionality provides an important benefit for PyClaw or when the currently supported version is deemed to be substantially outdated.

Running the tests

The PyClaw test suite is built around nosetests for automatic test discovery, with supplementary functionality from the pyclaw.util module. To run the complete test suite with helpful output, issue the following command at the top-level of the pyclaw source directory:

nosetests -vs

To run the parallel versions of the tests (if petsc4py is installed), run:

mpirun -n 4 nosetests -vs

(Replace 4 with the number of processes you’d like test on)

Try prime numbers if you’re really trying to break things!

Running serial tests simultaneously

When running the tests, if your machine has multiple cores you can take advantage of them by doing:

nosetests -vs --processes=2

(replace “2” with the number of processes you want to spawn). However, using large numbers of processes occasionally causes spurious failure of some tests due to issues with the operating system. If you see this behavior, it’s best to run the tests in serial or with a small number of processes.

Running a specific test

The PyClaw tests are associated with particular applications in the examples/ sub- directory of the primary repository directory. If you want to run tests for a specific application, simply specify the directory containing the application you are interested in:

nosetests -vs examples/acoustics_3d_variable

You can also specify a single file to run the tests it contains.

Doctests

Several of the main PyClaw modules also have doctests (tests in their docstrings). You can run them by executing the corresponding module:

cd $PYCLAW/src/pyclaw
python grid.py
python state.py

If the tests pass, you will see no output. You can get more output by using the -v option:

python state.py -v

Writing New Tests

If you contribute new functionality to PyClaw, it is expected that you will also write at least one or two new tests that exercise your contribution, so that further changes to other parts of PyClaw or your code don’t break your feature. You do not have to use any of the functionality offered by pyclaw.util, but it may simplify your test-writing and allow you to check more cases than you would easily specify by hand.

The most important function in pyclaw.util is pyclaw.util.gen_variants(), which allows you to perform combinatorial testing without manually specifying every feature you’d like to perform. Currently, gen_variants() can multiplicatively exercise kernel_languages (Fortran or Python) and pure PyClaw or PetClaw implementations. This allows you to write one function that tests four variants.

Another function provided by util is pyclaw.util.test_app(). The test_app() function will run an application as if started from the command line with the specified keyword arguments passed in. This is useful for testing specific code that does not necessarily work with petclaw, for example, and is not expected to.

You will notice that both gen_variants() and test_app() require a verifier method as an argument. These functions both effectively run tests and verify output with the following function calls:

output = application(**kwargs)
check_values = verifier(output)

The verifier method needs to return None if there is no problem with the output, or a sequence of three values describing what was expected, what it received, and more details about the error. A very simple verifier method that you can use is pyclaw.util.check_diff(), which can use either an absolute tolerance or a relative tolerance to compare an expected value against the test output from the application.

See examples/acoustics_1d_homogeneous/test_acoustics.py for a comprehensive example of how to use gen_variants() and check_diff(). See examples/shallow_sphere/test_shallow_sphere.py for an example that uses test_app() and also loads a known solution from disk using numpy.

Catching errors with Pyflakes and Pylint

Pyflakes and Pylint are Python packages designed to help you catch errors or poor coding practices. To run pylint on the whole PyClaw package, do:

cd $PYCLAW
pylint -d C pyclaw

The -d option suppresses a lot of style warnings, since PyClaw doesn’t generally conform to PEP8. To run pylint on just one module, use something like:

pylint -d C pyclaw.state

Since pylint output can be long, it’s helpful to write it to an html file and open that in a web browser:

pylint -d C pyclaw.state -f html > pylint.html

Pyflakes is similar to pylint but aims only to catch errors. If you use Vim, there is a nice extension package pyflakes.vim that will catch errors as you code and underline them in red.

Checking test coverage

You can use nose to see how much of the code is covered by the current suite of tests and track progress if you add more tests

nosetests --with-coverage --cover-package=pyclaw --cover-html

This creates a set of html files in ./cover, showing exactly which lines of code have been tested.