def test_cpp_function_roundtrip():
    """Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer"""
    from pybind11_tests import dummy_function, dummy_function2, test_dummy_function, roundtrip

    if test_dummy_function(
            dummy_function) != "matches dummy_function: eval(1) = 2":
        raise AssertionError
    if test_dummy_function(roundtrip(
            dummy_function)) != "matches dummy_function: eval(1) = 2":
        raise AssertionError
    if roundtrip(None, expect_none=True) is not None:
        raise AssertionError
    if test_dummy_function(
            lambda x: x + 2
    ) != "can't convert to function pointer: eval(1) = 3":
        raise AssertionError

    with pytest.raises(TypeError) as excinfo:
        test_dummy_function(dummy_function2)
    if "incompatible function arguments" not in str(excinfo.value):
        raise AssertionError

    with pytest.raises(TypeError) as excinfo:
        test_dummy_function(lambda x, y: x + y)
    if not any(s in str(excinfo.value)
               for s in ("missing 1 required positional argument",
                         "takes exactly 2 arguments")):
        raise AssertionError
def test_cpp_function_roundtrip():
    """Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer"""
    from pybind11_tests import dummy_function, dummy_function2, test_dummy_function, roundtrip

    assert test_dummy_function(dummy_function) == "matches dummy_function: eval(1) = 2"
    assert test_dummy_function(roundtrip(dummy_function)) == "matches dummy_function: eval(1) = 2"
    assert roundtrip(None, expect_none=True) is None
    assert test_dummy_function(lambda x: x + 2) == "can't convert to function pointer: eval(1) = 3"

    with pytest.raises(TypeError) as excinfo:
        test_dummy_function(dummy_function2)
    assert "incompatible function arguments" in str(excinfo.value)

    with pytest.raises(TypeError) as excinfo:
        test_dummy_function(lambda x, y: x + y)
    assert any(s in str(excinfo.value) for s in ("missing 1 required positional argument",
                                                 "takes exactly 2 arguments"))