diff --git a/README.md b/README.md index 0290da6..dd84920 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,42 @@ Notes: """ ``` +## Using decorators + +Functions and methods can be decorated with the `inherit_docstring` decorator +to inherit the docstring of another function or method. For example, the above +example can be rewritten as: + +```python +from docstring_inheritance import inherit_docstring + + +def parent(): + """Parent summary. + + Args: + x: Description for x. + y: Description for y. + + Notes: + Parent notes. + """ + + +@inherit_docstring(source=parent, style="google") +def child(): + """ + Args: + z: Description for z. + + Returns: + Something. + + Notes: + Child notes. + """ +``` + # Docstring inheritance specification ## Sections order diff --git a/src/docstring_inheritance/__init__.py b/src/docstring_inheritance/__init__.py index 89270cd..24b8d77 100644 --- a/src/docstring_inheritance/__init__.py +++ b/src/docstring_inheritance/__init__.py @@ -19,7 +19,7 @@ # SOFTWARE. from __future__ import annotations -from typing import Any +from typing import Any, Callable, Literal from .class_docstrings_inheritor import ClassDocstringsInheritor from .class_docstrings_inheritor import DocstringInheritor @@ -120,3 +120,16 @@ def __init__( inherit_numpy_docstring, init_in_class=True, ) + + +def inherit_docstring(func: Callable = None, *, source: Callable = None, style: Literal["numpy", "google"] = "numpy"): + """Decorator for inherit docstring from other functions.""" + assert source is not None, "Source function is not given." + assert style in ("numpy", "google"), "Style must be either 'numpy' or 'google'." + + def wrapper(f): + inherit_func = inherit_numpy_docstring if style == "numpy" else inherit_google_docstring + inherit_func(source.__doc__, f) + return f + + return wrapper if func is None else wrapper(func) diff --git a/tests/test_inheritance_for_functions.py b/tests/test_inheritance_for_functions.py index f2f2a98..f0842e9 100644 --- a/tests/test_inheritance_for_functions.py +++ b/tests/test_inheritance_for_functions.py @@ -23,6 +23,7 @@ import pytest +from docstring_inheritance import inherit_docstring from docstring_inheritance import inherit_google_docstring from docstring_inheritance import inherit_numpy_docstring from docstring_inheritance.class_docstrings_inheritor import ClassDocstringsInheritor @@ -131,6 +132,38 @@ def child(x, missing_doc, *child_varargs, **child_kwargs): assert child.__doc__ == expected.strip("\n") +def test_decorator(): + def parent(arg, *parent_varargs, **parent_kwargs): + """Parent summary. + + Args: + arg: desc + *parent_varargs: Parent *args + **parent_kwargs: Parent **kwargs + """ + + @inherit_docstring(source=parent, style="google") + def child(x, missing_doc, *child_varargs, **child_kwargs): + """Child summary. + + Args: + x: X + child_varargs: Not *args + *child_varargs: Child *args + **child_kwargs: Child **kwargs + """ + + expected = """Child summary. + +Args: + x: X + missing_doc: The description is missing. + *child_varargs: Child *args + **child_kwargs: Child **kwargs +""" + assert child.__doc__ == expected.strip("\n") + + @pytest.mark.parametrize( "inherit_docstring", [inherit_numpy_docstring, inherit_google_docstring] )