.. _coding_conventions: Coding Conventions ================== .. contents:: :local: :backlinks: none Absolute vs. Relative Imports ----------------------------- We generally use **absolute imports**, as `PEP 8 `_ recommends. Layout and Documentation ------------------------ Module Description ~~~~~~~~~~~~~~~~~~ First line: short description of module. Optional further lines: extra info. .. code-block:: python """Utility functions for complex analysis in planar geometry. Uses and generates numpy complex numbers. """ Headlines for Structure ~~~~~~~~~~~~~~~~~~~~~~~ If the methods within a module can be categorized, you can sort them accordingly and use headlines to structure the module visually. Use this style: .. code-block:: python #################### # sampling functions #################### def sample_fct1(arg): ... def sample_fct2(arg): ... Commenting ---------- You are welcome to **comment your code** where necessary. Details on the implementation can also be explained in the **docstring** inside the "Notes"-section, as explained on the page :ref:`docstring_conventions`. Naming ------ Singular vs plural for vectorized functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Always use **singular** when naming a **vectorized function** (i.e. it can handle a single object or an array of objects as input): **Do this** .. code-block:: python def add_point(coord_list): ... **Do NOT do that** .. code-block:: python def add_points(coord_list): ... Non-ASCII characters ~~~~~~~~~~~~~~~~~~~~ We only want to use ASCII characters for names of functions, classes, modules etc. to make things easy to type on any keyboard. This means we need to convert characters like "ö" to ascii characters. We decide how to do this on a case-by-case basis. We already decided on: - ``Möbius -> Mobius`` (instead of ``Moebius``). Inside Code ----------- If-Else Statements ~~~~~~~~~~~~~~~~~~ Using ``else`` for return statements or leaving it out generally depends on the context. .. code-block:: python if something: return this else: return that or leaving out the ``else`` .. code-block:: python if something: return this return that Using `guard clauses `_ is considered good practice. If leaving out the ``else`` helps to improve readability and reduces indentations it's generally best to leave it out. Formatted Strings ~~~~~~~~~~~~~~~~~ Use `f-strings `_ .. code-block:: python f"Text hello blabla {expression} blabla {expression}." Style and Formatting ~~~~~~~~~~~~~~~~~~~~ We use `black `_ to format all Python source files. Install black with .. code-block:: bash poetry install --with style The CI will fail if your changes don't conform to black. To check this, switch to the project root directory and run .. code-block:: bash python3 test.py --style Format every Python source file with .. code-block:: bash black . and specific files with .. code-block:: bash black path-to-file You can check which files will be formatted by black with .. code-block:: bash black --check . and view the changes with .. code-block:: bash black --diff --color . The big commit that reformats the whole library is ``2e09d86c7d2c3e7d2f9387ff2c950f8debc3b1a9``. If you don't want it to clutter up ``git blame``, run .. code-block:: bash git blame path-to-file --ignore-revs-file .git-blame-ignore-revs More information `here `_. Blender ------- Blender context and modes ~~~~~~~~~~~~~~~~~~~~~~~~~ If you rely on `bpy.context` having certain states, consider using `bpy.types.Context.temp_override `__. If you need to set modes for Blender objects, consider using :py:func:`~ddg.blender.context.mode`. If you need to work with BMeshes, consider using :py:func:`~ddg.blender.bmesh.bmesh_from_mesh`.