Skip to content

Commit b4ca366

Browse files
committed
Switch to a bool vec for the used_kwargs flag...
This makes more sense and saves a sort, and the small_vector implementation means it will actually take less space than a vector of size_t elements. The most common case is that all kwargs are used.
1 parent b517942 commit b4ca366

1 file changed

Lines changed: 8 additions & 15 deletions

File tree

include/pybind11/pybind11.h

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,10 +1007,9 @@ class cpp_function : public function {
10071007
}
10081008

10091009
// 2. Check kwargs and, failing that, defaults that may help complete the list
1010-
small_vector<size_t, arg_vector_small_size> used_kwargs;
1011-
if (kwnames_in) {
1012-
used_kwargs.reserve(static_cast<size_t>(PyTuple_GET_SIZE(kwnames_in)));
1013-
}
1010+
small_vector<bool, arg_vector_small_size> used_kwargs(
1011+
kwnames_in ? PyTuple_GET_SIZE(kwnames_in) : 0, false);
1012+
size_t used_kwargs_count = 0;
10141013
if (args_copied < num_args) {
10151014
for (; args_copied < num_args; ++args_copied) {
10161015
const auto &arg_rec = func.args[args_copied];
@@ -1020,7 +1019,8 @@ class cpp_function : public function {
10201019
ssize_t i = keyword_index(kwnames_in, arg_rec.name);
10211020
if (i >= 0) {
10221021
value = args_in_arr[n_args_in + static_cast<size_t>(i)];
1023-
used_kwargs.emplace_back(static_cast<size_t>(i));
1022+
used_kwargs.set(i, true);
1023+
used_kwargs_count++;
10241024
}
10251025
}
10261026

@@ -1052,8 +1052,7 @@ class cpp_function : public function {
10521052
}
10531053

10541054
// 3. Check everything was consumed (unless we have a kwargs arg)
1055-
if (!func.has_kwargs && kwnames_in
1056-
&& PyTuple_GET_SIZE(kwnames_in) > static_cast<ssize_t>(used_kwargs.size())) {
1055+
if (!func.has_kwargs && used_kwargs_count < used_kwargs.size()) {
10571056
continue; // Unconsumed kwargs, but no py::kwargs argument to accept them
10581057
}
10591058

@@ -1080,14 +1079,8 @@ class cpp_function : public function {
10801079
// 4b. If we have a py::kwargs, pass on any remaining kwargs
10811080
if (func.has_kwargs) {
10821081
dict kwargs;
1083-
size_t used_i = 0;
1084-
size_t name_count
1085-
= kwnames_in ? static_cast<size_t>(PyTuple_GET_SIZE(kwnames_in)) : 0;
1086-
used_kwargs.sort();
1087-
for (size_t i = 0; i < name_count; ++i) {
1088-
if (used_i < used_kwargs.size() && used_kwargs[used_i] == i) {
1089-
++used_i;
1090-
} else {
1082+
for (size_t i = 0; i < used_kwargs.size(); ++i) {
1083+
if (!used_kwargs[i]) {
10911084
kwargs[PyTuple_GET_ITEM(kwnames_in, i)] = args_in_arr[n_args_in + i];
10921085
}
10931086
}

0 commit comments

Comments
 (0)