Repository: matplotlib/matplotlib
File: lib/matplotlib/_api/deprecation.py (Python)

Code before:
    DECORATORS[wrapper] = decorator
    return wrapper


def make_keyword_only(since, name, func=None):
    """
    Decorator indicating that passing parameter *name* (or any of the following
    ones) positionally to *func* is being deprecated.

    When used on a method that has a pyplot wrapper, this should be the
    outermost decorator, so that :file:`boilerplate.py` can access the original
    signature.

    Examples
    --------
    Assume we want to only allow *dataset* and *positions* as positional
    parameters on the method ::

        def violinplot(self, dataset, positions=None, vert=None, ...)

    Introduce the deprecation by adding the decorator ::

        @_api.make_keyword_only("3.10", "vert")
        def violinplot(self, dataset, positions=None, vert=None, ...)

    When the deprecation expires, switch to

        def violinplot(self, dataset, positions=None, *, vert=None, ...)

    """

    decorator = functools.partial(make_keyword_only, since, name)

    if func is None:
        return decorator

    signature = inspect.signature(func)
    POK = inspect.Parameter.POSITIONAL_OR_KEYWORD
    KWO = inspect.Parameter.KEYWORD_ONLY
    assert (name in signature.parameters
            and signature.parameters[name].kind == POK), (
        f"Matplotlib internal error: {name!r} must be a positional-or-keyword "
        f"parameter for {func.__name__}(). If this error happens on a function with a "
        f"pyplot wrapper, make sure make_keyword_only() is the outermost decorator.")
    names = [*signature.parameters]
    name_idx = names.index(name)
    kwonly = [name for name in names[name_idx:]
              if signature.parameters[name].kind == POK]

    @functools.wraps(func)
    def wrapper(*args, **kwargs):

Review comment (suggestion):
```suggestion
    When the deprecation expires, switch to ::
```
I’m not sure if this is the cause, but the rendering of the third code block is a bit off
https://output.circle-artifacts.com/output/job/79ef365d-ab41-47ba-9d61-3de8e3f727f5/artifacts/0/doc/build/html/api/_api_api.html#matplotlib._api.deprecation.make_keyword_only

Code after:
    DECORATORS[wrapper] = decorator
    return wrapper


def make_keyword_only(since, name, func=None):
    """
    Decorator indicating that passing parameter *name* (or any of the following
    ones) positionally to *func* is being deprecated.

    When used on a method that has a pyplot wrapper, this should be the
    outermost decorator, so that :file:`boilerplate.py` can access the original
    signature.

    Examples
    --------
    Assume we want to only allow *dataset* and *positions* as positional
    parameters on the method ::

        def violinplot(self, dataset, positions=None, vert=None, ...)

    Introduce the deprecation by adding the decorator ::

        @_api.make_keyword_only("3.10", "vert")
        def violinplot(self, dataset, positions=None, vert=None, ...)

    When the deprecation expires, switch to ::

        def violinplot(self, dataset, positions=None, *, vert=None, ...)

    """

    decorator = functools.partial(make_keyword_only, since, name)

    if func is None:
        return decorator

    signature = inspect.signature(func)
    POK = inspect.Parameter.POSITIONAL_OR_KEYWORD
    KWO = inspect.Parameter.KEYWORD_ONLY
    assert (name in signature.parameters
            and signature.parameters[name].kind == POK), (
        f"Matplotlib internal error: {name!r} must be a positional-or-keyword "
        f"parameter for {func.__name__}(). If this error happens on a function with a "
        f"pyplot wrapper, make sure make_keyword_only() is the outermost decorator.")
    names = [*signature.parameters]
    name_idx = names.index(name)
    kwonly = [name for name in names[name_idx:]
              if signature.parameters[name].kind == POK]

    @functools.wraps(func)
    def wrapper(*args, **kwargs):