nicer error message for invalid function arguments

This commit is contained in:
Wenzel Jakob 2016-09-12 11:44:37 +09:00
parent b3794f1087
commit e99ebaedcf
6 changed files with 24 additions and 16 deletions

View File

@ -460,8 +460,10 @@ protected:
if (overloads->is_operator) if (overloads->is_operator)
return handle(Py_NotImplemented).inc_ref().ptr(); return handle(Py_NotImplemented).inc_ref().ptr();
std::string msg = "Incompatible " + std::string(overloads->is_constructor ? "constructor" : "function") + std::string msg = std::string(overloads->name) + "(): incompatible " +
" arguments. The following argument types are supported:\n"; std::string(overloads->is_constructor ? "constructor" : "function") +
" arguments. The following argument types are supported:\n";
int ctr = 0; int ctr = 0;
for (detail::function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) { for (detail::function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) {
msg += " "+ std::to_string(++ctr) + ". "; msg += " "+ std::to_string(++ctr) + ". ";
@ -489,7 +491,7 @@ protected:
msg += "\n"; msg += "\n";
} }
msg += " Invoked with: "; msg += "\nInvoked with: ";
tuple args_(args, true); tuple args_(args, true);
for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) { for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) {
msg += static_cast<std::string>(static_cast<object>(args_[ti]).str()); msg += static_cast<std::string>(static_cast<object>(args_[ti]).str());

View File

@ -83,7 +83,7 @@ def test_cpp_function_roundtrip():
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
test_dummy_function(dummy_function2) test_dummy_function(dummy_function2)
assert "Incompatible function arguments" in str(excinfo.value) assert "incompatible function arguments" in str(excinfo.value)
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
test_dummy_function(lambda x, y: x + y) test_dummy_function(lambda x, y: x + y)

View File

@ -24,9 +24,10 @@ def test_inheritance(msg):
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
dog_bark(polly) dog_bark(polly)
assert msg(excinfo.value) == """ assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported: dog_bark(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.Dog) -> str 1. (arg0: m.Dog) -> str
Invoked with: <m.Pet object at 0>
Invoked with: <m.Pet object at 0>
""" """

View File

@ -65,17 +65,19 @@ def test_no_id(capture, msg):
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
get_element(None) get_element(None)
assert msg(excinfo.value) == """ assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported: get_element(): incompatible function arguments. The following argument types are supported:
1. (arg0: m.issues.ElementA) -> int 1. (arg0: m.issues.ElementA) -> int
Invoked with: None
Invoked with: None
""" """
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
expect_int(5.2) expect_int(5.2)
assert msg(excinfo.value) == """ assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported: expect_int(): incompatible function arguments. The following argument types are supported:
1. (arg0: int) -> int 1. (arg0: int) -> int
Invoked with: 5.2
Invoked with: 5.2
""" """
assert expect_float(12) == 12 assert expect_float(12) == 12
@ -90,10 +92,11 @@ def test_str_issue(msg):
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
str(StrIssue("no", "such", "constructor")) str(StrIssue("no", "such", "constructor"))
assert msg(excinfo.value) == """ assert msg(excinfo.value) == """
Incompatible constructor arguments. The following argument types are supported: __init__(): incompatible constructor arguments. The following argument types are supported:
1. m.issues.StrIssue(arg0: int) 1. m.issues.StrIssue(arg0: int)
2. m.issues.StrIssue() 2. m.issues.StrIssue()
Invoked with: no, such, constructor
Invoked with: no, such, constructor
""" """

View File

@ -35,9 +35,10 @@ def test_named_arguments(msg):
# noinspection PyArgumentList # noinspection PyArgumentList
kw_func2(x=5, y=10, z=12) kw_func2(x=5, y=10, z=12)
assert msg(excinfo.value) == """ assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported: kw_func2(): incompatible function arguments. The following argument types are supported:
1. (x: int=100, y: int=200) -> str 1. (x: int=100, y: int=200) -> str
Invoked with:
Invoked with:
""" """
assert kw_func4() == "{13 17}" assert kw_func4() == "{13 17}"

View File

@ -35,9 +35,10 @@ def test_pointers(msg):
with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo:
get_void_ptr_value([1, 2, 3]) # This should not work get_void_ptr_value([1, 2, 3]) # This should not work
assert msg(excinfo.value) == """ assert msg(excinfo.value) == """
Incompatible function arguments. The following argument types are supported: get_void_ptr_value(): incompatible function arguments. The following argument types are supported:
1. (arg0: capsule) -> int 1. (arg0: capsule) -> int
Invoked with: [1, 2, 3]
Invoked with: [1, 2, 3]
""" """
assert return_null_str() is None assert return_null_str() is None