Development workflow

Setting up your development environment

Make a virtual environment:

$ mkdir devel
$ cd devel
$ python3 -m venv venv
$ source venv/bin/activate  # venv/bin/ is now first in $PATH
$ pip install --upgrade pip

Install master branch of ASE in editable mode:

$ git clone
$ pip install --editable ase/

Same thing for GPAW:

$ git clone
$ echo "noblas = True; nolibxc = True" > gpaw/
$ pip install -e gpaw


Here we used a simple that should always work:

  • noblas = True: Use the BLAS library built into NumPy (usually OpenBLAS).

  • nolibxc = True: Use GPAW’s own XC-functionals (only LDA, PBE, revPBE, RPBE and PW91).

See Customizing installation for details.

Download PAW datasets:

$ gpaw install-data --register ~/PAWDATA

Run the tests

The test-suite can be found in gpaw/test/. Run it like this:

$ pip install pytest-xdist
$ cd gpaw
$ pytest -n4

And with MPI (2, 4 and 8 cores):

$ mpiexec -n 2 pytest


This will take forever! It’s a good idea to learn and master pytest’s command-line options for selecting the subset of all the tests that are relevant.

Creating a merge request

Request to become a member of the gpaw project on GitLab here. This will allow you to push branches to the central repository (see below).

Create a branch for your changes:

$ cd gpaw
$ git switch -c fix-something


git switch -c fix-something is the same as any of these:

  • git branch fix-something && git switch fix-something

  • git branch fix-something && git checkout fix-something

  • git checkout -b fix-something

More git-tricks.

Make some changes and commit:

$ git add file1 file2 ...
$ git commit -m "Short summary of changes"

Push your branch to GitLab:

$ git push --set-upstream origin fix-something

and click the link to create a merge-request (MR). Mark the MR as DRAFT to signal that it is work-in-progress and remove the DRAFT-marker once the MR is ready for code review.

Every time you push your local repository changes upstream to the remote repository, you will trigger a continuous integration (CI) runner on the GitLab servers. The script that runs in CI is .gitlab-ci.yml. Here is a short summary of what happens in CI:

  • install the code

  • pytest -m ci: small selection of fast tests

  • mypy -p gpaw: Static code analysis (type hints)

  • flake8: pyflakes + pycodestyle (pep8) = flake8

If CI fails, you will have to fix things and push your changes.

It’s a good idea to also run the CI-checks locally:

$ pip install flake8 mypy
$ flake8 ...
$ mypy ...
$ pytest ...
$ # fix things
$ git add ...
$ git commit ...
$ git push  # Git now knows your upstream


You can use git push -i ci.skip if you want to skip CI.

How to write a good MR

A good MR

  • is short

  • does one thing

  • is not too old

For MRs with code changes:

  • make sure there is a test that covers the new/fixed code

  • make sure all variable and functions have descriptive names.

  • remember docstrings - if needed (no need for an add_numbers() function to have an """Add numbers.""" docstring).

For MRs with documentation changes, build the HTML-pages and make sure everything looks OK:

$ pip install sphinx-rtd-theme
$ cd gpaw/doc
$ make
$ make browse