diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index c518169c4..1010ae3e8 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1802,6 +1802,10 @@ struct function_call { /// The `convert` value the arguments should be loaded with std::vector args_convert; + /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if + /// present, are also in `args` but without a reference). + object args_ref, kwargs_ref; + /// The parent, if any handle parent; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index c8bab7703..6cedcc262 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -576,8 +576,8 @@ protected: continue; // Unconsumed kwargs, but no py::kwargs argument to accept them // 4a. If we have a py::args argument, create a new tuple with leftovers - tuple extra_args; if (func.has_args) { + tuple extra_args; if (args_to_copy == 0) { // We didn't copy out any position arguments from the args_in tuple, so we // can reuse it directly without copying: @@ -594,6 +594,7 @@ protected: } call.args.push_back(extra_args); call.args_convert.push_back(false); + call.args_ref = std::move(extra_args); } // 4b. If we have a py::kwargs, pass on any remaining kwargs @@ -602,6 +603,7 @@ protected: kwargs = dict(); // If we didn't get one, send an empty one call.args.push_back(kwargs); call.args_convert.push_back(false); + call.kwargs_ref = std::move(kwargs); } // 5. Put everything in a vector. Not technically step 5, we've been building it