# Path: seaborn/_decorators.py
# def _deprecate_positional_args(f):
#     """Decorator for methods that issues warnings for positional arguments.
# 
#     Using the keyword-only argument syntax in pep 3102, arguments after the
#     * will issue a warning when passed as a positional argument.
# 
#     Parameters
#     ----------
#     f : function
#         function to check arguments on
# 
#     """
#     sig = signature(f)
#     kwonly_args = []
#     all_args = []
# 
#     for name, param in sig.parameters.items():
#         if param.kind == Parameter.POSITIONAL_OR_KEYWORD:
#             all_args.append(name)
#         elif param.kind == Parameter.KEYWORD_ONLY:
#             kwonly_args.append(name)
# 
#     @wraps(f)
#     def inner_f(*args, **kwargs):
#         extra_args = len(args) - len(all_args)
#         if extra_args > 0:
#             plural = "s" if extra_args > 1 else ""
#             article = "" if plural else "a "
#             warnings.warn(
#                 "Pass the following variable{} as {}keyword arg{}: {}. "
#                 "From version 0.12, the only valid positional argument "
#                 "will be `data`, and passing other arguments without an "
#                 "explicit keyword will result in an error or misinterpretation."
#                 .format(plural, article, plural,
#                         ", ".join(kwonly_args[:extra_args])),
#                 FutureWarning
#             )
#         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
#         return f(**kwargs)
#     return inner_f
# 
# def share_init_params_with_map(cls):
#     """Make cls.map a classmethod with same signature as cls.__init__."""
#     map_sig = signature(cls.map)
#     init_sig = signature(cls.__init__)
# 
#     new = [v for k, v in init_sig.parameters.items() if k != "self"]
#     new.insert(0, map_sig.parameters["cls"])
#     cls.map.__signature__ = map_sig.replace(parameters=new)
#     cls.map.__doc__ = cls.__init__.__doc__
# 
#     cls.map = classmethod(cls.map)
# 
#     return cls


import inspect
import pytest
from .._decorators import (
    _deprecate_positional_args,
    share_init_params_with_map,
)
# github.com/scikit-learn/scikit-learn/blob/master/sklearn/utils/tests/test_validation.py
def test_deprecate_positional_args_warns_for_function():

    @_deprecate_positional_args
    def f1(a, b, *, c=1, d=1):
        return a, b, c, d

    with pytest.warns(
        FutureWarning,
        match=r"Pass the following variable as a keyword arg: c\."
    ):
        assert f1(1, 2, 3) == (1, 2, 3, 1)

    with pytest.warns(
        FutureWarning,
        match=r"Pass the following variables as keyword args: c, d\."
    ):
        assert f1(1, 2, 3, 4) == (1, 2, 3, 4)

    @_deprecate_positional_args
    def f2(a=1, *, b=1, c=1, d=1):
        return a, b, c, d

    with pytest.warns(
        FutureWarning,
        match=r"Pass the following variable as a keyword arg: b\.",
    ):
        assert f2(1, 2) == (1, 2, 1, 1)

    # The * is placed before a keyword only argument without a default value

# Path: seaborn/_decorators.py
# def _deprecate_positional_args(f):
#     """Decorator for methods that issues warnings for positional arguments.
# 
#     Using the keyword-only argument syntax in pep 3102, arguments after the
#     * will issue a warning when passed as a positional argument.
# 
#     Parameters
#     ----------
#     f : function
#         function to check arguments on
# 
#     """
#     sig = signature(f)
#     kwonly_args = []
#     all_args = []
# 
#     for name, param in sig.parameters.items():
#         if param.kind == Parameter.POSITIONAL_OR_KEYWORD:
#             all_args.append(name)
#         elif param.kind == Parameter.KEYWORD_ONLY:
#             kwonly_args.append(name)
# 
#     @wraps(f)
#     def inner_f(*args, **kwargs):
#         extra_args = len(args) - len(all_args)
#         if extra_args > 0:
#             plural = "s" if extra_args > 1 else ""
#             article = "" if plural else "a "
#             warnings.warn(
#                 "Pass the following variable{} as {}keyword arg{}: {}. "
#                 "From version 0.12, the only valid positional argument "
#                 "will be `data`, and passing other arguments without an "
#                 "explicit keyword will result in an error or misinterpretation."
#                 .format(plural, article, plural,
#                         ", ".join(kwonly_args[:extra_args])),
#                 FutureWarning
#             )
#         kwargs.update({k: arg for k, arg in zip(sig.parameters, args)})
#         return f(**kwargs)
#     return inner_f
# 
# def share_init_params_with_map(cls):
#     """Make cls.map a classmethod with same signature as cls.__init__."""
#     map_sig = signature(cls.map)
#     init_sig = signature(cls.__init__)
# 
#     new = [v for k, v in init_sig.parameters.items() if k != "self"]
#     new.insert(0, map_sig.parameters["cls"])
#     cls.map.__signature__ = map_sig.replace(parameters=new)
#     cls.map.__doc__ = cls.__init__.__doc__
# 
#     cls.map = classmethod(cls.map)
# 
#     return cls


# Path: seaborn/tests/test_decorators.py
import inspect
import pytest
from .._decorators import (
    _deprecate_positional_args,
    share_init_params_with_map,
)

# github.com/scikit-learn/scikit-learn/blob/master/sklearn/utils/tests/test_validation.py
def test_deprecate_positional_args_warns_for_function():

    @_deprecate_positional_args
    def f1(a, b, *, c=1, d=1):
        return a, b, c, d

    with pytest.warns(
        FutureWarning,
        match=r"Pass the following variable as a keyword arg: c\."
    ):
        assert f1(1, 2, 3) == (1, 2, 3, 1)

    with pytest.warns(
        FutureWarning,
        match=r"Pass the following variables as keyword args: c, d\."
    ):
        assert f1(1, 2, 3, 4) == (1, 2, 3, 4)

    @_deprecate_positional_args
    def f2(a=1, *, b=1, c=1, d=1):
        return a, b, c, d

    with pytest.warns(
        FutureWarning,
        match=r"Pass the following variable as a keyword arg: b\.",
    ):
        assert f2(1, 2) == (1, 2, 1, 1)

    # The * is placed before a keyword only argument without a default value

    @_deprecate_positional_args