I decided to extend the functionality of a Python program developed in one project while maintaining it in another new project. By taking over, I decided to keep the HTML document generated by Sphinx as an internal document. I have experience of converting to HTML with Doxygen in the past, and I embedded the same amount of information as comments in the source code, so I should support Sphinx. The background.
The detailed design document is automatically generated.
I'm new to Sphinx, so make a note of what you're doing. In addition, the original rule is adopted for the field of docstring.
As follows.
There are Google format and numpy format, but reStructureText (commonly known as reST) was adopted. The reason is as follows.
It's a procedure for Windows environment, but it seems that macOS and Linux are not so different.
pip install Sphinx sphinx-autodoc-typehints
pip install sphinx_rtd_theme
sphinx_rtd_theme
is used for HTML document themes.
The default is a little hard to see.
The following file structure is assumed.
.
├── src/ #The complete source code is below
│ ├── __init__.py
│ ├── Foo.py
│ ├── Bar.py
│ └── Hoge/
│ ├── __init__.py
│ └── Hoge.py
│
└── doc/ #This is the working directory of Sphinx
`doc /`
Execute the following command from the terminal.
sphinx-apidoc -F -a -o .\doc .\src
cd doc
make html
.\_build\html\index.html
make html
Generate an html document with. If you change the source code docstring, you only need to re-execute this command.
The command with the last index.html launches the default browser and opens the HTML document.
Sphinx seems to pass the target Python code to the processing system, and if there is an error in the target code, an error will occur with `` `make html``` and no document will be generated. Check the operation in advance.
Therefore, for example, if the target code uses a package that is unique to Windows, it cannot be documented in a macOS or Linux environment unless a dummy package is created by yourself.
It's not good to keep the default, so add the following line to the configuration file doc / conf.py
.
doc/conf.py
html_theme = 'sphinx_rtd_theme' #Specify display theme
autodoc_typehints = 'description' #Enable type hints
autoclass_content = 'both' # __init__()Also output
autodoc_default_options = {'private-members': True, #Output private method
'show-inheritance': True} #Show inheritance
What we are doing above is as follows.
_
, such as_method1 ()
or__method2 ()
After changing the settings, execute make html
.
I referred to this page for the settings. Import documentation from sphinx.ext.autodoc --docstring
By the way, I used it with language = en
. The layout didn't look right with ja
.
The reST notation of the adopted docstring is shown.
A description of the package is given here.
__init__.py
"""Package title
|Detailed information is written here.
|Be sure to open one line from the package title.
|← If you use a line block, the line feed state is maintained.
:author:Name of person in charge of this program
:copyright:Copyright notice
"""
Strings between colons, such as `: author: ``` and
`: copyright: ``` above, are called fields and can be defined independently. When HTML is output, it is displayed as follows.
The file header is the same as the package.
Foo.py
"""Module title
|Detailed information is written here.
|Be sure to open one line from the module title.
:note:If there are any notes, describe them here.
:author:Name of person in charge of this program
:copyright:Copyright notice
"""
The above shows an example of adding the : note:
field.
The : note:
field is used in all docstrings where necessary as a note.
The description of the class header is shown.
class Foo(object):
"""Class summary
|Detailed description of the class.
|Be sure to open one line from the class summary.
|← Line blocks can also be used.
"""
The description of the method header is shown.
class Foo(object):
def method(self, name: str, val: int) -> str:
'''Method summary
|Detailed description of the class.
|Be sure to open one line from the class summary.
|← Line blocks can also be used.
:param name:Name ← See type hints if type name is omitted
:param int val:Value ← You can write the type name directly
:returns:(Explanation of return value)
:rtype str:← Can be omitted if there is a return type and type hint
'''
...
To write a type hint, set `` `-> None``` for methods that have no return value.
2020/8/1: Supplement When I happened to look at the SudachiPy source code, I found that the type hints used only public methods. If maintenance is difficult, is there such a division?
The description of the members of the enumeration class is described as follows.
class State(enum.Enum):
"""State
"""
UNINIT = enum.auto() #:Uninitialized
READY = enum.auto() #:Wait
BUSY = enum.auto() #:processing
If the line of description becomes long, you can continue with `\`
or `\`
.
"""Module summary
Module description. ¥
This line is displayed from the top line without line breaks.
"""
When I introduced type hints for the purpose of documentation, I ended up getting stuck with type hints.
If you use your class as a type hint as it is, an error will occur.
class Foo(object):
def method(self, obj: Foo) -> None:
#↑ Foo becomes Undefined
pass
You can avoid the error by using a character string as shown below.
class Foo(object):
def method(self, obj: 'Foo') -> None:
# ↑ OK!
pass
It was also written properly on PEP-484.
If `list``` or
dict``` is specified as the argument or return type, the type of the element cannot be described. Therefore, it is described using ``
List and `` `Dict
of the typing package.
from typing import List
from typing import Dict
import Bar.Bar
class Foo(object):
def method(self, bars: List[Bar],
map: Dict[str, int]) -> List[str]:
...
The specifications of Foo.method () are as follows.
bars
is a list of objects of class Bar map
is a dictionary whose key is a string and whose value is an integer.Click here for details. PEP-484: Type Aliases
When importing between modules, an error occurs in circular import because it is in a mutual import state, and an error message such as ʻImportError: Cannot import name ...` is displayed. In such a case, the stance is basically "Please change the structure", but if the structure cannot be changed by all means, the following compromise was made.
(1) Give up the type hint and write the type name in the docstring (2) Make the type name a character string like Forward refences
Later, in the correspondence of (2), it was found that the check of F821 undefined name
was caught when passing through flake8, and in fact, all correspondence was done in (1).
Special Thanks
Recommended Posts