summaryrefslogtreecommitdiffstats
path: root/doc/development/tutorials/autodoc_ext.rst
blob: cfd23e7e694f55114061634eb0faed12e06af291 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
.. _autodoc_ext_tutorial:

Developing autodoc extension for IntEnum
========================================

The objective of this tutorial is to create an extension that adds
support for new type for autodoc. This autodoc extension will format
the ``IntEnum`` class from Python standard library. (module ``enum``)

Overview
--------

We want the extension that will create auto-documentation for IntEnum.
``IntEnum`` is the integer enum class from standard library ``enum`` module.

Currently this class has no special auto documentation behavior.

We want to add following to autodoc:

* A new ``autointenum`` directive that will document the ``IntEnum`` class.
* The generated documentation will have all the enum possible values
  with names.
* The ``autointenum`` directive will have an option ``:hex:`` which will
  cause the integers be printed in hexadecimal form.


Prerequisites
-------------

We need the same setup as in :doc:`the previous extensions <todo>`. This time,
we will be putting out extension in a file called :file:`autodoc_intenum.py`.
The :file:`my_enums.py` will contain the sample enums we will document.

Here is an example of the folder structure you might obtain:

.. code-block:: text

      └── source
          ├── _ext
          │   └── autodoc_intenum.py
          ├── conf.py
          ├── index.rst
          └── my_enums.py


Writing the extension
---------------------

Start with ``setup`` function for the extension.

.. literalinclude:: examples/autodoc_intenum.py
   :language: python
   :linenos:
   :pyobject: setup


The :meth:`~sphinx.application.Sphinx.setup_extension` method will pull the
autodoc extension because our new extension depends on autodoc.
:meth:`~sphinx.application.Sphinx.add_autodocumenter` is the method that
registers our new auto documenter class.

We want to import certain objects from the autodoc extension:

.. literalinclude:: examples/autodoc_intenum.py
   :language: python
   :linenos:
   :lines: 1-7


There are several different documenter classes such as ``MethodDocumenter``
or ``AttributeDocumenter`` available in the autodoc extension but
our new class is the subclass of ``ClassDocumenter`` which a
documenter class used by autodoc to document classes.

This is the definition of our new the auto-documenter class:

.. literalinclude:: examples/autodoc_intenum.py
   :language: python
   :linenos:
   :pyobject: IntEnumDocumenter


Important attributes of the new class:

**objtype**
    This attribute determines the ``auto`` directive name. In
    this case the auto directive will be ``autointenum``.

**directivetype**
    This attribute sets the generated directive name. In
    this example the generated directive will be ``.. :py:class::``.

**priority**
    the larger the number the higher is the priority. We want our
    documenter be higher priority than the parent.

**option_spec**
    option specifications. We copy the parent class options and
    add a new option *hex*.


Overridden members:

**can_document_member**
    This member is important to override. It should
    return *True* when the passed object can be documented by this class.

**add_directive_header**
    This method generates the directive header. We add
    **:final:** directive option. Remember to call **super** or no directive
    will be generated.

**add_content**
    This method generates the body of the class documentation.
    After calling the super method we generate lines for enum description.


Using the extension
-------------------

You can now use the new autodoc directive to document any ``IntEnum``.

For example, you have the following ``IntEnum``:

.. code-block:: python
   :caption: my_enums.py

   class Colors(IntEnum):
       """Colors enumerator"""
       NONE = 0
       RED = 1
       GREEN = 2
       BLUE = 3


This will be the documentation file with auto-documentation directive:

.. code-block:: rst
   :caption: index.rst

   .. autointenum:: my_enums.Colors