Doctests -------- .. contents:: :local: :backlinks: none Basic Examples ~~~~~~~~~~~~~~ Including interactive examples in the documentation is helpful to users. They can be tested automatically and these tests are called *doctests*. We use `pytest to run doctests `__, which in turn uses the Python's `doctest `__. Some examples: .. code-block:: python def f(): """Description. Examples -------- >>> 13 * 2 26 """ pass and .. code-block:: rst .. rst file >>> print("Hello ddg") Hello ddg >>> 13 * 2 26 or .. code-block:: rst .. rst file .. doctest:: >>> print("Hello ddg") Hello ddg >>> 13 * 2 26 A multiline example: .. code-block:: rst .. doctest:: >>> import ddg.datastructures.indexedfaceset.ifs_generator as gen >>> cylinder = gen.cylinder( ... resolution=20, ... top_radius=1, ... bot_radius=1, ... length=1, ... center=(0, 0, 0), ... normal=(0, 0, 1), ... ) >>> cylinder For more details consult the `doctest documentation `_. .. note:: Avoid ``# doctest: +SKIP`` comments if at all possible. They used to be necessary in order to run the doctests outside of Blender without failures (as ``bpy`` isn't available). This is no longer the case --- nowadays Blender doctests are run within Blender. Every Python docstring that has examples counts as one doctest. This means that one ``*.py`` file can have multiple doctests. In contrast, every ``*.rst`` file counts as one doctest. Doctest Conventions ~~~~~~~~~~~~~~~~~~~ Use absolute paths when importing something in a doctest, **don't** use ``*`` imports. **Do** .. code-block:: rst .. doctest:: >>> from ddg.math.grids import triangle_grid >>> triangle_grid or .. code-block:: rst .. doctest:: >>> import ddg.math.grids >>> ddg.math.grids.triangle_grid **Do NOT** .. code-block:: rst .. doctest:: >>> from ddg.math.grids import * >>> triangle_grid In general, it is best to show both the input and output like so .. code-block:: rst .. doctest:: >>> import numpy as np >>> a = np.arange(10).reshape(2, 5) >>> a array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) >>> b = a * a >>> b array([[ 0, 1, 4, 9, 16], [25, 36, 49, 64, 81]]) This not only makes it easier to understand, but also asserts that the input ``a`` is what you expect it to be. If the input depends on the library and it changes in the future, then the doctest will fail which makes it easier to debug errors. Warnings ~~~~~~~~ Python's `doctest `__ will fail if even a single character doesn't match the expected output. Sometimes this is undesirable, because - output may not be deterministic, for example - ``repr`` and ``str`` may include memory addresses which change every time the program is executed, - ``repr`` and ``str`` may not guarantee any particular order for ``set`` and other unordered containers (note that ``dict`` is ordered as of `Python 3.7 `__), - output may be very long which decreases readability, - output may have tracebacks which show file paths that depend on where the program is stored. See doctest's documentation on `directives `__ and `warnings `__ on how to deal with these issues.