sphinx-autoapi 3.3.0__tar.gz → 3.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/CHANGELOG.rst +27 -0
  2. {sphinx_autoapi-3.3.0/sphinx_autoapi.egg-info → sphinx_autoapi-3.3.2}/PKG-INFO +1 -1
  3. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/__init__.py +2 -2
  4. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/_astroid_utils.py +0 -30
  5. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/_mapper.py +28 -0
  6. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/_parser.py +68 -45
  7. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/documenters.py +23 -12
  8. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2/sphinx_autoapi.egg-info}/PKG-INFO +1 -1
  9. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/sphinx_autoapi.egg-info/SOURCES.txt +5 -0
  10. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/conftest.py +0 -2
  11. {sphinx_autoapi-3.3.0/tests/python/pymovedconfpy → sphinx_autoapi-3.3.2/tests/python/pyexample}/example/example.py +24 -0
  12. {sphinx_autoapi-3.3.0/tests/python/pyexample → sphinx_autoapi-3.3.2/tests/python/pymovedconfpy}/example/example.py +24 -0
  13. sphinx_autoapi-3.3.2/tests/python/pystdlib/conf.py +24 -0
  14. sphinx_autoapi-3.3.2/tests/python/pystdlib/index.rst +25 -0
  15. sphinx_autoapi-3.3.2/tests/python/pystdlib/stdlib/json.py +9 -0
  16. sphinx_autoapi-3.3.2/tests/python/pystdlib/stdlib/myast.py +10 -0
  17. sphinx_autoapi-3.3.2/tests/python/pystdlib/stdlib/myjson.py +10 -0
  18. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/test_pyintegration.py +116 -1
  19. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/LICENSE.rst +0 -0
  20. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/MANIFEST.in +0 -0
  21. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/README.rst +0 -0
  22. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/_objects.py +0 -0
  23. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/directives.py +0 -0
  24. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/extension.py +0 -0
  25. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/inheritance_diagrams.py +0 -0
  26. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/settings.py +0 -0
  27. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/index.rst +0 -0
  28. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/attribute.rst +0 -0
  29. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/class.rst +0 -0
  30. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/data.rst +0 -0
  31. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/exception.rst +0 -0
  32. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/function.rst +0 -0
  33. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/method.rst +0 -0
  34. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/module.rst +0 -0
  35. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/package.rst +0 -0
  36. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/autoapi/templates/python/property.rst +0 -0
  37. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/pyproject.toml +0 -0
  38. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/setup.cfg +0 -0
  39. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/setup.py +0 -0
  40. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/sphinx_autoapi.egg-info/dependency_links.txt +0 -0
  41. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/sphinx_autoapi.egg-info/requires.txt +0 -0
  42. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/sphinx_autoapi.egg-info/top_level.txt +0 -0
  43. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pep695/conf.py +0 -0
  44. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pep695/example/example.py +0 -0
  45. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pep695/index.rst +0 -0
  46. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py310unionpipe/conf.py +0 -0
  47. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py310unionpipe/example/example.py +0 -0
  48. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py310unionpipe/index.rst +0 -0
  49. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py38positionalparams/conf.py +0 -0
  50. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py38positionalparams/example/example.py +0 -0
  51. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py38positionalparams/index.rst +0 -0
  52. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3example/conf.py +0 -0
  53. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3example/example/example.py +0 -0
  54. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3example/example/example2.py +0 -0
  55. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3example/index.rst +0 -0
  56. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3implicitnamespace/conf.py +0 -0
  57. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3implicitnamespace/index.rst +0 -0
  58. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3implicitnamespace/namespace/example/__init__.py +0 -0
  59. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3implicitnamespace/namespace/sibling/__init__.py +0 -0
  60. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/py3implicitnamespace/namespace/sibling/sub_sibling.py +0 -0
  61. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyannotationcommentsexample/conf.py +0 -0
  62. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyannotationcommentsexample/example/example.py +0 -0
  63. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyannotationcommentsexample/index.rst +0 -0
  64. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyautodoc_typehints/conf.py +0 -0
  65. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyautodoc_typehints/example/example.py +0 -0
  66. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyautodoc_typehints/example/example2.py +0 -0
  67. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyautodoc_typehints/index.rst +0 -0
  68. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyemptyexample/conf.py +0 -0
  69. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyemptyexample/index.rst +0 -0
  70. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyexample/conf.py +0 -0
  71. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyexample/index.rst +0 -0
  72. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyexample/manualapi.rst +0 -0
  73. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyexample/null.rst +0 -0
  74. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample/conf.py +0 -0
  75. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample/example/example.py +0 -0
  76. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample/example/example.pyi +0 -0
  77. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample/index.rst +0 -0
  78. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample2/conf.py +0 -0
  79. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample2/example/example.py +0 -0
  80. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample2/example/example.pyi +0 -0
  81. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyiexample2/index.rst +0 -0
  82. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyisubmoduleinit/conf.py +0 -0
  83. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyisubmoduleinit/example/example.py +0 -0
  84. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyisubmoduleinit/example/submodule_foo/__init__.pyi +0 -0
  85. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyisubmoduleinit/index.rst +0 -0
  86. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pymovedconfpy/confpy/conf.py +0 -0
  87. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pymovedconfpy/index.rst +0 -0
  88. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pymovedconfpy/manualapi.rst +0 -0
  89. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pynorender/conf.py +0 -0
  90. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pynorender/example/_example.py +0 -0
  91. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pynorender/index.rst +0 -0
  92. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/__init__.py +0 -0
  93. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/_private_module.py +0 -0
  94. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/binary_data.py +0 -0
  95. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/foo.py +0 -0
  96. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/submodule.py +0 -0
  97. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/subpackage/__init__.py +0 -0
  98. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/subpackage/submodule.py +0 -0
  99. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/unicode_data.py +0 -0
  100. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/wildall/__init__.py +0 -0
  101. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/wildall/simple/__init__.py +0 -0
  102. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/wildcard/__init__.py +0 -0
  103. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/wildchain/__init__.py +0 -0
  104. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/complex/wildwildchain/__init__.py +0 -0
  105. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/conf.py +0 -0
  106. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackagecomplex/index.rst +0 -0
  107. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/conf.py +0 -0
  108. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/index.rst +0 -0
  109. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/__init__.py +0 -0
  110. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/_private_submodule.py +0 -0
  111. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/_private_subpackage/__init__.py +0 -0
  112. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/_private_subpackage/submodule.py +0 -0
  113. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/_private_subpackage/subpackage/__init__.py +0 -0
  114. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/_private_subpackage/subpackage/submodule.py +0 -0
  115. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/submodule.py +0 -0
  116. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/subpackage/__init__.py +0 -0
  117. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pypackageexample/package/subpackage/submodule.py +0 -0
  118. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyskipexample/conf.py +0 -0
  119. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyskipexample/example/example.py +0 -0
  120. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/pyskipexample/index.rst +0 -0
  121. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/test_own_page_option.py +0 -0
  122. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/python/test_parser.py +0 -0
  123. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/templateexample/conf.py +0 -0
  124. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/templateexample/example/example.py +0 -0
  125. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/templateexample/index.rst +0 -0
  126. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/templateexample/template_overrides/python/function.rst +0 -0
  127. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/test_astroid_utils.py +0 -0
  128. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/test_integration.py +0 -0
  129. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/toctreeexample/conf.py +0 -0
  130. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/toctreeexample/example/example.py +0 -0
  131. {sphinx_autoapi-3.3.0 → sphinx_autoapi-3.3.2}/tests/toctreeexample/index.rst +0 -0
