7

I'm using pybind11 to wrap a C++ class method in a conversion lambda "shim" (I must do this because reasons). One of the method's arguments is defaulted in C++.

class A
{
   void meow(Eigen::Matrix4f optMat = Eigen::Matrix4f::Identity());
};

In my pybind code I want to preserve this optional parameter:

py::class_<A>(m, "A")
       .def(py::init<>())
       .def("meow",
            [](A& self, Eigen::Matrix4f optMat = Eigen::Matrix4f::Identity()) 
            {
               return self.meow( optMat ); 
            });

How do I make optMat an optional named argument in the generated Python code?

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
  • Yes, I've seen the docs, it is unclear how to apply them to the lambda, since the lambda arguments are _not_ instantiations (of a `py:arg` object) but type declarations. – Adi Shavit Jul 29 '19 at 07:33

1 Answers1

12

Just add them after the lambda:

py::class_<A>(m, "A")
    .def(py::init<>())
    .def("meow",
         [](A& self, Eigen::Matrix4f optMat) {
             return self.meow(optMat); 
         },
         py::arg("optMat") = Eigen::Matrix4f::Identity());
Mika Fischer
  • 4,058
  • 1
  • 26
  • 28
  • Hi, will default argument `= Eigen::Matrix4f::Identity()` been called every time the python API is called ? Or it's been called only once when python module been loaded ? – linrongbin Jan 06 '22 at 08:23
  • @linrongbin Sorry for the late reply, but it's the latter. All the code above will only be executed once on module load. The default argument will be computed and stored in the python function object and later used as needed. – Mika Fischer Aug 02 '22 at 21:19