def test_without_parameters():
    sig = Signature([Parameter('foo'), Parameter('bar'), Parameter('baz')])

    expected = Signature([Parameter('bar')])

    result = sig.without_parameters(0, 'baz')
    assert result == expected
def test_replace():
    sig = Signature([Parameter('foo')], return_annotation=int)

    expected = Signature(return_annotation=str)

    result = sig.replace(parameters=[], return_annotation=str)
    assert isinstance(result, Signature)
    assert result == expected
def test_get_float_signature():
    sig = Signature.from_callable(float)
    assert sig.return_annotation is float
    assert len(sig.parameters) == 1
    assert list(sig.parameters) == ['x']
    assert sig.parameters['x'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['x'].default in {0, Parameter.missing}
def test_signature_with_optional_parameter():
    sig = Signature.from_callable(vars)

    assert sig.return_annotation is dict
    assert len(sig.parameters) == 1
    assert sig.parameters['object'].annotation is typing.Any
    assert sig.parameters['object'].default is Parameter.missing
def test_get_missing_parameter_names_with_optionals(func, args, kwargs,
                                                    expected):
    bound_args = Signature.from_callable(func).bind_partial(*args, **kwargs)

    result = bound_args.get_missing_parameter_names(
        include_optional_parameters=True)
    assert result == expected
def test_get_bool_signature():
    sig = Signature.from_callable(bool)
    assert sig.return_annotation is bool
    assert len(sig.parameters) == 1
    assert list(sig.parameters) == ['x']
    assert sig.parameters['x'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['x'].default is Parameter.missing
def test_num_required_arguments():
    sig = Signature([
        Parameter('a', Parameter.POSITIONAL_ONLY),
        Parameter('b', Parameter.VAR_POSITIONAL),
        Parameter('c', Parameter.KEYWORD_ONLY),
        Parameter('d', Parameter.VAR_KEYWORD)
    ])

    assert sig.num_required_arguments == 2
def test_get_int_signature():
    sig = Signature.from_callable(int)
    assert sig.return_annotation is int
    assert len(sig.parameters) == 2
    assert list(sig.parameters) == ['x', 'base']
    assert sig.parameters['x'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['x'].default in {0, Parameter.missing}
    assert sig.parameters['base'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['base'].default in {10, Parameter.missing}
def test_to_varargs_prefer_kwargs(func, args, kwargs, expected_args,
                                  expected_kwargs):
    sig = Signature.from_callable(func)
    bound_args = sig.bind_partial(*args, **kwargs)

    args, kwargs = bound_args.to_varargs(prefer='kwargs')

    assert args == expected_args
    assert kwargs == expected_kwargs
def test_store_signature():
    def foo(a=5) -> str:
        return 'bar'

    sig = Signature.from_callable(foo)
    foo.__signature__ = sig

    s = inspect.signature(foo)
    assert s is sig
def test_builtin_signatures():
    import builtins

    for thing in vars(builtins).values():
        if not callable(thing):
            continue

        try:
            _ = Signature.from_callable(thing)
        except Exception as e:
            msg = "Couldn't obtain signature of {!r}: {!r}"
            pytest.fail(msg.format(thing, e))
def test_get_signature():
    def foo(a, b=3) -> str:
        pass

    sig = Signature.from_callable(foo)
    assert sig.return_annotation is str
    assert len(sig.parameters) == 2
    assert list(sig.parameters) == ['a', 'b']
    assert sig.parameters['a'].kind == Parameter.POSITIONAL_OR_KEYWORD
    assert sig.parameters['a'].default == Parameter.empty
    assert sig.parameters['b'].kind == Parameter.POSITIONAL_OR_KEYWORD
    assert sig.parameters['b'].default == 3
def test_method_signature():
    class A:
        def method(self, foo: int = 3) -> None:
            pass

    class B(A):
        def method(self, *args, bar: bool = True, **kwargs):
            return super().method(*args, **kwargs)

    sig = Signature.for_method(B, 'method')
    assert list(sig.parameters) == ['self', 'foo', 'bar']
    assert sig.return_annotation is None
    assert sig.parameters['foo'].annotation is int
    assert sig.parameters['foo'].default == 3
    assert sig.parameters['foo'].kind is Parameter.POSITIONAL_OR_KEYWORD
    assert sig.parameters['bar'].annotation is bool
    assert sig.parameters['bar'].default is True
    assert sig.parameters['bar'].kind is Parameter.KEYWORD_ONLY
def test_get_signature_undoc_c_function(monkeypatch):
    fake_func = make_fake_c_function(None, monkeypatch)

    with pytest.raises(ValueError):
        Signature.from_callable(fake_func)
def test_get_missing_parameter_names(func, args, kwargs, expected):
    bound_args = Signature.from_callable(func).bind_partial(*args, **kwargs)

    assert bound_args.get_missing_parameter_names() == expected
def test_setitem():
    bound_args = Signature.from_callable(lambda x: x).bind(3)

    bound_args['x'] = 17
    assert bound_args['x'] == 17
def test_getitem_keyerror():
    bound_args = Signature.from_callable(lambda x: x).bind(3)

    with pytest.raises(KeyError):
        bound_args['y']
def test_len():
    bound_args = Signature.from_callable(lambda x, y: x).bind_partial(3)

    assert len(bound_args) == 1
def test_bind_partial(func, args, kwargs, expected_result):
    sig = Signature.from_callable(func)
    assert sig.bind_partial(*args, **kwargs).arguments == expected_result
def test_get_signature_noncallable():
    with pytest.raises(TypeError):
        Signature.from_callable(3)
def test_to_varargs_invalid_prefer_arg():
    bound_args = Signature.from_callable(lambda x: x).bind(3)

    with pytest.raises(ValueError):
        bound_args.to_varargs(prefer='foobar')
def test_iter():
    bound_args = Signature.from_callable(lambda x, y, z: x).bind_partial(3, 4)

    assert tuple(bound_args) == ('x', 'y')
        'd': 'D'
    }, {
        'a': ('A', 'B'),
        'c': {
            'd': 'D'
        }
    }),
])
def test_bind_partial(func, args, kwargs, expected_result):
    sig = Signature.from_callable(func)
    assert sig.bind_partial(*args, **kwargs).arguments == expected_result


@pytest.mark.parametrize('signature, expected', [
    (Signature([
        Parameter('a', Parameter.POSITIONAL_ONLY),
        Parameter('b', Parameter.VAR_POSITIONAL)
    ]), '(a, /, *b)'),
    (Signature([
        Parameter('a', Parameter.POSITIONAL_ONLY),
        Parameter('b', Parameter.POSITIONAL_ONLY)
    ]), '(a, b, /)'),
    (Signature([Parameter('a', default=Parameter.missing)]), '([a])'),
    (Signature([
        Parameter('a', Parameter.POSITIONAL_ONLY, default=Parameter.missing)
    ]), '([a], /)'),
    (Signature([
        Parameter('a', Parameter.POSITIONAL_ONLY, default=Parameter.missing),
        Parameter('b', default=Parameter.missing)
    ]), '([a], /[, b])'),
    (Signature([
        Parameter('a', Parameter.POSITIONAL_ONLY, default=Parameter.missing),