@@ -5,6 +5,33 @@ Versions follow `Semantic Versioning <https://semver.org/>`_ (``<major>.<minor>.
5
5
 
6
6
  .. towncrier release notes start
7
7
 
8
+ v3.3.2 (2024-09-25)
9
+ -------------------
10
+
11
+ Bugfixes
12
+ ^^^^^^^^
13
+
14
+ - Fix types missing from documentation generated by autodoc-style directives. (#473)
15
+
16
+
17
+ v3.3.1 (2024-09-01)
18
+ -------------------
19
+
20
+ Bugfixes
21
+ ^^^^^^^^
22
+
23
+ - Fix all class members missing when documenting a module with the same name as a standard library module
24
+
25
+ Members inherited from the standard library can also have their skip value
26
+ overridden by autoapi-skip-member. (#478)
27
+
28
+
29
+ Misc
30
+ ^^^^
31
+
32
+ - Updated all github actions.
33
+
34
+
8
35
  v3.3.0 (2024-08-28)
9
36
  -------------------
10
37
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sphinx-autoapi
3
- Version: 3.3.0
3
+ Version: 3.3.2
4
4
  Summary: Sphinx API documentation generator
5
5
  Home-page: http://github.com/readthedocs/sphinx-autoapi
6
6
  Author: Eric Holscher
@@ -3,5 +3,5 @@
3
3
  from .extension import setup
4
4
 
5
5
  __all__ = ("setup",)
6
- __version__ = "3.3.0"
7
- __version_info__ = (3, 3, 0)
6
+ __version__ = "3.3.2"
7
+ __version_info__ = (3, 3, 2)
@@ -644,36 +644,6 @@ def get_return_annotation(node: astroid.nodes.FunctionDef) -> str | None:
644
644
  return return_annotation
645
645
 
646
646
 
647
- def get_func_docstring(node: astroid.nodes.FunctionDef) -> str:
648
- """Get the docstring of a node, using a parent docstring if needed.
649
-
650
- Args:
651
- node: The node to get a docstring for.
652
-
653
- Returns:
654
- The docstring of the function, or the empty string if no docstring
655
- was found or defined.
656
- """
657
- doc = node.doc_node.value if node.doc_node else ""
658
-
659
- if not doc and isinstance(node.parent, astroid.nodes.ClassDef):
660
- for base in node.parent.ancestors():
661
- if node.name in ("__init__", "__new__"):
662
- base_module = base.qname().split(".", 1)[0]
663
- if in_stdlib(base_module):
664
- continue
665
-
666
- for child in base.get_children():
667
- if (
668
- isinstance(child, node.__class__)
669
- and child.name == node.name
670
- and child.doc_node is not None
671
- ):
672
- return child.doc_node.value
673
-
674
- return doc
675
-
676
-
677
647
  def get_class_docstring(node: astroid.nodes.ClassDef) -> str:
678
648
  """Get the docstring of a node, using a parent docstring if needed.
679
649
 
@@ -5,6 +5,7 @@ import itertools
5
5
  import operator
6
6
  import os
7
7
  import re
8
+ import sys
8
9
 
9
10
  from jinja2 import Environment, FileSystemLoader
10
11
  import sphinx
@@ -31,6 +32,14 @@ from ._objects import (
31
32
  )
32
33
  from .settings import OWN_PAGE_LEVELS, TEMPLATE_DIR
33
34
 
35
+ if sys.version_info < (3, 10): # PY310
36
+ from stdlib_list import in_stdlib
37
+ else:
38
+
39
+ def in_stdlib(module_name: str) -> bool:
40
+ return module_name in sys.stdlib_module_names
41
+
42
+
34
43
  LOGGER = sphinx.util.logging.getLogger(__name__)
35
44
 
36
45
 
@@ -451,6 +460,24 @@ class Mapper:
451
460
  )
452
461
  return None
453
462
 
463
+ def _skip_if_stdlib(self):
464
+ documented_modules = {obj["full_name"] for obj in self.paths.values()}
465
+
466
+ q = collections.deque(self.paths.values())
467
+ while q:
468
+ obj = q.popleft()
469
+ if "children" in obj:
470
+ q.extend(obj["children"])
471
+
472
+ if obj.get("inherited", False):
473
+ module = obj["inherited_from"]["full_name"].split(".", 1)[0]
474
+ if (
475
+ in_stdlib(module)
476
+ and not obj["inherited_from"]["is_abstract"]
477
+ and module not in documented_modules
478
+ ):
479
+ obj["hide"] = True
480
+
454
481
  def _resolve_placeholders(self):
455
482
  """Resolve objects that have been imported from elsewhere."""
456
483
  modules = {}
@@ -477,6 +504,7 @@ class Mapper:
477
504
  child["hide"] = True
478
505
 
479
506
  def map(self, options=None):
507
+ self._skip_if_stdlib()
480
508
  self._resolve_placeholders()
481
509
  self._hide_yo_kids()
482
510
  self.app.env.autoapi_annotations = {}
@@ -1,7 +1,5 @@
1
1
  import collections
2
- import itertools
3
2
  import os
4
- import sys
5
3
 
6
4
  import astroid
7
5
  import astroid.builder
@@ -10,14 +8,6 @@ import sphinx.util.docstrings
10
8
  from . import _astroid_utils
11
9
 
12
10
 
13
- if sys.version_info < (3, 10): # PY310
14
- from stdlib_list import in_stdlib
15
- else:
16
-
17
- def in_stdlib(module_name: str) -> bool:
18
- return module_name in sys.stdlib_module_names
19
-
20
-
21
11
  def _prepare_docstring(doc):
22
12
  return "\n".join(sphinx.util.docstrings.prepare_docstring(doc))
23
13
 
@@ -117,55 +107,69 @@ class Parser:
117
107
 
118
108
  return [data]
119
109
 
120
- def parse_classdef(self, node, data=None):
110
+ def _parse_classdef(self, node, use_name_stacks):
111
+ if use_name_stacks:
112
+ qual_name = self._get_qual_name(node.name)
113
+ full_name = self._get_full_name(node.name)
114
+
115
+ self._qual_name_stack.append(node.name)
116
+ self._full_name_stack.append(node.name)
117
+ else:
118
+ qual_name = node.qname()[len(node.root().qname()) + 1 :]
119
+ full_name = node.qname()
120
+
121
121
  type_ = "class"
122
122
  if _astroid_utils.is_exception(node):
123
123
  type_ = "exception"
124
124
 
125
- basenames = list(_astroid_utils.get_full_basenames(node))
126
-
127
125
  data = {
128
126
  "type": type_,
129
127
  "name": node.name,
130
- "qual_name": self._get_qual_name(node.name),
131
- "full_name": self._get_full_name(node.name),
132
- "bases": basenames,
128
+ "qual_name": qual_name,
129
+ "full_name": full_name,
130
+ "bases": list(_astroid_utils.get_full_basenames(node)),
133
131
  "doc": _prepare_docstring(_astroid_utils.get_class_docstring(node)),
134
132
  "from_line_no": node.fromlineno,
135
133
  "to_line_no": node.tolineno,
136
134
  "children": [],
135
+ "is_abstract": _astroid_utils.is_abstract_class(node),
137
136
  }
138
137
 
139
- self._qual_name_stack.append(node.name)
140
- self._full_name_stack.append(node.name)
141
- overridden = set()
142
138
  overloads = {}
139
+ for child in node.get_children():
140
+ children_data = self.parse(child)
141
+ for child_data in children_data:
142
+ if _parse_child(child_data, overloads):
143
+ data["children"].append(child_data)
144
+
145
+ data["children"] = list(self._resolve_inheritance(data))
146
+
147
+ return data
148
+
149
+ def _resolve_inheritance(self, *mro_data):
150
+ overridden = set()
143
151
  children = {}
144
- for base in itertools.chain(iter((node,)), node.ancestors()):
152
+ for i, cls_data in enumerate(mro_data):
145
153
  seen = set()
146
154
  base_children = []
155
+ overloads = {}
147
156
 
148
- # Don't document members inherited from standard library classes
149
- # unless that class is abstract.
150
- base_module = base.qname().split(".", 1)[0]
151
- if in_stdlib(base_module) and not _astroid_utils.is_abstract_class(base):
152
- continue
153
-
154
- for child in base.get_children():
155
- children_data = self.parse(child)
156
- for child_data in children_data:
157
- name = child_data["name"]
157
+ for child_data in cls_data["children"]:
158
+ name = child_data["name"]
158
159
 
159
- existing_child = children.get(name)
160
- if existing_child and not existing_child["doc"]:
161
- existing_child["doc"] = child_data["doc"]
160
+ existing_child = children.get(name)
161
+ if existing_child and not existing_child["doc"]:
162
+ existing_child["doc"] = child_data["doc"]
162
163
 
163
- if name in overridden:
164
- continue
164
+ if name in overridden:
165
+ continue
165
166
 
166
- seen.add(name)
167
- if _parse_child(node, child_data, overloads, base):
168
- base_children.append(child_data)
167
+ seen.add(name)
168
+ if _parse_child(child_data, overloads):
169
+ base_children.append(child_data)
170
+ child_data["inherited"] = i != 0
171
+ if child_data["inherited"]:
172
+ child_data["inherited_from"] = cls_data
169
173
 
170
174
  overridden.update(seen)
171
175
 
@@ -185,7 +189,29 @@ class Parser:
185
189
 
186
190
  children[base_child["name"]] = base_child
187
191
 
188
- data["children"].extend(children.values())
192
+ return children.values()
193
+
194
+ def _relevant_ancestors(self, node):
195
+ for base in node.ancestors():
196
+ if base.qname() in (
197
+ "__builtins__.object",
198
+ "builtins.object",
199
+ "builtins.type",
200
+ ):
201
+ continue
202
+
203
+ yield base
204
+
205
+ def parse_classdef(self, node):
206
+ data = self._parse_classdef(node, use_name_stacks=True)
207
+
208
+ ancestors = self._relevant_ancestors(node)
209
+ ancestor_data = [
210
+ self._parse_classdef(base, use_name_stacks=False) for base in ancestors
211
+ ]
212
+ if ancestor_data:
213
+ data["children"] = list(self._resolve_inheritance(data, *ancestor_data))
214
+
189
215
  self._qual_name_stack.pop()
190
216
  self._full_name_stack.pop()
191
217
 
@@ -227,7 +253,7 @@ class Parser:
227
253
  "qual_name": self._get_qual_name(node.name),
228
254
  "full_name": self._get_full_name(node.name),
229
255
  "args": _astroid_utils.get_args_info(node.args),
230
- "doc": _prepare_docstring(_astroid_utils.get_func_docstring(node)),
256
+ "doc": _prepare_docstring(node.doc_node.value if node.doc_node else ""),
231
257
  "from_line_no": node.fromlineno,
232
258
  "to_line_no": node.tolineno,
233
259
  "return_annotation": _astroid_utils.get_return_annotation(node),
@@ -302,7 +328,7 @@ class Parser:
302
328
  children_data = self.parse(child)
303
329
 
304
330
  for child_data in children_data:
305
- if _parse_child(node, child_data, overloads):
331
+ if _parse_child(child_data, overloads):
306
332
  data["children"].append(child_data)
307
333
 
308
334
  return data
@@ -352,7 +378,7 @@ class Parser:
352
378
  return data
353
379
 
354
380
 
355
- def _parse_child(node, child_data, overloads, base=None) -> bool:
381
+ def _parse_child(child_data, overloads) -> bool:
356
382
  if child_data["type"] in ("function", "method", "property"):
357
383
  name = child_data["name"]
358
384
  if name in overloads:
@@ -369,7 +395,4 @@ def _parse_child(node, child_data, overloads, base=None) -> bool:
369
395
  if child_data["is_overload"] and name not in overloads:
370
396
  overloads[name] = child_data
371
397
 
372
- if base:
373
- child_data["inherited"] = base is not node
374
-
375
398
  return True
@@ -98,7 +98,7 @@ class _AutoapiDocstringSignatureMixin:
98
98
 
99
99
 
100
100
  class AutoapiFunctionDocumenter(
101
- AutoapiDocumenter, autodoc.FunctionDocumenter, _AutoapiDocstringSignatureMixin
101
+ AutoapiDocumenter, _AutoapiDocstringSignatureMixin, autodoc.FunctionDocumenter
102
102
  ):
103
103
  objtype = "apifunction"
104
104
  directivetype = "function"
@@ -147,9 +147,7 @@ class AutoapiDecoratorDocumenter(
147
147
  return "(" + to_format + ")"
148
148
 
149
149
 
150
- class AutoapiClassDocumenter(
151
- AutoapiDocumenter, autodoc.ClassDocumenter, _AutoapiDocstringSignatureMixin
152
- ):
150
+ class AutoapiClassDocumenter(AutoapiDocumenter, autodoc.ClassDocumenter):
153
151
  objtype = "apiclass"
154
152
  directivetype = "class"
155
153
  doc_as_attr = False
@@ -174,9 +172,18 @@ class AutoapiClassDocumenter(
174
172
  bases = ", ".join(f":class:`{base}`" for base in self.object.bases)
175
173
  self.add_line(f" Bases: {bases}", sourcename)
176
174
 
175
+ def format_signature(self, **kwargs):
176
+ # Set "manual" attributes at the last possible moment.
177
+ # This is to let a manual entry or docstring searching happen first,
178
+ # and falling back to the discovered signature only when necessary.
179
+ if self.args is None:
180
+ self.args = self.object.args
181
+
182
+ return super().format_signature(**kwargs)
183
+
177
184
 
178
185
  class AutoapiMethodDocumenter(
179
- AutoapiDocumenter, autodoc.MethodDocumenter, _AutoapiDocstringSignatureMixin
186
+ AutoapiDocumenter, _AutoapiDocstringSignatureMixin, autodoc.MethodDocumenter
180
187
  ):
181
188
  objtype = "apimethod"
182
189
  directivetype = "method"
@@ -230,9 +237,6 @@ class AutoapiPropertyDocumenter(AutoapiDocumenter, autodoc.PropertyDocumenter):
230
237
  autodoc.ClassLevelDocumenter.add_directive_header(self, sig)
231
238
 
232
239
  sourcename = self.get_sourcename()
233
- if self.options.annotation and self.options.annotation is not autodoc.SUPPRESS:
234
- self.add_line(f" :type: {self.options.annotation}", sourcename)
235
-
236
240
  for property_type in (
237
241
  "abstractmethod",
238
242
  "classmethod",
@@ -240,6 +244,9 @@ class AutoapiPropertyDocumenter(AutoapiDocumenter, autodoc.PropertyDocumenter):
240
244
  if property_type in self.object.properties:
241
245
  self.add_line(f" :{property_type}:", sourcename)
242
246
 
247
+ if self.object.annotation:
248
+ self.add_line(f" :type: {self.object.annotation}", sourcename)
249
+
243
250
 
244
251
  class AutoapiDataDocumenter(AutoapiDocumenter, autodoc.DataDocumenter):
245
252
  objtype = "apidata"
@@ -254,14 +261,16 @@ class AutoapiDataDocumenter(AutoapiDocumenter, autodoc.DataDocumenter):
254
261
  autodoc.ModuleLevelDocumenter.add_directive_header(self, sig)
255
262
  sourcename = self.get_sourcename()
256
263
  if not self.options.annotation:
257
- # TODO: Change sphinx to allow overriding of object description
258
264
  if self.object.value is not None:
259
- self.add_line(f" :annotation: = {self.object.value}", sourcename)
265
+ self.add_line(f" :value: {self.object.value}", sourcename)
260
266
  elif self.options.annotation is autodoc.SUPPRESS:
261
267
  pass
262
268
  else:
263
269
  self.add_line(f" :annotation: {self.options.annotation}", sourcename)
264
270
 
271
+ if self.object.annotation:
272
+ self.add_line(f" :type: {self.object.annotation}", sourcename)
273
+
265
274
 
266
275
  class AutoapiAttributeDocumenter(AutoapiDocumenter, autodoc.AttributeDocumenter):
267
276
  objtype = "apiattribute"
@@ -277,14 +286,16 @@ class AutoapiAttributeDocumenter(AutoapiDocumenter, autodoc.AttributeDocumenter)
277
286
  autodoc.ClassLevelDocumenter.add_directive_header(self, sig)
278
287
  sourcename = self.get_sourcename()
279
288
  if not self.options.annotation:
280
- # TODO: Change sphinx to allow overriding of object description
281
289
  if self.object.value is not None:
282
- self.add_line(f" :annotation: = {self.object.value}", sourcename)
290
+ self.add_line(f" :value: {self.object.value}", sourcename)
283
291
  elif self.options.annotation is autodoc.SUPPRESS:
284
292
  pass
285
293
  else:
286
294
  self.add_line(f" :annotation: {self.options.annotation}", sourcename)
287
295
 
296
+ if self.object.annotation:
297
+ self.add_line(f" :type: {self.object.annotation}", sourcename)
298
+
288
299
 
289
300
  class AutoapiModuleDocumenter(AutoapiDocumenter, autodoc.ModuleDocumenter):
290
301
  objtype = "apimodule"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sphinx-autoapi
3
- Version: 3.3.0
3
+ Version: 3.3.2
4
4
  Summary: Sphinx API documentation generator
5
5
  Home-page: http://github.com/readthedocs/sphinx-autoapi
6
6
  Author: Eric Holscher
@@ -116,6 +116,11 @@ tests/python/pypackageexample/package/subpackage/submodule.py
116
116
  tests/python/pyskipexample/conf.py
117
117
  tests/python/pyskipexample/index.rst
118
118
  tests/python/pyskipexample/example/example.py
119
+ tests/python/pystdlib/conf.py
120
+ tests/python/pystdlib/index.rst
121
+ tests/python/pystdlib/stdlib/json.py
122
+ tests/python/pystdlib/stdlib/myast.py
123
+ tests/python/pystdlib/stdlib/myjson.py
119
124
  tests/templateexample/conf.py
120
125
  tests/templateexample/index.rst
121
126
  tests/templateexample/example/example.py
@@ -1,8 +1,6 @@
1
- import io
2
1
  import os
3
2
  import pathlib
4
3
  import shutil
5
- from unittest.mock import call
6
4
 
7
5
  from bs4 import BeautifulSoup
8
6
  import pytest
@@ -3,6 +3,7 @@
3
3
  This is a description
4
4
  """
5
5
 
6
+ from dataclasses import dataclass
6
7
  from functools import cached_property
7
8
 
8
9
  A_TUPLE = ("a", "b")
@@ -171,3 +172,26 @@ def fn_with_long_sig(
171
172
  arguments
172
173
  ):
173
174
  """A function with a long signature."""
175
+
176
+
177
+ TYPED_DATA: int = 1
178
+ """This is TYPED_DATA."""
179
+
180
+
181
+ @dataclass
182
+ class TypedAttrs:
183
+ one: str
184
+ """This is TypedAttrs.one."""
185
+ two: int = 1
186
+ """This is TypedAttrs.two."""
187
+
188
+
189
+ class TypedClassInit:
190
+ """This is TypedClassInit."""
191
+
192
+ def __init__(self, one: int = 1) -> None:
193
+ self._one = one
194
+
195
+ def typed_method(self, two: int) -> int:
196
+ """This is TypedClassInit.typed_method."""
197
+ return self._one + two
@@ -3,6 +3,7 @@
3
3
  This is a description
4
4
  """
5
5
 
6
+ from dataclasses import dataclass
6
7
  from functools import cached_property
7
8
 
8
9
  A_TUPLE = ("a", "b")
@@ -171,3 +172,26 @@ def fn_with_long_sig(
171
172
  arguments
172
173
  ):
173
174
  """A function with a long signature."""
175
+
176
+
177
+ TYPED_DATA: int = 1
178
+ """This is TYPED_DATA."""
179
+
180
+
181
+ @dataclass
182
+ class TypedAttrs:
183
+ one: str
184
+ """This is TypedAttrs.one."""
185
+ two: int = 1
186
+ """This is TypedAttrs.two."""
187
+
188
+
189
+ class TypedClassInit:
190
+ """This is TypedClassInit."""
191
+
192
+ def __init__(self, one: int = 1) -> None:
193
+ self._one = one
194
+
195
+ def typed_method(self, two: int) -> int:
196
+ """This is TypedClassInit.typed_method."""
197
+ return self._one + two
@@ -0,0 +1,24 @@
1
+ templates_path = ["_templates"]
2
+ source_suffix = ".rst"
3
+ master_doc = "index"
4
+ project = "pystdlib"
5
+ copyright = "2015, readthedocs"
6
+ author = "readthedocs"
7
+ version = "0.1"
8
+ release = "0.1"
9
+ language = "en"
10
+ exclude_patterns = ["_build"]
11
+ pygments_style = "sphinx"
12
+ todo_include_todos = False
13
+ html_theme = "alabaster"
14
+ htmlhelp_basename = "pystdlibdoc"
15
+ extensions = ["autoapi.extension"]
16
+ autoapi_dirs = ["stdlib"]
17
+ autoapi_file_pattern = "*.py"
18
+ autoapi_keep_files = True
19
+ autoapi_options = [
20
+ "members",
21
+ "undoc-members" "special-members",
22
+ "imported-members",
23
+ "inherited-members",
24
+ ]
@@ -0,0 +1,25 @@
1
+ .. pypackageexample documentation master file, created by
2
+ sphinx-quickstart on Fri May 29 13:34:37 2015.
3
+ You can adapt this file completely to your liking, but it should at least
4
+ contain the root `toctree` directive.
5
+
6
+ Welcome to pypackageexample's documentation!
7
+ ============================================
8
+
9
+ .. toctree::
10
+
11
+ autoapi/index
12
+
13
+ Contents:
14
+
15
+ .. toctree::
16
+ :maxdepth: 2
17
+
18
+
19
+
20
+ Indices and tables
21
+ ==================
22
+
23
+ * :ref:`genindex`
24
+ * :ref:`modindex`
25
+ * :ref:`search`
@@ -0,0 +1,9 @@
1
+ """json is the same name as a stdlib module."""
2
+
3
+
4
+ class JSONDecoder:
5
+ """Do things with json."""
6
+
7
+ def decode(self, s):
8
+ """Decode a string."""
9
+ return s
@@ -0,0 +1,10 @@
1
+ """This is a docstring."""
2
+
3
+ import ast
4
+
5
+
6
+ class MyVisitor(ast.NodeVisitor):
7
+ """My custom visitor."""
8
+
9
+ def my_visit(self):
10
+ """My visit method."""
@@ -0,0 +1,10 @@
1
+ """This is a docstring."""
2
+
3
+ from json import JSONDecoder
4
+
5
+
6
+ class MyJSONDecoder(JSONDecoder):
7
+ """This is a class."""
8
+
9
+ def my_method(self):
10
+ """This is a method."""
@@ -1,4 +1,3 @@
1
- import io
2
1
  import os
3
2
  import pathlib
4
3
  import sys
@@ -178,6 +177,74 @@ class TestSimpleModuleManual:
178
177
  example_file = parse("_build/html/manualapi.html")
179
178
  assert example_file.find(id="example.decorator_okay")
180
179
 
180
+ def test_dataclass(self, parse):
181
+ example_file = parse("_build/html/manualapi.html")
182
+
183
+ typedattrs_sig = example_file.find(id="example.TypedAttrs")
184
+ assert typedattrs_sig
185
+
186
+ typedattrs = typedattrs_sig.parent
187
+
188
+ one = typedattrs.find(id="example.TypedAttrs.one")
189
+ assert one
190
+ one_value = one.find_all(class_="property")
191
+ assert one_value[0].text == ": str"
192
+ one_docstring = one.parent.find("dd").contents[0].text
193
+ assert one_docstring.strip() == "This is TypedAttrs.one."
194
+
195
+ two = typedattrs.find(id="example.TypedAttrs.two")
196
+ assert two
197
+ two_value = two.find_all(class_="property")
198
+ assert two_value[0].text == ": int"
199
+ assert two_value[1].text == " = 1"
200
+ two_docstring = two.parent.find("dd").contents[0].text
201
+ assert two_docstring.strip() == "This is TypedAttrs.two."
202
+
203
+ def test_data(self, parse):
204
+ example_file = parse("_build/html/manualapi.html")
205
+
206
+ typed_data = example_file.find(id="example.TYPED_DATA")
207
+ assert typed_data
208
+ typed_data_value = typed_data.find_all(class_="property")
209
+ assert typed_data_value[0].text == ": int"
210
+ assert typed_data_value[1].text == " = 1"
211
+
212
+ typed_data_docstring = typed_data.parent.find("dd").contents[0].text
213
+ assert typed_data_docstring.strip() == "This is TYPED_DATA."
214
+
215
+ def test_class(self, parse):
216
+ example_file = parse("_build/html/manualapi.html")
217
+
218
+ typed_cls = example_file.find(id="example.TypedClassInit")
219
+ assert typed_cls
220
+ arg = typed_cls.find(class_="sig-param")
221
+ assert arg.text == "one: int = 1"
222
+ typed_cls_docstring = typed_cls.parent.find("dd").contents[0].text
223
+ assert typed_cls_docstring.strip() == "This is TypedClassInit."
224
+
225
+ typed_method = example_file.find(id="example.TypedClassInit.typed_method")
226
+ assert typed_method
227
+ arg = typed_method.find(class_="sig-param")
228
+ assert arg.text == "two: int"
229
+ return_type = typed_method.find(class_="sig-return-typehint")
230
+ assert return_type.text == "int"
231
+ typed_method_docstring = typed_method.parent.find("dd").contents[0].text
232
+ assert typed_method_docstring.strip() == "This is TypedClassInit.typed_method."
233
+
234
+ def test_property(self, parse):
235
+ example_file = parse("_build/html/manualapi.html")
236
+
237
+ foo_sig = example_file.find(id="example.Foo")
238
+ assert foo_sig
239
+ foo = foo_sig.parent
240
+
241
+ property_simple = foo.find(id="example.Foo.property_simple")
242
+ assert property_simple
243
+ property_simple_value = property_simple.find_all(class_="property")
244
+ assert property_simple_value[-1].text == ": int"
245
+ property_simple_docstring = property_simple.parent.find("dd").text.strip()
246
+ assert property_simple_docstring == "This property should parse okay."
247
+
181
248
 
182
249
  class TestMovedConfPy(TestSimpleModule):
183
250
  @pytest.fixture(autouse=True, scope="class")
@@ -1243,3 +1310,51 @@ def test_nothing_to_render_raises_warning(builder):
1243
1310
  builder("pynorender", warningiserror=True)
1244
1311
 
1245
1312
  assert "No modules were rendered" in str(exc_info.value)
1313
+
1314
+
1315
+ class TestStdLib:
1316
+ """Check that modules with standard library names are still documented."""
1317
+
1318
+ @pytest.fixture(autouse=True)
1319
+ def built(self, builder):
1320
+ builder("pystdlib")
1321
+
1322
+ def test_integration(self, parse):
1323
+ json_file = parse("_build/html/autoapi/json/index.html")
1324
+
1325
+ json_mod = json_file.find(id="json")
1326
+ assert "json is the same name" in json_mod.parent.text
1327
+
1328
+ assert json_file.find(id="json.JSONDecoder")
1329
+ decode = json_file.find(id="json.JSONDecoder.decode")
1330
+ assert decode
1331
+ wrap_docstring = decode.parent.find("dd").text.strip()
1332
+ assert wrap_docstring == "Decode a string."
1333
+
1334
+ myjson_file = parse("_build/html/autoapi/myjson/index.html")
1335
+
1336
+ # Find members that are not inherited from local standard library classes.
1337
+ ctx = myjson_file.find(id="myjson.MyJSONDecoder")
1338
+ assert ctx
1339
+ meth = myjson_file.find(id="myjson.MyJSONDecoder.my_method")
1340
+ assert meth
1341
+ meth_docstring = meth.parent.find("dd").text.strip()
1342
+ assert meth_docstring == "This is a method."
1343
+
1344
+ # Find members that are inherited from local standard library classes.
1345
+ decode = myjson_file.find(id="myjson.MyJSONDecoder.decode")
1346
+ assert decode
1347
+
1348
+ myast_file = parse("_build/html/autoapi/myast/index.html")
1349
+
1350
+ # Find members that are not inherited from standard library classes.
1351
+ visitor = myast_file.find(id="myast.MyVisitor")
1352
+ assert visitor
1353
+ meth = myast_file.find(id="myast.MyVisitor.my_visit")
1354
+ assert meth
1355
+ meth_docstring = meth.parent.find("dd").text.strip()
1356
+ assert meth_docstring == "My visit method."
1357
+
1358
+ # Find members that are inherited from standard library classes.
1359
+ meth = myast_file.find(id="myast.MyVisitor.visit")
1360
+ assert not meth
File without changes
File without changes