def test_inspect_arguments_case_no_params_no_args():
    """
    Test `inspect_arguments`.
    """

    # Create function
    def func():
        pass

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[],
        kwargs={},
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == []
    assert info.kwdonly_param_names == []
    assert info.varpos_param_name is None
    assert info.varkwd_param_name is None
    assert info.fixed_arg_infos == {}
    assert info.varpos_arg_infos == []
    assert info.varkwd_arg_infos == {}
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}
def test_inspect_arguments_case_varkwd_param_kwd_args():
    """
    Test `inspect_arguments`.
    """

    # Create function
    def func(**var_kwargs):
        pass

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[],
        kwargs=dict(a=1, b=2),
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == []
    assert info.kwdonly_param_names == []
    assert info.varpos_param_name is None
    assert info.varkwd_param_name == 'var_kwargs'
    assert info.fixed_arg_infos == {}
    assert info.varpos_arg_infos == []

    #
    assert set(info.varkwd_arg_infos.keys()) == set(['a', 'b'])

    #
    arg_info = info.varkwd_arg_infos['a']

    #
    assert arg_info.name == 'a'
    assert arg_info.value == 1
    assert arg_info.type == ArgumentType.VAR_KEYWORD
    assert arg_info.pos_index is None
    assert arg_info.varpos_index is None
    assert arg_info.param_type == ParameterType.VAR_KEYWORD

    #
    arg_info = info.varkwd_arg_infos['b']

    #
    assert arg_info.name == 'b'
    assert arg_info.value == 2
    assert arg_info.type == ArgumentType.VAR_KEYWORD
    assert arg_info.pos_index is None
    assert arg_info.varpos_index is None
    assert arg_info.param_type == ParameterType.VAR_KEYWORD

    #
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}
def test_inspect_arguments_case_varpos_param_pos_args():
    """
    Test `inspect_arguments`.
    """

    # Create function
    def func(*var_args):
        pass

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[1, 2],
        kwargs={},
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == []
    assert info.kwdonly_param_names == []
    assert info.varpos_param_name == 'var_args'
    assert info.varkwd_param_name is None
    assert info.fixed_arg_infos == {}

    #
    assert len(info.varpos_arg_infos) == 2

    #
    arg_info = info.varpos_arg_infos[0]

    #
    assert arg_info.name is None
    assert arg_info.value == 1
    assert arg_info.type == ArgumentType.VAR_POSITIONAL
    assert arg_info.pos_index is None
    assert arg_info.varpos_index == 0
    assert arg_info.param_type == ParameterType.VAR_POSITIONAL

    #
    arg_info = info.varpos_arg_infos[1]

    #
    assert arg_info.name is None
    assert arg_info.value == 2
    assert arg_info.type == ArgumentType.VAR_POSITIONAL
    assert arg_info.pos_index is None
    assert arg_info.varpos_index == 1
    assert arg_info.param_type == ParameterType.VAR_POSITIONAL

    #
    assert info.varkwd_arg_infos == {}
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}
def test_inspect_arguments_case_no_params_pos_args():
    """
    Test `inspect_arguments`.
    """

    # Create function
    def func():
        pass

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[0],
        kwargs={},
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == []
    assert info.kwdonly_param_names == []
    assert info.varpos_param_name is None
    assert info.varkwd_param_name is None
    assert info.fixed_arg_infos == {}

    #
    assert len(info.varpos_arg_infos) == 1

    #
    arg_info = info.varpos_arg_infos[0]

    #
    assert arg_info.name is None
    assert arg_info.type == ArgumentType.VAR_POSITIONAL

    # This is because the function has no variable-positional parameter
    assert arg_info.param_type is None

    #
    assert info.varkwd_arg_infos == {}
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}
def test_inspect_arguments_case_no_params_kwd_args():
    """
    Test `inspect_arguments`.
    """

    # Create function
    def func():
        pass

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[],
        kwargs=dict(a=1, ),
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == []
    assert info.kwdonly_param_names == []
    assert info.varpos_param_name is None
    assert info.varkwd_param_name is None
    assert info.fixed_arg_infos == {}
    assert info.varpos_arg_infos == []

    #
    assert len(info.varkwd_arg_infos) == 1

    #
    arg_info = info.varkwd_arg_infos['a']

    #
    assert arg_info.name == 'a'
    assert arg_info.type == ArgumentType.VAR_KEYWORD

    # This is because the function has no variable-keyword parameter
    assert arg_info.param_type is None

    #
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}
def test_inspect_arguments_case_poskwd_param_dft_args():
    """
    Test `inspect_arguments`.
    """

    # Create function
    def func(a=1):
        pass

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[],
        kwargs={},
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == ['a']
    assert info.kwdonly_param_names == []
    assert info.varpos_param_name is None
    assert info.varkwd_param_name is None
    assert list(info.fixed_arg_infos.keys()) == ['a']

    #
    arg_info = info.fixed_arg_infos['a']

    #
    assert arg_info.name == 'a'
    assert arg_info.type == ArgumentType.DEFAULT
    assert arg_info.value == 1
    assert arg_info.pos_index is None
    assert arg_info.varpos_index is None
    assert arg_info.param_type == ParameterType.POSITIONAL_OR_KEYWORD

    #
    assert info.varpos_arg_infos == []
    assert info.varkwd_arg_infos == {}
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}
def test_inspect_arguments_case_kwdonly_params_kwd_args():
    """
    Test `inspect_arguments`.
    """
    # If is Python 2.
    # Python 2 has no keyword-only parameters.
    if IS_PY2:
        # Ignore
        return

    # Create function.
    # The keyword-only parameter syntax will cause syntax error in Python 2.
    # Use exec to avoid the syntax error.
    py3_only_code = r"""
def func(*, a=1, b=2):
    pass
"""

    # `exec`'s context dict
    context_dict = {}

    # Execute code in the context
    exec(py3_only_code, context_dict, context_dict)

    # Get function
    func = context_dict['func']

    # Inspect function arguments
    info = inspect_arguments(
        func=func,
        args=[],
        kwargs=dict(
            a=100,
            b=200,
        ),
    )

    # Check inspect info
    check_inspect_info(info)

    #
    assert info.poskwd_param_names == []
    assert info.kwdonly_param_names == ['a', 'b']
    assert info.varpos_param_name is None
    assert info.varkwd_param_name is None

    #
    assert list(info.fixed_arg_infos.keys()) == ['a', 'b']

    #
    arg_info = info.fixed_arg_infos['a']

    #
    assert arg_info.name == 'a'
    assert arg_info.value == 100
    assert arg_info.type == ArgumentType.KEYWORD_ONLY
    assert arg_info.pos_index is None
    assert arg_info.varpos_index is None
    assert arg_info.param_type == ParameterType.KEYWORD_ONLY

    #
    arg_info = info.fixed_arg_infos['b']

    #
    assert arg_info.name == 'b'
    assert arg_info.value == 200
    assert arg_info.type == ArgumentType.KEYWORD_ONLY
    assert arg_info.pos_index is None
    assert arg_info.varpos_index is None
    assert arg_info.param_type == ParameterType.KEYWORD_ONLY

    #
    assert info.varpos_arg_infos == []
    assert info.varkwd_arg_infos == {}
    assert info.dupkwd_arg_infos == {}
    assert info.missing_arg_infos == {}