Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.
Everyone interacting in the QDYN-pylib project's code base, issue tracker, and any communication channels is expected to follow the PyPA Code of Conduct.
Report bugs at https://github.com/qucontrol/qdynpylib/issues.
If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug, ideally a minimal but complete script or notebook.
- All error messages in full, as plain text. If the output is long, attach it as a file.
The best way to send feedback is to file an issue at https://github.com/qucontrol/qdynpylib/issues.
If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome :)
Before you submit a pull request, check that it meets these guidelines:
- The pull request should include tests.
- If the pull request adds functionality, the docs should be updated.
- Check https://github.com/qucontrol/qdynpylib/actions and make sure that the tests pass for all supported Python versions.
Ready to contribute? Follow Aaron Meurer's Git Workflow Notes (with qucontrol/qdyn
instead of sympy/sympy
)
In short,
- Clone the repository from
[email protected]:qucontrol/qdyn.git
- Fork the repo on GitHub to your personal account.
- Add your fork as a remote.
- Pull in the latest changes from the master branch.
- Create a topic branch.
- Make your changes and commit them (testing locally).
- Push changes to the topic branch on your remote.
- Make a pull request against the base master branch through the Github website of your fork.
The project uses tox for automated testing across multiple versions of Python and for various development tasks such as linting and generating the documentation. See Development Prerequisites for details.
There is also a Makefile
that wraps around tox, for convenience on Unix-based systems. In your checked-out clone, run
make help
to see the available make targets. If you cannot use make
, but want to use tox
directly (e.g., on Windows), run
tox -av
to see a list of tox environments and a description.
Contributing to the package's developments requires that you have Python 3.8 and tox installed. It is strongly recommended that you also have installations of all other supported Python versions. The recommended way to install multiple versions of Python at the same time is through pyenv (or pyenv-win on Windows).
For developers with direct access to the repository, QDYN-pylib uses a simple branching model where all developments happens directly on the master
branch. Releases are tags on master
. All commits on master
should pass all tests and be well-documented. This is so that git bisect
can be effective. For any non-trivial issue, it is recommended to create a topic branch, instead of working on master
. There are no restrictions on commits on topic branches, they do not need to contain complete documentation, pass any tests, or even be able to run.
To create a topic-branch named to address issue #1:
git branch 1-title-of-issue
git checkout 1-title-of-issue
You can then make commits, and push them to Github to trigger Continuous Integration testing:
git push -u origin 1-title-of-issue
Commit early and often! You are welcome to rewrite history on topic branches by force-pushing. Before submitting a pull request or merging into master
, clean up the commit history of the topic branch.
- Avoid having a series of meaningless granular commits like "start bugfix", "continue development", "add more work on bugfix", "fix typos", and so forth. Instead, use
git commit --amend
to add to your previous commit. This is the ideal way to "commit early and often". You do not have to wait until a commit is "perfect"; it is a good idea to make hourly/daily "snapshots" of work in progress. Amending a commit also allows you to change the commit message of your last commit. - You can combine multiple existing commits by "squashing" them. For example, use
git rebase -i HEAD~4
to combined the previous four commits into one. See the "Rewriting History" section of Pro Git book for details (if you feel this is too far outside of your git comfort zone, just skip it). - You can use the
--fixup
flag forgit commit
to add to a previous commit. Fixup commits must be squashed (git rebase --autosquash
) before merging. - If you work on a topic branch for a long time, and there is significant work on
master
in the meantime, periodically rebase your topic branch on the current master (git rebase master
). Avoid mergingmaster
into your topic branch. See Merging vs. Rebasing.
If you are collaborating with others on a topic branch, coordinate with them before rewriting history.
When you are done with a topic branch (the issue has been fixed), finish up by merging the topic branch back into master
:
git checkout master
git merge --no-ff 1-title-of-issue
The --no-ff
option is critical, so that an explicit merge commit is created (especially if you rebased). Summarize the changes of the branch relative to master
in the commit message.
Then, you can push master and delete the topic branch both locally and on Github:
git push origin master
git push --delete origin 1-title-of-issue
git branch -D 1-title-of-issue
Write commit messages according to this template:
Short (50 chars or less) summary ("subject line")
More detailed explanatory text. Wrap it to 72 characters. The blank
line separating the summary from the body is critical (unless you omit
the body entirely).
Write your subject line in the imperative: "Fix bug" and not "Fixed
bug" or "Fixes bug." This convention matches up with commit messages
generated by commands like git merge and git revert. A properly formed
git commit subject line should always be able to complete the sentence
"If applied, this commit will <your subject line here>".
Further paragraphs come after blank lines.
- Bullet points are okay, too.
- Typically a hyphen or asterisk is used for the bullet, followed by a
single space. Use a hanging indent.
You should reference any issue that is being addressed in the commit, as
e.g. "#1" for issue #1. If the commit closes an issue, state this on the
last line of the message (see below). This will automatically close the
issue on Github as soon as the commit is pushed there.
Closes #1
See Closing issues using keywords for details on references to issues that Github will understand.
QDYN-pylib includes a full test-suite using pytest. We strive for a test coverage above 90%.
From a checkout of the qdyn
repository you can use
make test
to run the entire test suite, or
tox -e py37-test,py38-test,py39-test
if make
is not available.
The tests are organized in the tests
subfolder. It includes python scripts whose name start with test_
, which contain functions whose names also start with test_
. Any such functions in any such files are picked up by pytest for testing. In addition, doctests from any docstring or any documentation file (*.rst
) are picked up (by the pytest doctest plugin).
All code must be compatible with PEP 8. The line length limit is 79 characters, although exceptions are permissible if this improves readability significantly.
Beyond PEP 8, this project adopts the Black code style. You can run make black-check
or tox -e run-blackcheck
to check adherence to the code style, and make black
or tox -e run-black
to apply it.
Imports within python modules must be sorted according to the isort configuration in setup.cfg
. The command make isort-check
or tox -e run-isortcheck
checks whether all imports are sorted correctly, and make isort
or tox -e run-isort
modifies all Python modules in-place with the proper sorting.
The code style is enforced as part of the test suite, as well as through git pre-commit hooks that prevent committing code not does not meet the requirements. These hooks are managed through the pre-commit framework.
You may use make flake8-check
or tox -e run-flake8
and make pylint-check
or tox -e run-pylint
for additional checks on the code with flake8 and pylint, but there is no strict requirement for a perfect score with either one of these linters. They only serve as a guideline for code that might be improved.
QDYN-pylib could always use more documentation, whether as part of the official docs, in docstrings, or even on the web in blog posts, articles, and such.
The package documentation is generated with Sphinx, the documentation (and docstrings) are formatted using the Restructured Text markup language (file extension rst
). See also the Matplotlib Sphinx cheat sheet for some helpful tips.
The Documentation should be structured in four distinct categories:
- Tutorials (learning-oriented)
- How-to Guides (problem-oriented)
- Reference Guides / API (information-oriented)
- Explanations (understanding-oriented)
For the API documentation, each function or class must have a docstring; this docstring must be written in the "Google Style" format (as implemented by Sphinx' napoleon extension). Docstrings and any other part of the documentation can include mathematical formulas in LaTeX syntax (using mathjax).
For module variables and class attributes, use a docstring "inline" immediately after the definition. However, for instance attributes, it is preferable to include an "Attributes:" section in the class docstring (instead of using "attribute docstrings" in __init__
). While attribute docstrings have the benefit that it is less likely for there to be a mismatch between the documentation and the implementation, they also have some significant drawbacks, for example: They do not show up in help(<class>)
or <class>?
in IPython, they tend to make __init__
much harder to read, and they don't work for classes defined via attrs.
The __init__
method should never have a docstring; it's arguments are described in the class docstring instead.
At any point, from a checkout of the qdyn
repository, you may run
make docs
or
tox -e docs
to generate the documentation locally.
Releases should follow Semantic Versioning, and version numbers published to PyPI must be compatible with PEP 440.
In short, versions number follow the pattern major.minor.patch
, e.g. 0.1.0
for the first release, and 1.0.0
for the first stable release. If necessary, pre-release versions might be published as e.g:
1.0.0-dev1 # developer's preview 1 for release 1.0.0
1.0.0-rc1 # release candidate 1 for 1.0.0
Errors in the release metadata or documentation only may be fixed in a post-release, e.g.:
1.0.0.post1 # first post-release after 1.0.0
Post-releases should be used sparingly, but they are acceptable even though they are not supported by the Semantic Versioning specification.
The current version is available through the __version__
attribute of the qdyn
package
Between releases, __version__
on the master branch should either be the version number of the last release, with "+dev" appended (as a "local version identifier"), or the version number of the next planned release, with "-dev" appended ("pre-release identifier" with extra dash). The version string "1.0.0-dev1+dev" is a valid value after the "1.0.0-dev1" pre-release. The "+dev" suffix must never be included in a release to PyPI.
Note that twine applies normalization to the above recommended forms to make them strictly compatible with PEP 440, before uploading to PyPI. Users installing the package through pip may use the original version specification as well as the normalized one (or any other variation that normalizes to the same result).
When making a release via
make release
the above versioning conventions will be taken into account automatically.
Releases must be tagged in git, using the version string prefixed by "v", e.g. v1.0.0-dev1
and v1.0.0
. This makes them available at https://github.com/qucontrol/qdynpylib/releases.