pybind11
pybind11 copied to clipboard
[BUG]: Incompatible function arguments when using py::function with default parameter
Required prerequisites
- [X] Make sure you've read the documentation. Your issue may be addressed there.
- [X] Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- [ ] Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
2.11.1
Problem description
When setting up a function that takes a py::function
as an input argument AND which lets that argument default to nullptr
or py::none()
, that function cannot be used from Python with default arguments.
The workaround is to use py::object
and just work with it as if it were a py::function
.
A similar issue was reported previously in https://github.com/pybind/pybind11/issues/3205, but for some reason that issue was closed. It's worth noting that in my code example I set the default argument to nullptr
but we see the same behavior if the default argument is py::none()
. If the default argument is py::object()
or py::function()
then you get the issue reported in #3205, namely that we cannot even import the function because we get the error "cannot convert default argument in func2 into a Python object (type not registered yet?)"
Reproducible example code
#include <pybind11/pybind11.h>
namespace py = pybind11;
using namespace pybind11::literals;
PYBIND11_MODULE(example, m) {
m.def("func1", [](py::object func_to_call){}, "docstring", "func_to_call"_a=nullptr);
m.def("func2", [](py::function func_to_call){}, "docstring", "func_to_call"_a=nullptr);
/*Python:
from example import func1, func2
func1(lambda x: x) # works
func1() # works
func2(lambda x: x) # works
func2() # incompatible argument error
*/
}
Is this a regression? Put the last known working version here if it is.
Not a regression