Coding Guidelines

To keep consistency, we ask you to comply with the following guidelines for contributions. However, these are just guidelines - it still helps if you contribute something, even if doesn’t follow these rules ;-)

  • Use a code style based on PEP 8. The git repo includes a config file .style.yapf for the python package yapf. yapf is a tool to auto-format code, e.g., by the command yapf -i some/file (-i for “in place”). We run yapf on a regular basis on the github main branch. If your branch diverged, it might help to run yapf before merging.


    Since no tool is perfect, you can format some regions of code manually and enclose them with the special comments # yapf: disable and # yapf: enable.

  • Every function/class/module should be documented by its doc-string, see PEP 257. We auto-format the doc-strings with docformatter on a regular basis.

    Additional documentation for the user guide is in the folder doc/.

    The documentation uses reStructuredText. If you are new to reStructuredText, read this introduction. We use the numpy style for doc-strings (with the napoleon extension to sphinx). You can read about them in these Instructions for the doc strings. In addition, you can take a look at the following example file. Helpful hints on top of that:

    r"""<- this r makes me a raw string, thus '\' has no special meaning.
    Otherwise you would need to escape backslashes, e.g. in math formulas.
    You can include cross references to classes, methods, functions, modules like
    :class:`~tenpy.linalg.np_conserved.Array`, :meth:`~tenpy.linalg.np_conserved.Array.to_ndarray`,
    :func:``, :mod:`tenpy.linalg.np_conserved`.
    The ~ in the beginning makes only the last part of the name appear in the generated documentation.
    Documents of the userguide can be referenced with :doc:`/intro_npc` even from inside the doc-strings.
    You can also cross-link to other documentations, e.g. :class:`numpy.ndarray`, :func`scipy.linalg.svd` and :mod: will work.
    Moreover, you can link to github issues, arXiv papers, dois, and topics in the community forum with
    e.g. :issue:`5`, :arxiv:`1805.00055`, :doi:`10.1000/1` and :forum:`3`.
    Citations from the literature list can be cited as :cite:`white1992` using the bibtex key.
    Write inline formulas as :math:`H |\Psi\rangle = E |\Psi\rangle` or displayed equations as
    .. math ::
       e^{i\pi} + 1 = 0
    In doc-strings, math can only be used in the Notes section.
    To refer to variables within math, use `\mathtt{varname}`.
    .. todo ::
       This block can describe things which need to be done and is automatically included in a section of :doc:`todo`.
  • Use relative imports within TeNPy. Example:

    from ..linalg import np_conserved as npc
  • Use the python package pytest for testing. Run it simply with pytest in tests/. You should make sure that all tests run through, before you git push back into the public repo. Long-running tests are marked with the attribute slow; for a quick check you can also run pytest -m "not slow".

    We have set up github actions to automatically run the tests.

  • Reversely, if you write new functions, please also include suitable tests!

  • Preserve backwards compatibility as far as possible. If you change how a feature works, or how it is accessed or what its function signature is, keep the deprecated version around with suitable deprecation warnings. Issue a DeprecationWarning or FutureWarning when the deprecated implementation is used. A common pattern for deprecated classes is to subclass from the new implementation and override methods as needed. Use the .. deprecated :: directive in the docstring and describe what should be used instead. Include a version number roughly 2-3 versions in the future, at which the deprecated version will be removed. Make sure you update the changelog, clearly stating which new feature replaces which old one in what circumstance. For deprecated config options use deprecated_alias().

  • During development, you might introduce # TODO comments. But also try to remove them again later! If you’re not 100% sure that you will remove it soon, please add a doc-string with a .. todo :: block, such that we can keep track of it.

    Unfinished functions should raise NotImplementedError().

  • Summarize the changes you have made in the changelog. For PRs and larger changes, make a new file, and e.g. name it after the PR, doc/changelog/latest/pr_401.txt or similar. Make sure to use .txt suffix. It should contain only bullet points (- `` followed by text, additional lines starting with two spaces). For very small changes, you may add to (or create, if it doesn't exist yet) ``doc/changelog/latest/misc.txt.

  • If you want to try out new things in temporary files: any folder named playground is ignored by git.

  • If you add a new toycode or example: add a reference to include it in the documentation.

  • We’ve created a sphinx extensions for documenting config-option dictionaries. If a class takes a dictionary of options, we usually call it options, convert it to a Config at the very beginning of the __init__ with asConfig(), save it as self.options, and document it in the class doc-string with a .. cfg:config :: directive. The name of the config should usually be the class-name (if that is sufficiently unique), or for algorithms directly the common name of the algorithm, e.g. “DMRG”; use the same name for the use the same name for the documentation of the .. cfg:config :: directive as for the Config class instance. Attributes which are simply read-out options should be documented by just referencing the options with the :cfg:option:`configname.optionname` role.