| 
 | 1 | +Code Style Tools  | 
 | 2 | +================  | 
 | 3 | + | 
 | 4 | +There are plenty of tools for checking code style. This section presents some of  | 
 | 5 | +the most popular ones in the Python ecosystem. A minimum configuration is  | 
 | 6 | +provided for each one so you can easily include them in your PyAnsys project.  | 
 | 7 | + | 
 | 8 | +Most of the tools presented can be configured using :ref:`the  | 
 | 9 | +\`\`pyproject.toml\`\` file`, avoiding dotfiles and thus leading to a much  | 
 | 10 | +cleaner root project directory.  | 
 | 11 | + | 
 | 12 | + | 
 | 13 | +Black  | 
 | 14 | +-----  | 
 | 15 | +`Black`_ is the most popular code formatter in the Python community, as it is  | 
 | 16 | +being maintained by the Python Software Foundation. It allows for a minimum  | 
 | 17 | +configuration to ensure that Python code format looks almost the same across  | 
 | 18 | +projects.   | 
 | 19 | + | 
 | 20 | +Unlike `PEP 8`_, the default line length imposed by `black`_ is 88 and not 79  | 
 | 21 | +characters.  | 
 | 22 | + | 
 | 23 | +The minimum black configuration for a PyAnsys project should look like:  | 
 | 24 | + | 
 | 25 | +.. code-block:: toml  | 
 | 26 | +
  | 
 | 27 | +    [tool.black]  | 
 | 28 | +    line-length: "<length>"  | 
 | 29 | +
  | 
 | 30 | +
  | 
 | 31 | +Isort  | 
 | 32 | +-----  | 
 | 33 | +The goal of `isort`_  is to properly format ``import`` statements by making sure  | 
 | 34 | +they follow the standard library, third party libraries and custom library  | 
 | 35 | +order.  | 
 | 36 | + | 
 | 37 | +When using `isort`_ with `black`_, it is important to properly configure both  | 
 | 38 | +tools so no conflicts appear. To do so, make sure you take advantage of the  | 
 | 39 | +``--porfile black`` flag in `isort`_.  | 
 | 40 | + | 
 | 41 | +.. code-block:: toml  | 
 | 42 | +
  | 
 | 43 | +   [tool.isort]  | 
 | 44 | +   profile = "black"  | 
 | 45 | +   force_sort_within_sections = true  | 
 | 46 | +   line_length = "<length>"  | 
 | 47 | +   default_section = "THIRDPARTY"  | 
 | 48 | +   src_paths = ["doc", "src", "tests"]  | 
 | 49 | +
  | 
 | 50 | +
  | 
 | 51 | +Flake8  | 
 | 52 | +------  | 
 | 53 | +The goal of `flake8` is to act as a `PEP 8`_ compliance checker. Again, it is  | 
 | 54 | +important to make sure that if this tool is being used with `black`_, no  | 
 | 55 | +conflicts arise.  | 
 | 56 | + | 
 | 57 | +The following configuration is the minimum one to setup `flake8`_ together with  | 
 | 58 | +`black`_ one.  | 
 | 59 | + | 
 | 60 | +The configuration for `flake8`_ must be specified in a ``.flake8`` file.  | 
 | 61 | + | 
 | 62 | +.. code-block:: toml  | 
 | 63 | +
  | 
 | 64 | +   [flake8]  | 
 | 65 | +   max-line-length = 88  | 
 | 66 | +   extend-ignore = E203  | 
 | 67 | +
  | 
 | 68 | +
  | 
 | 69 | +Pre-commit  | 
 | 70 | +----------  | 
 | 71 | +To make sure that every commit you made is compliant with the code style  | 
 | 72 | +guidelines of PyAnsys, you can take advantage of `pre-commit`_ in your project.  | 
 | 73 | +Every time you stage some changes and once you commit those, `pre-commit`_ will  | 
 | 74 | +only allow you to do so if all the defined hooks succeedd.  | 
 | 75 | + | 
 | 76 | +The configuration for `pre-commit`_ must be defined in a  | 
 | 77 | +`.pre-commit-config.yaml` file. The following lines present a minimum  | 
 | 78 | +`pre-commit`_ configuration which includes both code and documentation  | 
 | 79 | +formatting tools.  | 
 | 80 | + | 
 | 81 | + | 
 | 82 | +.. code-block:: yaml  | 
 | 83 | +
  | 
 | 84 | +    repos:  | 
 | 85 | +      | 
 | 86 | +    - repo: https://github.com/psf/black  | 
 | 87 | +      rev: X.Y.Z  | 
 | 88 | +      hooks:  | 
 | 89 | +      - id: black  | 
 | 90 | +      | 
 | 91 | +    - repo: https://github.com/pycqa/isort  | 
 | 92 | +      rev: X.Y.Z  | 
 | 93 | +      hooks:  | 
 | 94 | +      - id: isort  | 
 | 95 | +      | 
 | 96 | +    - repo: https://gitlab.com/PyCQA/flake8  | 
 | 97 | +      rev: X.Y.Z  | 
 | 98 | +      hooks:  | 
 | 99 | +      - id: flake8  | 
 | 100 | +      | 
 | 101 | +    - repo: https://github.com/codespell-project/codespell  | 
 | 102 | +      rev: vX.Y.Z  | 
 | 103 | +      hooks:  | 
 | 104 | +      - id: codespell  | 
 | 105 | +      | 
 | 106 | +    - repo: https://github.com/pycqa/pydocstyle  | 
 | 107 | +      rev: X.Y.Z  | 
 | 108 | +      hooks:  | 
 | 109 | +      - id: pydocstyle  | 
 | 110 | +        additional_dependencies: [toml]  | 
 | 111 | +        exclude: "tests/"  | 
 | 112 | +
  | 
 | 113 | +Installing ``pre-commit``  | 
 | 114 | +~~~~~~~~~~~~~~~~~~~~~~~~~  | 
 | 115 | +You can install ``pre-commit`` by running:  | 
 | 116 | + | 
 | 117 | +.. code-block:: bash  | 
 | 118 | +
  | 
 | 119 | +    python -m pip install pre-commit  | 
 | 120 | +
  | 
 | 121 | +Then, make sure you install it as a ``Git hook`` by running:  | 
 | 122 | + | 
 | 123 | +.. code-block:: bash  | 
 | 124 | +
  | 
 | 125 | +    pre-commit install  | 
 | 126 | +
  | 
 | 127 | +Using ``pre-commit``  | 
 | 128 | +~~~~~~~~~~~~~~~~~~~~  | 
 | 129 | +From then on, pre-commit will automatically trigger every time you try to commit  | 
 | 130 | +a change. If any of the hooks defined in `.pre-commit-config.yaml` fails, you  | 
 | 131 | +will need to fix the failing files, stage the new changes and try to commit  | 
 | 132 | +those again.  | 
 | 133 | + | 
 | 134 | +If you want to manually run ``pre-commit``, you can execute:  | 
 | 135 | + | 
 | 136 | +.. code-block:: bash  | 
 | 137 | +
  | 
 | 138 | +    pre-commit run --all-files --show-diff-on-failure  | 
 | 139 | +
  | 
 | 140 | +Previous command will show the current and expected style of the code if any of  | 
 | 141 | +the hooks fail.  | 
 | 142 | + | 
 | 143 | + | 
 | 144 | +Using ``pre-commit``  | 
 | 145 | +~~~~~~~~~~~~~~~~~~~~  | 
 | 146 | + | 
 | 147 | +Tox  | 
 | 148 | +---  | 
 | 149 | +A tool you may consider to use in your project is `tox`_. This tool is an  | 
 | 150 | +automation tool similar to `Make`_ but with the advantage of allowing to test  | 
 | 151 | +your package in a temporary virtual environment. This guarantees reproducible  | 
 | 152 | +builds, as your package is no longer tested in "local" mode but in isolated  | 
 | 153 | +form.  | 
 | 154 | + | 
 | 155 | +Configuration for `tox`_ is stored in a ``tox.ini`` file. The minimum  | 
 | 156 | +configuration for a PyAnsys ``py<product>-<library>`` project should be:  | 
 | 157 | + | 
 | 158 | +.. code-block:: ini  | 
 | 159 | +
  | 
 | 160 | +    [tox]  | 
 | 161 | +    description = Default tox environments list  | 
 | 162 | +    envlist =  | 
 | 163 | +        style,{py37,py38,py39,py310}{,-coverage},doc  | 
 | 164 | +    skip_missing_interpreters = true  | 
 | 165 | +    isolated_build = true  | 
 | 166 | +    isolated_build_env = build  | 
 | 167 | +      | 
 | 168 | +    [testenv]  | 
 | 169 | +    description = Checks for project unit tests and coverage (if desired)  | 
 | 170 | +    basepython =  | 
 | 171 | +        py37: python3.7  | 
 | 172 | +        py38: python3.8  | 
 | 173 | +        py39: python3.9  | 
 | 174 | +        py310: python3.10  | 
 | 175 | +        py: python3  | 
 | 176 | +        {style,reformat,doc,build}: python3  | 
 | 177 | +    setenv =  | 
 | 178 | +        PYTHONUNBUFFERED = yes  | 
 | 179 | +        coverage: PYTEST_EXTRA_ARGS = --cov=ansys.product --cov-report=term --cov-report=xml --cov-report=html  | 
 | 180 | +    deps =  | 
 | 181 | +        -r{toxinidir}/requirements/requirements_tests.txt  | 
 | 182 | +    commands =  | 
 | 183 | +        pytest {env:PYTEST_MARKERS:} {env:PYTEST_EXTRA_ARGS:} {posargs:-vv}  | 
 | 184 | +      | 
 | 185 | +    [testenv:style]  | 
 | 186 | +    description = Checks project code style  | 
 | 187 | +    skip_install = true  | 
 | 188 | +    deps =  | 
 | 189 | +        pre-commit  | 
 | 190 | +    commands =  | 
 | 191 | +        pre-commit install  | 
 | 192 | +        pre-commit run --all-files --show-diff-on-failure  | 
 | 193 | +      | 
 | 194 | +    [testenv:doc]  | 
 | 195 | +    description = Check if documentation generates properly  | 
 | 196 | +    deps =  | 
 | 197 | +        -r{toxinidir}/requirements/requirements_doc.txt  | 
 | 198 | +    commands =  | 
 | 199 | +        sphinx-build -d "{toxworkdir}/doc_doctree" doc/source "{toxworkdir}/doc_out" --color -vW -bhtml  | 
 | 200 | +
  | 
 | 201 | +
  | 
 | 202 | +Previous configuration assumes that you have a ``requirements/`` directory that  | 
 | 203 | +contains a ``requirements_tests.txt`` and a ``requirements_doc.txt``. In  | 
 | 204 | +addition, the ``style`` environment will execute pre-commit, which guarantees  | 
 | 205 | +the usage of this tool in your project.  | 
 | 206 | + | 
 | 207 | +Installing ``tox``  | 
 | 208 | +~~~~~~~~~~~~~~~~~~  | 
 | 209 | +You can install this tool as any other Python one by running:  | 
 | 210 | + | 
 | 211 | +.. code-block:: bash  | 
 | 212 | +
  | 
 | 213 | +    python -m pip install tox  | 
 | 214 | +
  | 
 | 215 | +
  | 
 | 216 | +Using ``tox``  | 
 | 217 | +~~~~~~~~~~~~~  | 
 | 218 | + | 
 | 219 | +The core concept behind `tox`_ are ``environments``. These are similar to  | 
 | 220 | +``Makefile`` rules and highly customizable. Previous configuration ships with  | 
 | 221 | +different environments among which you can find:  | 
 | 222 | + | 
 | 223 | +- ``style``: for checking the code style of your project.  | 
 | 224 | +- ``py``: which will run your test suite.  | 
 | 225 | +- ``doc``: for building the documentation of your project.  | 
 | 226 | + | 
 | 227 | +Execute any of the previous environments by running ``tox -e <env-name>``. You  | 
 | 228 | +can run multiple environments by specifying those with commas ``tox -e  | 
 | 229 | +<env-name0>,<env-name1>,...```.  To run all available environments, simply  | 
 | 230 | +execute ``tox``.  | 
 | 231 | + | 
 | 232 | + | 
 | 233 | +.. LINKS AND REFERENCES  | 
 | 234 | +
  | 
 | 235 | +.. _black: https://black.readthedocs.io/en/latest/  | 
 | 236 | +.. _isort: https://pycqa.github.io/isort/  | 
 | 237 | +.. _flake8: https://flake8.pycqa.org/en/latest/  | 
 | 238 | +.. _pre-commit: https://pre-commit.com/  | 
 | 239 | +.. _tox: https://tox.wiki/en/latest/  | 
0 commit comments