mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #8972 from igo95862/master
Tutorial for extending autodoc
This commit is contained in:
commit
3693ffe232
142
doc/development/tutorials/autodoc_ext.rst
Normal file
142
doc/development/tutorials/autodoc_ext.rst
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
.. _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.setup_extension` method will pull the autodoc extension
|
||||||
|
because our new extension depends on autodoc. :meth:`~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
|
||||||
|
|
||||||
|
|
52
doc/development/tutorials/examples/autodoc_intenum.py
Normal file
52
doc/development/tutorials/examples/autodoc_intenum.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
from enum import IntEnum
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
|
from docutils.statemachine import StringList
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
|
from sphinx.ext.autodoc import ClassDocumenter, bool_option
|
||||||
|
|
||||||
|
|
||||||
|
class IntEnumDocumenter(ClassDocumenter):
|
||||||
|
objtype = 'intenum'
|
||||||
|
directivetype = 'class'
|
||||||
|
priority = 10 + ClassDocumenter.priority
|
||||||
|
option_spec = dict(ClassDocumenter.option_spec)
|
||||||
|
option_spec['hex'] = bool_option
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_document_member(cls,
|
||||||
|
member: Any, membername: str,
|
||||||
|
isattr: bool, parent: Any) -> bool:
|
||||||
|
return isinstance(member, IntEnum)
|
||||||
|
|
||||||
|
def add_directive_header(self, sig: str) -> None:
|
||||||
|
super().add_directive_header(sig)
|
||||||
|
self.add_line(' :final:', self.get_sourcename())
|
||||||
|
|
||||||
|
def add_content(self,
|
||||||
|
more_content: Optional[StringList],
|
||||||
|
no_docstring: bool = False
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
super().add_content(more_content, no_docstring)
|
||||||
|
|
||||||
|
source_name = self.get_sourcename()
|
||||||
|
enum_object: IntEnum = self.object
|
||||||
|
use_hex = self.options.hex
|
||||||
|
self.add_line('', source_name)
|
||||||
|
|
||||||
|
for enum_value in enum_object:
|
||||||
|
the_value_name = enum_value.name
|
||||||
|
the_value_value = enum_value.value
|
||||||
|
if use_hex:
|
||||||
|
the_value_value = hex(the_value_value)
|
||||||
|
|
||||||
|
self.add_line(
|
||||||
|
f"**{the_value_name}**: {the_value_value}", source_name)
|
||||||
|
self.add_line('', source_name)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app: Sphinx) -> None:
|
||||||
|
app.setup_extension('sphinx.ext.autodoc') # Require autodoc extension
|
||||||
|
app.add_autodocumenter(IntEnumDocumenter)
|
@ -13,3 +13,5 @@ Refer to the following tutorials to get started with extension development.
|
|||||||
helloworld
|
helloworld
|
||||||
todo
|
todo
|
||||||
recipe
|
recipe
|
||||||
|
autodoc_ext
|
||||||
|
|
||||||
|
@ -1102,7 +1102,7 @@ class Sphinx:
|
|||||||
If *override* is True, the given *cls* is forcedly installed even if
|
If *override* is True, the given *cls* is forcedly installed even if
|
||||||
a documenter having the same name is already installed.
|
a documenter having the same name is already installed.
|
||||||
|
|
||||||
.. todo:: Add real docs for Documenter and subclassing
|
See :ref:`autodoc_ext_tutorial`.
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
.. versionadded:: 0.6
|
||||||
.. versionchanged:: 2.2
|
.. versionchanged:: 2.2
|
||||||
|
Loading…
Reference in New Issue
Block a user