Skip to content

Commit 1b128e1

Browse files
committed
Inherit docstrings from parent classes
This change makes it so that subclass methods that do not have docstrings inherit a docstring from the first parent class whose overriden method has a docstring. It also improves the case for the options ```yaml include_empty: false include_inherited: true ``` where inherited subclass methods are omitted if they have no docstring, yet a parent class method has a docstring. e.g. ``` class Base: def m1(): ... """Calculate m1""" def m2(): ... """Calculate m2""" class Derived(Base): def m2(): ... ``` If the intention is to document `Derived` and include the inherited methods, it would be a surprise if `Derived.m2` is omitted or it is included but it has no docstring. As a result to have an option like `include_inherited_docstring` that can be `false` does not align with the users expected intentions.
1 parent 3b673a9 commit 1b128e1

File tree

6 files changed

+33
-3
lines changed

6 files changed

+33
-3
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ requires-python = ">=3.9"
3333
dependencies = [
3434
"click",
3535
"griffe >= 0.33",
36+
"griffe-inherited-docstrings",
3637
"sphobjinv >= 2.3.1",
3738
"tabulate >= 0.9.0",
3839
"importlib-metadata >= 5.1.0",

quartodoc/autosummary.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from griffe.dataclasses import Alias
1212
from griffe.docstrings.parsers import Parser, parse
1313
from griffe.docstrings import dataclasses as ds # noqa
14+
from griffe.extensions import Extensions
15+
from griffe_inherited_docstrings import InheritDocstringsExtension
1416
from griffe import dataclasses as dc
1517
from plum import dispatch # noqa
1618
from pathlib import Path
@@ -123,6 +125,7 @@ def get_object(
123125

124126
if loader is None:
125127
loader = GriffeLoader(
128+
extensions=Extensions(InheritDocstringsExtension()),
126129
docstring_parser=Parser(parser),
127130
docstring_options=get_parser_defaults(parser),
128131
modules_collection=ModulesCollection(),

quartodoc/builder/blueprint.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from griffe.collections import ModulesCollection, LinesCollection
1010
from griffe.docstrings.parsers import Parser
1111
from griffe.exceptions import AliasResolutionError
12+
from griffe.extensions import Extensions
13+
from griffe_inherited_docstrings import InheritDocstringsExtension
1214
from functools import partial
1315
from textwrap import indent
1416

@@ -145,6 +147,7 @@ class BlueprintTransformer(PydanticTransformer):
145147
def __init__(self, get_object=None, parser="numpy"):
146148
if get_object is None:
147149
loader = GriffeLoader(
150+
extensions=Extensions(InheritDocstringsExtension()),
148151
docstring_parser=Parser(parser),
149152
docstring_options=get_parser_defaults(parser),
150153
modules_collection=ModulesCollection(),

quartodoc/tests/__snapshots__/test_renderers.ambr

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,16 @@
5454

5555
| Name | Description |
5656
| --- | --- |
57+
| [another_method](#quartodoc.tests.example_class.C.another_method) | Another method |
5758
| [some_class_method](#quartodoc.tests.example_class.C.some_class_method) | A class method |
5859
| [some_method](#quartodoc.tests.example_class.C.some_method) | A method |
5960

61+
### another_method { #quartodoc.tests.example_class.C.another_method }
62+
63+
`tests.example_class.C.another_method()`
64+
65+
Another method
66+
6067
### some_class_method { #quartodoc.tests.example_class.C.some_class_method }
6168

6269
`tests.example_class.C.some_class_method()`
@@ -112,9 +119,16 @@
112119

113120
| Name | Description |
114121
| --- | --- |
122+
| [another_method](#quartodoc.tests.example_class.C.another_method) | Another method |
115123
| [some_class_method](#quartodoc.tests.example_class.C.some_class_method) | A class method |
116124
| [some_method](#quartodoc.tests.example_class.C.some_method) | A method |
117125

126+
## another_method { #quartodoc.tests.example_class.C.another_method }
127+
128+
`tests.example_class.C.another_method()`
129+
130+
Another method
131+
118132
## some_class_method { #quartodoc.tests.example_class.C.some_class_method }
119133

120134
`tests.example_class.C.some_class_method()`

quartodoc/tests/example_class.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ def __init__(self, x: str, y: int):
2525
def some_method(self):
2626
"""A method"""
2727

28+
def another_method(self):
29+
"""Another method"""
30+
2831
@property
2932
def some_property(self):
3033
"""A property"""
@@ -41,6 +44,9 @@ class Child(C):
4144
def some_new_method(self):
4245
"""A new method"""
4346

47+
# To test inheriting docstring
48+
def another_method(self): ...
49+
4450

4551
class AttributesTable:
4652
"""The short summary.

quartodoc/tests/test_builder_blueprint.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def _check_member_names(members, expected):
217217
[
218218
("attributes", {"some_property", "z", "SOME_ATTRIBUTE"}),
219219
("classes", {"D"}),
220-
("functions", {"some_method", "some_class_method"}),
220+
("functions", {"some_method", "another_method", "some_class_method"}),
221221
],
222222
)
223223
def test_blueprint_fetch_members_include_kind_false(kind, removed):
@@ -227,6 +227,7 @@ def test_blueprint_fetch_members_include_kind_false(kind, removed):
227227
"z",
228228
"some_property",
229229
"some_method",
230+
"another_method",
230231
"D",
231232
"some_class_method",
232233
}
@@ -240,8 +241,10 @@ def test_blueprint_fetch_members_include_inherited():
240241
auto = lo.Auto(name="quartodoc.tests.example_class.Child", include_inherited=True)
241242
bp = blueprint(auto)
242243

243-
member_names = set([entry.name for entry in bp.members])
244-
assert "some_method" in member_names
244+
members = {entry.name: entry for entry in bp.members}
245+
assert "some_method" in members
246+
assert "another_method" in members
247+
assert "Another method" in members["another_method"].obj.docstring.value
245248

246249

247250
def test_blueprint_fetch_members_dynamic():

0 commit comments

Comments
 (0)