Skip to content

Commit

Permalink
fix: Fix inheritance logic when intermediate class without member is …
Browse files Browse the repository at this point in the history
…present

Issue-4: #4
PR-5: #5
Co-authored-by: Timothée Mazzucotelli <dev@pawamoy.fr>
  • Loading branch information
thomasmarwitz and pawamoy authored Nov 5, 2024
1 parent c89f92f commit 639ff80
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/griffe_inherited_docstrings/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@

def _docstring_above(obj: Object) -> Docstring | None:
with contextlib.suppress(IndexError, KeyError):
parent = obj.parent.mro()[0] # type: ignore[union-attr]
return parent.members[obj.name].docstring
for parent in obj.parent.mro(): # type: ignore[union-attr]
# Fetch docstring from first parent that has the member.
if obj.name in parent.members:
return parent.members[obj.name].docstring
return None


Expand All @@ -35,7 +37,7 @@ def _inherit_docstrings(obj: Object, *, merge: bool = False, seen: set[str] | No

elif obj.is_class:
# Recursively handle top-most parents first.
# It means that we can just check the first parent
# It means that we can just check the first parent with the member
# when actually inheriting (and optionally merging) a docstring,
# since the docstrings of the other parents have already been inherited.
for parent in reversed(obj.mro()): # type: ignore[attr-defined]
Expand Down
29 changes: 29 additions & 0 deletions tests/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,32 @@ def meth(self):
assert package["D.meth"].docstring.value == package["A.meth"].docstring.value + "\n\n" + f"{meth_doc} D."
assert package["E.attr"].docstring.value == package["D.attr"].docstring.value + "\n\n" + f"{attr_doc} E."
assert package["E.meth"].docstring.value == package["D.meth"].docstring.value + "\n\n" + f"{meth_doc} E."


def test_inherit_and_merge_docstrings_intermediate_class() -> None:
"""Inherit and merge docstrings from parent classes with an intermediate class.
It is important that the intermediate class doesn't have the member for which
docstring inheritance should be performed.
"""
with temporary_visited_package(
"package",
modules={
"__init__.py": """
class Parent:
def method(self):
'''Parent.'''
class Intermediate(Parent):
# This shouldn't break the inherting of docstrings.
# See https://github.com/mkdocstrings/griffe-inherited-docstrings/issues/4.
...
class Child(Intermediate):
def method(self):
'''Child.'''
""",
},
extensions=Extensions(InheritDocstringsExtension(merge=True)),
) as package:
assert package["Child.method"].docstring.value == "Parent.\n\nChild."

0 comments on commit 639ff80

Please sign in to comment.