|
1 | 1 | # Python guidelines
|
2 | 2 |
|
3 |
| -For any [Python][py] code, please stick to the guidelines described in this |
| 3 | +For all [Python][py] code, please stick to the guidelines described in this |
4 | 4 | section.
|
5 | 5 |
|
6 | 6 | ## Python version
|
7 | 7 |
|
8 |
| -For any new projects, please use one of the two most recent [Python minor |
9 |
| -versions][py-downloads]. For existing projects, use the Python version used |
10 |
| -throughout the project. |
| 8 | +For any _new_ projects, please use one of the two most recent [Python minor |
| 9 | +versions][py-downloads], exclusing pre-releases. For existing projects, use the |
| 10 | +Python version used throughout the project (mentioned in `pyproject.toml`). |
11 | 11 |
|
12 |
| -## Code formatting |
| 12 | +## Packaging, build system & dependencies |
13 | 13 |
|
14 |
| -Please format the code using [`black`][py-black] and default parameters. Where |
15 |
| -[`black`][py-black] is not prescriptive, please use a consistent coding style. |
16 |
| -In particular, when contributing to an existing code base, please adhere to the |
17 |
| -coding style you find. In all cases, please adhere to [PEP 8][py-pep8]. |
| 14 | +Please use [`pyproject.toml`][py-toml] to configure packaging, building, and |
| 15 | +dependency management. Please do not use `setup.py` and do no specify your |
| 16 | +dependencies in `requirements.txt`, except for legacy projects where they are |
| 17 | +still used. |
18 | 18 |
|
19 |
| -## Docstrings |
| 19 | +Preferably, segregate dependencies for different tasks. For example, use |
| 20 | +`[tool.poetry.test.dependencies]` for testing dependencies, and |
| 21 | +`[tool.poetry.dependencies]` for runtime dependencies. |
20 | 22 |
|
21 |
| -Please add [Google-style docstrings][py-doc-google] to _all_ modules, functions |
22 |
| -and methods. Follow [PEP 257][py-pep257]. Do not include types in the |
23 |
| -docstrings. |
| 23 | +Please sort entries (sections, dependencies) in `pyproject.toml` alphabetically |
| 24 | +to ease maintenance. If using Poetry (see below), you can use the |
| 25 | +[`poetry-sort`][py-poetry-sort] plugin to help with this. Otherwise any other |
| 26 | +TOML sorter should work as well. |
| 27 | + |
| 28 | +> **Note**: We strongly recommend using the [Poetry][py-poetry] package manager |
| 29 | +> instead of `pip`. In that case, use `poetry.lock` to lock the dependencies |
| 30 | +> (make > sure to commit the file to version control). To add a new dependency, |
| 31 | +> use the following command: |
| 32 | +> |
| 33 | +> ```python |
| 34 | +> poetry add <package> --group=<group> |
| 35 | +> ``` |
| 36 | +> |
| 37 | +> To build the project, use: |
| 38 | +> |
| 39 | +> ```python |
| 40 | +> poetry build |
| 41 | +> ``` |
| 42 | +
|
| 43 | +### Console scripts |
| 44 | +
|
| 45 | +If your project has one or more console script entry points, use |
| 46 | +`pyproject.toml` file to define them, e.g.: |
| 47 | +
|
| 48 | +```toml |
| 49 | +[tool.poetry.scripts] |
| 50 | +my-script = "my_package.my_module.my_submodule:my_function" |
| 51 | +``` |
| 52 | +
|
| 53 | +## Code formatting and linting |
| 54 | + |
| 55 | +### Ruff |
| 56 | + |
| 57 | +In an effort to reduce dependencies, we recommend using [`ruff`][py-ruff] for |
| 58 | +new projects and configuring it in `pyproject.toml`. Configure strictness based |
| 59 | +on project requirements, but at least use the following: |
| 60 | + |
| 61 | +```toml |
| 62 | +[tool.ruff.lint] |
| 63 | +select = [ |
| 64 | + "B", # flake8-bugbear |
| 65 | + "D", # pydocstyle |
| 66 | + "E", # pycodestyle |
| 67 | + "F", # Pyflakes |
| 68 | + "I", # isort |
| 69 | + "PL", # pylint |
| 70 | + "SIM", # flake8-simplify |
| 71 | + "UP", # pyupgrade |
| 72 | +] |
| 73 | +``` |
| 74 | + |
| 75 | +> **Note**: You can fix lints by running `ruff check --fix <Path>` and `ruff |
| 76 | +> format <Path>` to format the code. |
| 77 | +
|
| 78 | +### Docstrings |
| 79 | + |
| 80 | +Please use [Google-style docstrings][py-doc-google] for all packages, modules, |
| 81 | +classes, methods and functions. With `pydocstyle`, you can enforce this style |
| 82 | +with the following entry in the `pyproject.toml` file: |
| 83 | + |
| 84 | +```toml |
| 85 | +[tool.ruff.lint.pydocstyle] |
| 86 | +convention = "google" |
| 87 | +``` |
| 88 | + |
| 89 | +For **methods and functions**, please include at least the following sections, |
| 90 | +where applicable: |
| 91 | + |
| 92 | +- `Args` |
| 93 | +- `Returns` (or `Yields`, for generator functions) |
| 94 | +- `Raises` |
| 95 | + |
| 96 | +For **classes**, please include the `Attributes` section. |
| 97 | + |
| 98 | +Furthermore, in all cases, consider including `Examples` and `Note` sections. |
24 | 99 |
|
25 | 100 | ## Type hints
|
26 | 101 |
|
27 | 102 | Add [type hints][py-typing] to _all_ function and method signatures, as well as
|
28 |
| -any global variables. Adding type hints to local variables is recommended. |
29 |
| -Adding type hints to (unit) tests is not necessary. |
| 103 | +any global variables. Adding type hints to local variables is recommended if |
| 104 | +types aren't obvious from assignments. |
30 | 105 |
|
31 |
| -## Linters & static type checkers |
| 106 | +Adding type hints to (unit) tests is not necessary. |
32 | 107 |
|
33 |
| -Please make use of the following tools with default parameters to make sure |
34 |
| -your code is of good quality: |
| 108 | +> **Note**: You can try using [MonkeyType][py-monkey-type] to help with adding |
| 109 | +> type hints to your code. |
35 | 110 |
|
36 |
| -- [`flake8`][py-flake8] |
37 |
| -- [`flake8-docstring`][py-flake8-doc] |
38 |
| -- [`pylint`][py-pylint] |
39 |
| -- [`mypy`][py-mypy] |
| 111 | +### Static type checkers |
40 | 112 |
|
41 |
| -When disabling rules is required, it is preferable to do so in-line, rather |
42 |
| -than globally. |
| 113 | +Please use a type checker to check for type consistency across your project. We |
| 114 | +recommend using [`mypy`][py-mypy], but alternatives are acceptable. |
43 | 115 |
|
44 | 116 | ## Testing
|
45 | 117 |
|
46 |
| -Use [`pytest`][py-pytest] as a test runner for unit tests. You can determine |
47 |
| -the test coverage with the [`coverage`][py-cov] package. Strive for a test |
48 |
| -coverage of 100% for new projects. Proposed code changes should never reduce |
49 |
| -the previous test coverage. |
| 118 | +Please provide extensive tests (both unit and integration) for your code and |
| 119 | +determine the test coverage with the [`coverage`][py-cov] package. Strive |
| 120 | +for a test coverage of 100% for unit and 70% for integration tests, because: |
| 121 | + |
| 122 | +> Untested code is broken code. |
| 123 | +
|
| 124 | +Please use [`pytest`][py-pytest] as a runner for your tests (it also comes with |
| 125 | +many useful features and extensions). |
| 126 | + |
| 127 | +Be aware that proposed code changes **must never** reduce the previous test |
| 128 | +coverage. |
0 commit comments