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_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
        '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),