|
| 1 | +Contributing to NumCodecs |
| 2 | +========================= |
| 3 | + |
| 4 | +NumCodecs is a community maintained project. We welcome contributions in the form of bug |
| 5 | +reports, bug fixes, documentation, enhancement proposals and more. This page provides |
| 6 | +information on how best to contribute. |
| 7 | + |
| 8 | +Asking for help |
| 9 | +--------------- |
| 10 | + |
| 11 | +If you have a question about how to use NumCodecs, please post your question on |
| 12 | +StackOverflow using the `"numcodecs" tag <https://stackoverflow.com/questions/tagged/numcodecs>`_. |
| 13 | +If you don't get a response within a day or two, feel free to raise a `GitHub issue |
| 14 | +<https://github.com/zarr-developers/numcodecs/issues/new>`_ including a link to your |
| 15 | +StackOverflow question. We will try to respond to questions as quickly as possible, but |
| 16 | +please bear in mind that there may be periods where we have limited time to answer |
| 17 | +questions due to other commitments. |
| 18 | + |
| 19 | +Bug reports |
| 20 | +----------- |
| 21 | + |
| 22 | +If you find a bug, please raise a `GitHub issue |
| 23 | +<https://github.com/zarr-developers/numcodecs/issues/new>`_. Please include the following items in |
| 24 | +a bug report: |
| 25 | + |
| 26 | +1. A minimal, self-contained snippet of Python code reproducing the problem. You can |
| 27 | + format the code nicely using markdown, e.g.:: |
| 28 | + |
| 29 | + |
| 30 | + ```python |
| 31 | + >>> import numcodecs |
| 32 | + >>> codec = numcodecs.Zlib(1) |
| 33 | + ... |
| 34 | + ``` |
| 35 | + |
| 36 | +2. Information about the version of NumCodecs, along with versions of dependencies and the |
| 37 | + Python interpreter, and installation information. The version of NumCodecs can be obtained |
| 38 | + from the ``numcodecs.__version__`` property. Please also state how NumCodecs was installed, |
| 39 | + e.g., "installed via pip into a virtual environment", or "installed using conda". |
| 40 | + Information about other packages installed can be obtained by executing ``pip list`` |
| 41 | + (if using pip to install packages) or ``conda list`` (if using conda to install |
| 42 | + packages) from the operating system command prompt. The version of the Python |
| 43 | + interpreter can be obtained by running a Python interactive session, e.g.:: |
| 44 | + |
| 45 | + $ python |
| 46 | + Python 3.6.1 (default, Mar 22 2017, 06:17:05) |
| 47 | + [GCC 6.3.0 20170321] on linux |
| 48 | + |
| 49 | +3. An explanation of why the current behaviour is wrong/not desired, and what you |
| 50 | + expect instead. |
| 51 | + |
| 52 | +Enhancement proposals |
| 53 | +--------------------- |
| 54 | + |
| 55 | +If you have an idea about a new feature or some other improvement to NumCodecs, please raise a |
| 56 | +`GitHub issue <https://github.com/zarr-developers/numcodecs/issues/new>`_ first to discuss. |
| 57 | + |
| 58 | +We very much welcome ideas and suggestions for how to improve NumCodecs, but please bear in |
| 59 | +mind that we are likely to be conservative in accepting proposals for new features. The |
| 60 | +reasons for this are that we would like to keep the NumCodecs code base lean and focused on |
| 61 | +a core set of functionalities, and available time for development, review and maintenance |
| 62 | +of new features is limited. But if you have a great idea, please don't let that stop |
| 63 | +you posting it on GitHub, just please don't be offended if we respond cautiously. |
| 64 | + |
| 65 | +Contributing code and/or documentation |
| 66 | +-------------------------------------- |
| 67 | + |
| 68 | +Forking the repository |
| 69 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 70 | + |
| 71 | +The NumCodecs source code is hosted on GitHub at the following location: |
| 72 | + |
| 73 | +* `https://github.com/zarr-developers/numcodecs <https://github.com/zarr-developers/numcodecs>`_ |
| 74 | + |
| 75 | +You will need your own fork to work on the code. Go to the link above and hit |
| 76 | +the "Fork" button. Then clone your fork to your local machine:: |
| 77 | + |
| 78 | + $ git clone [email protected]:your-user-name/numcodecs.git |
| 79 | + $ cd numcodecs |
| 80 | + $ git remote add upstream [email protected]:zarr-developers/numcodecs.git |
| 81 | + |
| 82 | +Creating a development environment |
| 83 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 84 | + |
| 85 | +To work with the NumCodecs source code, it is recommended to set up a Python virtual |
| 86 | +environment and install all NumCodecs dependencies using the same versions as are used by |
| 87 | +the core developers and continuous integration services. Assuming you have a Python |
| 88 | +3 interpreter already installed, and have also installed the virtualenv package, and |
| 89 | +you have cloned the NumCodecs source code and your current working directory is the root of |
| 90 | +the repository, you can do something like the following:: |
| 91 | + |
| 92 | + $ mkdir -p ~/pyenv/numcodecs-dev |
| 93 | + $ virtualenv --no-site-packages --python=/usr/bin/python3.6 ~/pyenv/numcodecs-dev |
| 94 | + $ source ~/pyenv/numcodecs-dev/bin/activate |
| 95 | + $ pip install -r requirements_dev.txt |
| 96 | + $ python setup.py build_ext --inplace |
| 97 | + |
| 98 | +To verify that your development environment is working, you can run the unit tests:: |
| 99 | + |
| 100 | + $ pytest -v numcodecs |
| 101 | + |
| 102 | +Creating a branch |
| 103 | +~~~~~~~~~~~~~~~~~ |
| 104 | + |
| 105 | +Before you do any new work or submit a pull request, please open an issue on GitHub to |
| 106 | +report the bug or propose the feature you'd like to add. |
| 107 | + |
| 108 | +It's best to create a new, separate branch for each piece of work you want to do. E.g.:: |
| 109 | + |
| 110 | + git fetch upstream |
| 111 | + git checkout -b shiny-new-feature upsteam/master |
| 112 | + |
| 113 | +This changes your working directory to the 'shiny-new-feature' branch. Keep any changes in |
| 114 | +this branch specific to one bug or feature so it is clear what the branch brings to |
| 115 | +NumCodecs. |
| 116 | + |
| 117 | +To update this branch with latest code from NumCodecs, you can retrieve the changes from |
| 118 | +the master branch and perform a rebase:: |
| 119 | + |
| 120 | + git fetch upstream |
| 121 | + git rebase upstream/master |
| 122 | + |
| 123 | +This will replay your commits on top of the latest NumCodecs git master. If this leads to |
| 124 | +merge conflicts, these need to be resolved before submitting a pull request. |
| 125 | +Alternatively, you can merge the changes in from upstream/master instead of rebasing, |
| 126 | +which can be simpler:: |
| 127 | + |
| 128 | + git fetch upstream |
| 129 | + git merge upstream/master |
| 130 | + |
| 131 | +Again, any conflicts need to be resolved before submitting a pull request. |
| 132 | + |
| 133 | +Running the test suite |
| 134 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 135 | + |
| 136 | +NumCodecs includes a suite of unit tests, as well as doctests included in function and class |
| 137 | +docstrings. The simplest way to run the unit tests is to invoke:: |
| 138 | + |
| 139 | + $ pytest -v numcodecs |
| 140 | + |
| 141 | +To also run the doctests within docstrings, run:: |
| 142 | + |
| 143 | + $ pytest -v --doctest-modules numcodecs |
| 144 | + |
| 145 | +Tests can be run under different Python versions using tox. E.g. (assuming you have the |
| 146 | +corresponding Python interpreters installed on your system):: |
| 147 | + |
| 148 | + $ tox -e py27,py34,py35,py36 |
| 149 | + |
| 150 | +NumCodecs currently supports Python 2.7 and Python 3.4-3.6, so the above command must |
| 151 | +succeed before code can be accepted into the main code base. Note that only the py36 |
| 152 | +tox environment runs the doctests, i.e., doctests only need to succeed under Python 3.6. |
| 153 | + |
| 154 | +All tests are automatically run via Travis (Linux) and AppVeyor (Windows) continuous |
| 155 | +integration services for every pull request. Tests must pass under both services before |
| 156 | +code can be accepted. |
| 157 | + |
| 158 | +Code standards |
| 159 | +~~~~~~~~~~~~~~ |
| 160 | + |
| 161 | +All code must conform to the PEP8 standard. Regarding line length, lines up to 100 |
| 162 | +characters are allowed, although please try to keep under 90 wherever possible. |
| 163 | +Conformance can be checked by running:: |
| 164 | + |
| 165 | + $ flake8 --max-line-length=100 numcodecs |
| 166 | + |
| 167 | +This is automatically run when invoking ``tox -e py36``. |
| 168 | + |
| 169 | +Test coverage |
| 170 | +~~~~~~~~~~~~~ |
| 171 | + |
| 172 | +NumCodecs maintains 100% test coverage under the latest Python stable release (currently |
| 173 | +Python 3.6). Both unit tests and docstring doctests are included when computing |
| 174 | +coverage. Running ``tox -e py36`` will automatically run the test suite with coverage |
| 175 | +and produce a coverage report. This should be 100% before code can be accepted into the |
| 176 | +main code base. |
| 177 | + |
| 178 | +When submitting a pull request, coverage will also be collected across all supported |
| 179 | +Python versions via the Coveralls service, and will be reported back within the pull |
| 180 | +request. Coveralls coverage must also be 100% before code can be accepted. |
| 181 | + |
| 182 | +Documentation |
| 183 | +~~~~~~~~~~~~~ |
| 184 | + |
| 185 | +Docstrings for user-facing classes and functions should follow the `numpydoc |
| 186 | +<https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt>`_ standard, |
| 187 | +including sections for Parameters and Examples. All examples will be run as doctests |
| 188 | +under Python 3.6. |
| 189 | + |
| 190 | +NumCodecs uses Sphinx for documentation, hosted on readthedocs.org. Documentation is |
| 191 | +written in the RestructuredText markup language (.rst files) in the ``docs`` folder. |
| 192 | +The documentation consists both of prose and API documentation. All user-facing classes |
| 193 | +and functions should be included in the API documentation. Any changes should also be |
| 194 | +included in the release notes (``docs/release.rst``). |
| 195 | + |
| 196 | +The documentation can be built by running:: |
| 197 | + |
| 198 | + $ tox -e docs |
| 199 | + |
| 200 | +The resulting built documentation will be available in the ``.tox/docs/tmp/html`` folder. |
| 201 | + |
| 202 | +Development best practices, policies and procedures |
| 203 | +--------------------------------------------------- |
| 204 | + |
| 205 | +The following information is mainly for core developers, but may also be of interest to |
| 206 | +contributors. |
| 207 | + |
| 208 | +Merging pull requests |
| 209 | +~~~~~~~~~~~~~~~~~~~~~ |
| 210 | + |
| 211 | +Pull requests submitted by an external contributor should be reviewed and approved by at least |
| 212 | +one core developers before being merged. Ideally, pull requests submitted by a core developer |
| 213 | +should be reviewed and approved by at least one other core developers before being merged. |
| 214 | + |
| 215 | +Pull requests should not be merged until all CI checks have passed (Travis, AppVeyor, |
| 216 | +Coveralls) against code that has had the latest master merged in. |
| 217 | + |
| 218 | +Compatibility and versioning policies |
| 219 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 220 | + |
| 221 | +Because NumCodecs is a data encoding/decoding library, there are two types of compatibility to |
| 222 | +consider: API compatibility and data format compatibility. |
| 223 | + |
| 224 | +API compatibility |
| 225 | +""""""""""""""""" |
| 226 | + |
| 227 | +All functions, classes and methods that are included in the API |
| 228 | +documentation (files under ``docs/api/*.rst``) are considered as part of the NumCodecs |
| 229 | +**public API**, except if they have been documented as an experimental feature, in which case they |
| 230 | +are part of the **experimental API**. |
| 231 | + |
| 232 | +Any change to the public API that does **not** break existing third party |
| 233 | +code importing NumCodecs, or cause third party code to behave in a different way, is a |
| 234 | +**backwards-compatible API change**. For example, adding a new function, class or method is usually |
| 235 | +a backwards-compatible change. However, removing a function, class or method; removing an argument |
| 236 | +to a function or method; adding a required argument to a function or method; or changing the |
| 237 | +behaviour of a function or method, are examples of **backwards-incompatible API changes**. |
| 238 | + |
| 239 | +If a release contains no changes to the public API (e.g., contains only bug fixes or |
| 240 | +other maintenance work), then the micro version number should be incremented (e.g., |
| 241 | +2.2.0 -> 2.2.1). If a release contains public API changes, but all changes are |
| 242 | +backwards-compatible, then the minor version number should be incremented |
| 243 | +(e.g., 2.2.1 -> 2.3.0). If a release contains any backwards-incompatible public API changes, |
| 244 | +the major version number should be incremented (e.g., 2.3.0 -> 3.0.0). |
| 245 | + |
| 246 | +Backwards-incompatible changes to the experimental API can be included in a minor release, |
| 247 | +although this should be minimised if possible. I.e., it would be preferable to save up |
| 248 | +backwards-incompatible changes to the experimental API to be included in a major release, and to |
| 249 | +stabilise those features at the same time (i.e., move from experimental to public API), rather than |
| 250 | +frequently tinkering with the experimental API in minor releases. |
| 251 | + |
| 252 | +Data format compatibility |
| 253 | +""""""""""""""""""""""""" |
| 254 | + |
| 255 | +Each codec class in NumCodecs exposes a ``codec_id`` attribute, which is an identifier for the |
| 256 | +**format of the encoded data** produced by that codec. Thus it is valid for two or more codec |
| 257 | +classes to expose the same value for the ``codec_id`` attribute if the format of the encoded data |
| 258 | +is identical. The ``codec_id`` is intended to provide a basis for achieving and managing |
| 259 | +interoperability between versions of the NumCodecs package, as well as between NumCodecs and other |
| 260 | +software libraries that aim to provide compatible codec implementations. Currently there is no |
| 261 | +formal specification of the encoded data format corresponding to each ``codec_id``, so the codec |
| 262 | +classes provided in the NumCodecs package should be taken as the reference implementation for a |
| 263 | +given ``codec_id``. |
| 264 | + |
| 265 | +There must be a one-to-one mapping from ``codec_id`` values to encoded data formats, and that |
| 266 | +mapping must not change once the first implementation of a ``codec_id`` has been published within a |
| 267 | +NumCodecs release. If a change is proposed to the encoded data format for a particular type of |
| 268 | +codec, then this must be implemented in NumCodecs via a new codec class exposing a new ``codec_id`` |
| 269 | +value. |
| 270 | + |
| 271 | +Note that the NumCodecs test suite includes a data fixture and tests to try and ensure that |
| 272 | +data format compatibility is not accidentally broken. See the |
| 273 | +:func:`test_backwards_compatibility` functions in test modules for each codec for examples. |
| 274 | + |
| 275 | +When to make a release |
| 276 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 277 | + |
| 278 | +Ideally, any bug fixes that don't change the public API should be released as soon as |
| 279 | +possible. It is fine for a micro release to contain only a single bug fix. |
| 280 | + |
| 281 | +When to make a minor release is at the discretion of the core developers. There are no |
| 282 | +hard-and-fast rules, e.g., it is fine to make a minor release to make a single new |
| 283 | +feature available; equally, it is fine to make a minor release that includes a number of |
| 284 | +changes. |
| 285 | + |
| 286 | +Major releases obviously need to be given careful consideration, and should be done as |
| 287 | +infrequently as possible, as they will break existing code and/or affect data |
| 288 | +compatibility in some way. |
| 289 | + |
| 290 | +Release procedure |
| 291 | +~~~~~~~~~~~~~~~~~ |
| 292 | + |
| 293 | +Checkout and update the master branch:: |
| 294 | + |
| 295 | + $ git checkout master |
| 296 | + $ git pull |
| 297 | + |
| 298 | +Verify all tests pass on all supported Python versions, and docs build:: |
| 299 | + |
| 300 | + $ tox |
| 301 | + |
| 302 | +Tag the version (where "X.X.X" stands for the version number, e.g., "2.2.0"):: |
| 303 | + |
| 304 | + $ version=X.X.X |
| 305 | + $ git tag -a v$version -m v$version |
| 306 | + $ git push --tags |
| 307 | + |
| 308 | +Release source code to PyPI:: |
| 309 | + |
| 310 | + $ python setup.py register sdist |
| 311 | + $ twine upload dist/numcodecs-${version}.tar.gz |
| 312 | + |
| 313 | +Obtain checksum for release to conda-forge:: |
| 314 | + |
| 315 | + $ openssl sha256 dist/numcodecs-${version}.tar.gz |
| 316 | + |
| 317 | +Release to conda-forge by making a pull request against the numcodecs-feedstock conda-forge |
| 318 | +repository, incrementing the version number. |
0 commit comments