1""" 2 sphinx.ext.napoleon 3 ~~~~~~~~~~~~~~~~~~~ 4 5 Support for NumPy and Google style docstrings. 6 7 :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. 8 :license: BSD, see LICENSE for details. 9""" 10 11from typing import Any, Dict, List 12 13from sphinx import __display_version__ as __version__ 14from sphinx.application import Sphinx 15from sphinx.ext.napoleon.docstring import GoogleDocstring, NumpyDocstring 16from sphinx.util import inspect 17 18 19class Config: 20 """Sphinx napoleon extension settings in `conf.py`. 21 22 Listed below are all the settings used by napoleon and their default 23 values. These settings can be changed in the Sphinx `conf.py` file. Make 24 sure that "sphinx.ext.napoleon" is enabled in `conf.py`:: 25 26 # conf.py 27 28 # Add any Sphinx extension module names here, as strings 29 extensions = ['sphinx.ext.napoleon'] 30 31 # Napoleon settings 32 napoleon_google_docstring = True 33 napoleon_numpy_docstring = True 34 napoleon_include_init_with_doc = False 35 napoleon_include_private_with_doc = False 36 napoleon_include_special_with_doc = False 37 napoleon_use_admonition_for_examples = False 38 napoleon_use_admonition_for_notes = False 39 napoleon_use_admonition_for_references = False 40 napoleon_use_ivar = False 41 napoleon_use_param = True 42 napoleon_use_rtype = True 43 napoleon_use_keyword = True 44 napoleon_preprocess_types = False 45 napoleon_type_aliases = None 46 napoleon_custom_sections = None 47 napoleon_attr_annotations = True 48 49 .. _Google style: 50 https://google.github.io/styleguide/pyguide.html 51 .. _NumPy style: 52 https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt 53 54 Attributes 55 ---------- 56 napoleon_google_docstring : :obj:`bool` (Defaults to True) 57 True to parse `Google style`_ docstrings. False to disable support 58 for Google style docstrings. 59 napoleon_numpy_docstring : :obj:`bool` (Defaults to True) 60 True to parse `NumPy style`_ docstrings. False to disable support 61 for NumPy style docstrings. 62 napoleon_include_init_with_doc : :obj:`bool` (Defaults to False) 63 True to list ``__init___`` docstrings separately from the class 64 docstring. False to fall back to Sphinx's default behavior, which 65 considers the ``__init___`` docstring as part of the class 66 documentation. 67 68 **If True**:: 69 70 def __init__(self): 71 \"\"\" 72 This will be included in the docs because it has a docstring 73 \"\"\" 74 75 def __init__(self): 76 # This will NOT be included in the docs 77 78 napoleon_include_private_with_doc : :obj:`bool` (Defaults to False) 79 True to include private members (like ``_membername``) with docstrings 80 in the documentation. False to fall back to Sphinx's default behavior. 81 82 **If True**:: 83 84 def _included(self): 85 \"\"\" 86 This will be included in the docs because it has a docstring 87 \"\"\" 88 pass 89 90 def _skipped(self): 91 # This will NOT be included in the docs 92 pass 93 94 napoleon_include_special_with_doc : :obj:`bool` (Defaults to False) 95 True to include special members (like ``__membername__``) with 96 docstrings in the documentation. False to fall back to Sphinx's 97 default behavior. 98 99 **If True**:: 100 101 def __str__(self): 102 \"\"\" 103 This will be included in the docs because it has a docstring 104 \"\"\" 105 return unicode(self).encode('utf-8') 106 107 def __unicode__(self): 108 # This will NOT be included in the docs 109 return unicode(self.__class__.__name__) 110 111 napoleon_use_admonition_for_examples : :obj:`bool` (Defaults to False) 112 True to use the ``.. admonition::`` directive for the **Example** and 113 **Examples** sections. False to use the ``.. rubric::`` directive 114 instead. One may look better than the other depending on what HTML 115 theme is used. 116 117 This `NumPy style`_ snippet will be converted as follows:: 118 119 Example 120 ------- 121 This is just a quick example 122 123 **If True**:: 124 125 .. admonition:: Example 126 127 This is just a quick example 128 129 **If False**:: 130 131 .. rubric:: Example 132 133 This is just a quick example 134 135 napoleon_use_admonition_for_notes : :obj:`bool` (Defaults to False) 136 True to use the ``.. admonition::`` directive for **Notes** sections. 137 False to use the ``.. rubric::`` directive instead. 138 139 Note 140 ---- 141 The singular **Note** section will always be converted to a 142 ``.. note::`` directive. 143 144 See Also 145 -------- 146 :attr:`napoleon_use_admonition_for_examples` 147 148 napoleon_use_admonition_for_references : :obj:`bool` (Defaults to False) 149 True to use the ``.. admonition::`` directive for **References** 150 sections. False to use the ``.. rubric::`` directive instead. 151 152 See Also 153 -------- 154 :attr:`napoleon_use_admonition_for_examples` 155 156 napoleon_use_ivar : :obj:`bool` (Defaults to False) 157 True to use the ``:ivar:`` role for instance variables. False to use 158 the ``.. attribute::`` directive instead. 159 160 This `NumPy style`_ snippet will be converted as follows:: 161 162 Attributes 163 ---------- 164 attr1 : int 165 Description of `attr1` 166 167 **If True**:: 168 169 :ivar attr1: Description of `attr1` 170 :vartype attr1: int 171 172 **If False**:: 173 174 .. attribute:: attr1 175 176 Description of `attr1` 177 178 :type: int 179 180 napoleon_use_param : :obj:`bool` (Defaults to True) 181 True to use a ``:param:`` role for each function parameter. False to 182 use a single ``:parameters:`` role for all the parameters. 183 184 This `NumPy style`_ snippet will be converted as follows:: 185 186 Parameters 187 ---------- 188 arg1 : str 189 Description of `arg1` 190 arg2 : int, optional 191 Description of `arg2`, defaults to 0 192 193 **If True**:: 194 195 :param arg1: Description of `arg1` 196 :type arg1: str 197 :param arg2: Description of `arg2`, defaults to 0 198 :type arg2: int, optional 199 200 **If False**:: 201 202 :parameters: * **arg1** (*str*) -- 203 Description of `arg1` 204 * **arg2** (*int, optional*) -- 205 Description of `arg2`, defaults to 0 206 207 napoleon_use_keyword : :obj:`bool` (Defaults to True) 208 True to use a ``:keyword:`` role for each function keyword argument. 209 False to use a single ``:keyword arguments:`` role for all the 210 keywords. 211 212 This behaves similarly to :attr:`napoleon_use_param`. Note unlike 213 docutils, ``:keyword:`` and ``:param:`` will not be treated the same 214 way - there will be a separate "Keyword Arguments" section, rendered 215 in the same fashion as "Parameters" section (type links created if 216 possible) 217 218 See Also 219 -------- 220 :attr:`napoleon_use_param` 221 222 napoleon_use_rtype : :obj:`bool` (Defaults to True) 223 True to use the ``:rtype:`` role for the return type. False to output 224 the return type inline with the description. 225 226 This `NumPy style`_ snippet will be converted as follows:: 227 228 Returns 229 ------- 230 bool 231 True if successful, False otherwise 232 233 **If True**:: 234 235 :returns: True if successful, False otherwise 236 :rtype: bool 237 238 **If False**:: 239 240 :returns: *bool* -- True if successful, False otherwise 241 242 napoleon_preprocess_types : :obj:`bool` (Defaults to False) 243 Enable the type preprocessor for numpy style docstrings. 244 245 napoleon_type_aliases : :obj:`dict` (Defaults to None) 246 Add a mapping of strings to string, translating types in numpy 247 style docstrings. Only works if ``napoleon_preprocess_types = True``. 248 249 napoleon_custom_sections : :obj:`list` (Defaults to None) 250 Add a list of custom sections to include, expanding the list of parsed sections. 251 252 The entries can either be strings or tuples, depending on the intention: 253 * To create a custom "generic" section, just pass a string. 254 * To create an alias for an existing section, pass a tuple containing the 255 alias name and the original, in that order. 256 * To create a custom section that displays like the parameters or returns 257 section, pass a tuple containing the custom section name and a string 258 value, "params_style" or "returns_style". 259 260 If an entry is just a string, it is interpreted as a header for a generic 261 section. If the entry is a tuple/list/indexed container, the first entry 262 is the name of the section, the second is the section key to emulate. If the 263 second entry value is "params_style" or "returns_style", the custom section 264 will be displayed like the parameters section or returns section. 265 266 napoleon_attr_annotations : :obj:`bool` (Defaults to True) 267 Use the type annotations of class attributes that are documented in the docstring 268 but do not have a type in the docstring. 269 270 """ 271 _config_values = { 272 'napoleon_google_docstring': (True, 'env'), 273 'napoleon_numpy_docstring': (True, 'env'), 274 'napoleon_include_init_with_doc': (False, 'env'), 275 'napoleon_include_private_with_doc': (False, 'env'), 276 'napoleon_include_special_with_doc': (False, 'env'), 277 'napoleon_use_admonition_for_examples': (False, 'env'), 278 'napoleon_use_admonition_for_notes': (False, 'env'), 279 'napoleon_use_admonition_for_references': (False, 'env'), 280 'napoleon_use_ivar': (False, 'env'), 281 'napoleon_use_param': (True, 'env'), 282 'napoleon_use_rtype': (True, 'env'), 283 'napoleon_use_keyword': (True, 'env'), 284 'napoleon_preprocess_types': (False, 'env'), 285 'napoleon_type_aliases': (None, 'env'), 286 'napoleon_custom_sections': (None, 'env'), 287 'napoleon_attr_annotations': (True, 'env'), 288 } 289 290 def __init__(self, **settings: Any) -> None: 291 for name, (default, rebuild) in self._config_values.items(): 292 setattr(self, name, default) 293 for name, value in settings.items(): 294 setattr(self, name, value) 295 296 297def setup(app: Sphinx) -> Dict[str, Any]: 298 """Sphinx extension setup function. 299 300 When the extension is loaded, Sphinx imports this module and executes 301 the ``setup()`` function, which in turn notifies Sphinx of everything 302 the extension offers. 303 304 Parameters 305 ---------- 306 app : sphinx.application.Sphinx 307 Application object representing the Sphinx process 308 309 See Also 310 -------- 311 `The Sphinx documentation on Extensions 312 <http://sphinx-doc.org/extensions.html>`_ 313 314 `The Extension Tutorial <http://sphinx-doc.org/extdev/tutorial.html>`_ 315 316 `The Extension API <http://sphinx-doc.org/extdev/appapi.html>`_ 317 318 """ 319 if not isinstance(app, Sphinx): 320 # probably called by tests 321 return {'version': __version__, 'parallel_read_safe': True} 322 323 _patch_python_domain() 324 325 app.setup_extension('sphinx.ext.autodoc') 326 app.connect('autodoc-process-docstring', _process_docstring) 327 app.connect('autodoc-skip-member', _skip_member) 328 329 for name, (default, rebuild) in Config._config_values.items(): 330 app.add_config_value(name, default, rebuild) 331 return {'version': __version__, 'parallel_read_safe': True} 332 333 334def _patch_python_domain() -> None: 335 try: 336 from sphinx.domains.python import PyTypedField 337 except ImportError: 338 pass 339 else: 340 import sphinx.domains.python 341 from sphinx.locale import _ 342 for doc_field in sphinx.domains.python.PyObject.doc_field_types: 343 if doc_field.name == 'parameter': 344 doc_field.names = ('param', 'parameter', 'arg', 'argument') 345 break 346 sphinx.domains.python.PyObject.doc_field_types.append( 347 PyTypedField('keyword', label=_('Keyword Arguments'), 348 names=('keyword', 'kwarg', 'kwparam'), 349 typerolename='obj', typenames=('paramtype', 'kwtype'), 350 can_collapse=True)) 351 352 353def _process_docstring(app: Sphinx, what: str, name: str, obj: Any, 354 options: Any, lines: List[str]) -> None: 355 """Process the docstring for a given python object. 356 357 Called when autodoc has read and processed a docstring. `lines` is a list 358 of docstring lines that `_process_docstring` modifies in place to change 359 what Sphinx outputs. 360 361 The following settings in conf.py control what styles of docstrings will 362 be parsed: 363 364 * ``napoleon_google_docstring`` -- parse Google style docstrings 365 * ``napoleon_numpy_docstring`` -- parse NumPy style docstrings 366 367 Parameters 368 ---------- 369 app : sphinx.application.Sphinx 370 Application object representing the Sphinx process. 371 what : str 372 A string specifying the type of the object to which the docstring 373 belongs. Valid values: "module", "class", "exception", "function", 374 "method", "attribute". 375 name : str 376 The fully qualified name of the object. 377 obj : module, class, exception, function, method, or attribute 378 The object to which the docstring belongs. 379 options : sphinx.ext.autodoc.Options 380 The options given to the directive: an object with attributes 381 inherited_members, undoc_members, show_inheritance and noindex that 382 are True if the flag option of same name was given to the auto 383 directive. 384 lines : list of str 385 The lines of the docstring, see above. 386 387 .. note:: `lines` is modified *in place* 388 389 """ 390 result_lines = lines 391 docstring = None # type: GoogleDocstring 392 if app.config.napoleon_numpy_docstring: 393 docstring = NumpyDocstring(result_lines, app.config, app, what, name, 394 obj, options) 395 result_lines = docstring.lines() 396 if app.config.napoleon_google_docstring: 397 docstring = GoogleDocstring(result_lines, app.config, app, what, name, 398 obj, options) 399 result_lines = docstring.lines() 400 lines[:] = result_lines[:] 401 402 403def _skip_member(app: Sphinx, what: str, name: str, obj: Any, 404 skip: bool, options: Any) -> bool: 405 """Determine if private and special class members are included in docs. 406 407 The following settings in conf.py determine if private and special class 408 members or init methods are included in the generated documentation: 409 410 * ``napoleon_include_init_with_doc`` -- 411 include init methods if they have docstrings 412 * ``napoleon_include_private_with_doc`` -- 413 include private members if they have docstrings 414 * ``napoleon_include_special_with_doc`` -- 415 include special members if they have docstrings 416 417 Parameters 418 ---------- 419 app : sphinx.application.Sphinx 420 Application object representing the Sphinx process 421 what : str 422 A string specifying the type of the object to which the member 423 belongs. Valid values: "module", "class", "exception", "function", 424 "method", "attribute". 425 name : str 426 The name of the member. 427 obj : module, class, exception, function, method, or attribute. 428 For example, if the member is the __init__ method of class A, then 429 `obj` will be `A.__init__`. 430 skip : bool 431 A boolean indicating if autodoc will skip this member if `_skip_member` 432 does not override the decision 433 options : sphinx.ext.autodoc.Options 434 The options given to the directive: an object with attributes 435 inherited_members, undoc_members, show_inheritance and noindex that 436 are True if the flag option of same name was given to the auto 437 directive. 438 439 Returns 440 ------- 441 bool 442 True if the member should be skipped during creation of the docs, 443 False if it should be included in the docs. 444 445 """ 446 has_doc = getattr(obj, '__doc__', False) 447 is_member = (what == 'class' or what == 'exception' or what == 'module') 448 if name != '__weakref__' and has_doc and is_member: 449 cls_is_owner = False 450 if what == 'class' or what == 'exception': 451 qualname = getattr(obj, '__qualname__', '') 452 cls_path, _, _ = qualname.rpartition('.') 453 if cls_path: 454 try: 455 if '.' in cls_path: 456 import functools 457 import importlib 458 459 mod = importlib.import_module(obj.__module__) 460 mod_path = cls_path.split('.') 461 cls = functools.reduce(getattr, mod_path, mod) 462 else: 463 cls = inspect.unwrap(obj).__globals__[cls_path] 464 except Exception: 465 cls_is_owner = False 466 else: 467 cls_is_owner = (cls and hasattr(cls, name) and # type: ignore 468 name in cls.__dict__) 469 else: 470 cls_is_owner = False 471 472 if what == 'module' or cls_is_owner: 473 is_init = (name == '__init__') 474 is_special = (not is_init and name.startswith('__') and 475 name.endswith('__')) 476 is_private = (not is_init and not is_special and 477 name.startswith('_')) 478 inc_init = app.config.napoleon_include_init_with_doc 479 inc_special = app.config.napoleon_include_special_with_doc 480 inc_private = app.config.napoleon_include_private_with_doc 481 if ((is_special and inc_special) or 482 (is_private and inc_private) or 483 (is_init and inc_init)): 484 return False 485 return None 486