Skip to content

Commit caa1379

Browse files
jagermanwjakob
authored andcommitted
Make bad kwarg arguments try next overload
Fixes #688. My (commented) assumption that such an error is "highly likely to be a caller mistake" was proven false by #688.
1 parent 60d0e0d commit caa1379

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

include/pybind11/pybind11.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -444,21 +444,19 @@ class cpp_function : public function {
444444
size_t args_copied = 0;
445445

446446
// 1. Copy any position arguments given.
447+
bool bad_kwarg = false;
447448
for (; args_copied < args_to_copy; ++args_copied) {
448-
// If we find a given positional argument that also has a named kwargs argument,
449-
// raise a TypeError like Python does. (We could also continue with the next
450-
// overload, but this seems highly likely to be a caller mistake rather than a
451-
// legitimate overload).
452-
if (kwargs_in && args_copied < func.args.size() && func.args[args_copied].name) {
453-
handle value = PyDict_GetItemString(kwargs_in, func.args[args_copied].name);
454-
if (value)
455-
throw type_error(std::string(func.name) + "(): got multiple values for argument '" +
456-
std::string(func.args[args_copied].name) + "'");
449+
if (kwargs_in && args_copied < func.args.size() && func.args[args_copied].name
450+
&& PyDict_GetItemString(kwargs_in, func.args[args_copied].name)) {
451+
bad_kwarg = true;
452+
break;
457453
}
458454

459455
call.args.push_back(PyTuple_GET_ITEM(args_in, args_copied));
460456
call.args_convert.push_back(args_copied < func.args.size() ? func.args[args_copied].convert : true);
461457
}
458+
if (bad_kwarg)
459+
continue; // Maybe it was meant for another overload (issue #688)
462460

463461
// We'll need to copy this if we steal some kwargs for defaults
464462
dict kwargs = reinterpret_borrow<dict>(kwargs_in);

0 commit comments

Comments
 (0)