diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 9121e00b3e8d6..3c1602344c314 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -757,7 +757,7 @@ def _validate_shift_value(self, fill_value): "will raise in a future version, pass " f"{self._scalar_type.__name__} instead.", FutureWarning, - stacklevel=10, + stacklevel=8, ) fill_value = new_fill diff --git a/pandas/tseries/offsets.py b/pandas/tseries/offsets.py index 8aced50b78ae2..10fd7e5680ff9 100644 --- a/pandas/tseries/offsets.py +++ b/pandas/tseries/offsets.py @@ -35,7 +35,7 @@ to_dt64D, ) from pandas.errors import AbstractMethodError -from pandas.util._decorators import Appender, Substitution, cache_readonly +from pandas.util._decorators import cache_readonly, doc __all__ = [ "Day", @@ -877,11 +877,12 @@ class BusinessMonthBegin(MonthOffset): _day_opt = "business_start" +@doc(bound="bound") class _CustomBusinessMonth(CustomMixin, BusinessMixin, MonthOffset): """ DateOffset subclass representing custom business month(s). - Increments between %(bound)s of month dates. + Increments between {bound} of month dates. Parameters ---------- @@ -971,14 +972,12 @@ def apply(self, other): return result -@Substitution(bound="end") -@Appender(_CustomBusinessMonth.__doc__) +@doc(_CustomBusinessMonth, bound="end") class CustomBusinessMonthEnd(_CustomBusinessMonth): _prefix = "CBM" -@Substitution(bound="beginning") -@Appender(_CustomBusinessMonth.__doc__) +@doc(_CustomBusinessMonth, bound="beginning") class CustomBusinessMonthBegin(_CustomBusinessMonth): _prefix = "CBMS" diff --git a/pandas/util/_decorators.py b/pandas/util/_decorators.py index 80286d5f138ad..6135ccba1573d 100644 --- a/pandas/util/_decorators.py +++ b/pandas/util/_decorators.py @@ -329,55 +329,52 @@ def wrapper(*args, **kwargs) -> Callable[..., Any]: return decorate -def doc(*args: Union[str, Callable], **kwargs) -> Callable[[F], F]: +def doc(*docstrings: Union[str, Callable], **params) -> Callable[[F], F]: """ A decorator take docstring templates, concatenate them and perform string substitution on it. This decorator will add a variable "_docstring_components" to the wrapped - function to keep track the original docstring template for potential usage. + callable to keep track the original docstring template for potential usage. If it should be consider as a template, it will be saved as a string. Otherwise, it will be saved as callable, and later user __doc__ and dedent to get docstring. Parameters ---------- - *args : str or callable + *docstrings : str or callable The string / docstring / docstring template to be appended in order - after default docstring under function. - **kwargs - The objects which would be used to format docstring template. + after default docstring under callable. + **params + The string which would be used to format docstring template. """ - def decorator(func: F) -> F: - @wraps(func) - def wrapper(*args, **kwargs) -> Callable: - return func(*args, **kwargs) - + def decorator(decorated: F) -> F: # collecting docstring and docstring templates docstring_components: List[Union[str, Callable]] = [] - if func.__doc__: - docstring_components.append(dedent(func.__doc__)) + if decorated.__doc__: + docstring_components.append(dedent(decorated.__doc__)) - for arg in args: - if hasattr(arg, "_docstring_components"): - docstring_components.extend(arg._docstring_components) # type: ignore - elif isinstance(arg, str) or arg.__doc__: - docstring_components.append(arg) + for docstring in docstrings: + if hasattr(docstring, "_docstring_components"): + docstring_components.extend( + docstring._docstring_components # type: ignore + ) + elif isinstance(docstring, str) or docstring.__doc__: + docstring_components.append(docstring) # formatting templates and concatenating docstring - wrapper.__doc__ = "".join( + decorated.__doc__ = "".join( [ - arg.format(**kwargs) - if isinstance(arg, str) - else dedent(arg.__doc__ or "") - for arg in docstring_components + component.format(**params) + if isinstance(component, str) + else dedent(component.__doc__ or "") + for component in docstring_components ] ) - wrapper._docstring_components = docstring_components # type: ignore - - return cast(F, wrapper) + decorated._docstring_components = docstring_components # type: ignore + return decorated return decorator