Source code for metacells.utilities.documentation

"""
Documentation
-------------

Utilities for documenting Python functions.
"""

from inspect import Parameter
from inspect import signature
from typing import Any
from typing import Callable
from typing import TypeVar
from warnings import warn

__all__ = [
    "expand_doc",
]


CALLABLE = TypeVar("CALLABLE")


[docs] def expand_doc(**kwargs: Any) -> Callable[[CALLABLE], CALLABLE]: ''' Expand the keyword arguments and the annotated function's default argument values inside the function's document string. That is, given something like: .. code:: python @expand_doc(foo=7) def bar(baz, vaz=5): """ Bar with {foo} foos and parameter vaz (default: {baz}). """ Then ``help(bar)`` will print: .. code:: text Bar with 7 foos and parameter vaz (default: 5). ''' def documented(function: Callable) -> Callable: for parameter in signature(function).parameters.values(): if parameter.default != Parameter.empty and parameter.name not in kwargs: kwargs[parameter.name] = parameter.default assert function.__doc__ is not None try: expanded_doc = function.__doc__.format_map(kwargs) except BaseException as exception: raise RuntimeError( # pylint: disable=raise-missing-from f"key {exception} " f"in expand_doc documentation for the function " f"{function.__module__}.{function.__qualname__}" ) if expanded_doc == function.__doc__: expand_doc_had_no_effect = ( "@expand_doc had no effect on the documentation of the function " f"{function.__module__}.{function.__qualname__}" ) warn(expand_doc_had_no_effect) function.__doc__ = expanded_doc return function return documented # type: ignore