diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index c428e3f13a..4203dccfbc 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -2191,7 +2191,20 @@ unpacking_collector collect_arguments(Args &&...args) { template template object object_api::operator()(Args &&...args) const { - return detail::collect_arguments(std::forward(args)...).call(derived().ptr()); + if constexpr(all_of...>::value) + // Collect only positional arguments for a Python function call + return simple_collector(std::forward(args)...).call(derived().ptr()); + else { + // Following argument order rules for generalized unpacking according to PEP 448 + static_assert( + constexpr_last() < constexpr_first() + && constexpr_last() < constexpr_first(), + "Invalid function call: positional args must precede keywords and ** unpacking; " + "* unpacking must precede ** unpacking" + ); + // Collect all arguments, including keywords and unpacking (only instantiated when needed) + return unpacking_collector(std::forward(args)...).call(derived().ptr()); + } } template