The minimal config:
import deal extensions = ['sphinx.ext.autodoc'] def setup(app): deal.autodoc(app)
And that’s all. Now, every time you include something using autodoc, deal will automatically inject documentation for contracts.
This is how deal converts every contract into text:
If the contract has
messageargument specified, it is used.
If the contract is a named function, the function name is used.
If the contract is a lambda, the source code is used.
See also sphinx example.
deal.example allows to provide a usage example for the decorated function. This example is executed only when running tests and partially checked by the linter. It’s not, however, executed at runtime. The example must return
True if it is valid.
@deal.example(lambda: double(3) == 6) def double(x): return x * 2
Depending on the context and on the mypy version you use, you may encounter
Cannot determine type of "double" error message from mypy (see mypy#11212). If you do, you can:
Upgrade mypy version above 0.910.
# type: ignore[has-type]to the reported line.
If you want to provide an example of when the function raises an exception, you can catch and compare this exception using
@deal.example(lambda: deal.catch(div, 4, 0) is ZeroDivisionError) @deal.raises(ZeroDivisionError) @deal.reason(ZeroDivisionError, lambda x: x == 0) def div(x, y): return x / y
For more complex examples (requiring setup, teardown, or complicated arguments) use doctest.
The Writing docstrings page of Sphinx documentation provides a good description on how to write docstrings in RST format. Also, there is PEP-257 which describes stylistic conventions related to docstrings (and tells what docstrings are).
If you prefer more human-friendly Markdown, it needs a bit of hacking. The MyST-Parser extension allows to use Markdown for Sphinx documentation but not for docstrings (see #228). If you want Markdown support for docstrings, you can add m2r2 converter into
docs/conf.py as a hook for autodoc:
from m2r2 import convert def autodoc_process(app, what, name, obj, options, lines): if not lines: return lines text = convert('\n'.join(lines)) lines[:] = text.split('\n') def setup(app): app.connect('autodoc-process-docstring', autodoc_process)
It doesn’t matter what format you choose, deal supports all of them.