@@ -174,6 +174,25 @@ struct DispatchIssue : Base {
174
174
}
175
175
};
176
176
177
+ // An abstract adder class that uses visitor pattern to add two data
178
+ // objects and send the result to the visitor functor
179
+ struct AdderBase {
180
+ struct Data {};
181
+ using DataVisitor = std::function<void (const Data&)>;
182
+
183
+ virtual void operator ()(const Data& first, const Data& second, const DataVisitor& visitor) const = 0;
184
+ virtual ~AdderBase () = default ;
185
+ AdderBase () = default ;
186
+ AdderBase (const AdderBase&) = delete ;
187
+ };
188
+
189
+ struct Adder : AdderBase {
190
+ void operator ()(const Data& first, const Data& second, const DataVisitor& visitor) const override {
191
+ PYBIND11_OVERRIDE_PURE_NAME (void , AdderBase, " __call__" , operator (), first, second, visitor);
192
+ }
193
+ };
194
+
195
+
177
196
static void test_gil () {
178
197
{
179
198
py::gil_scoped_acquire lock;
@@ -295,6 +314,27 @@ TEST_SUBMODULE(virtual_functions, m) {
295
314
296
315
m.def (" dispatch_issue_go" , [](const Base * b) { return b->dispatch (); });
297
316
317
+ // test_recursive_dispatch_issue
318
+ // #3357: Recursive dispatch fails to find python function override
319
+ pybind11::class_<AdderBase, Adder>(m, " Adder" )
320
+ .def (pybind11::init<>())
321
+ .def (" __call__" , &AdderBase::operator ());
322
+
323
+ pybind11::class_<AdderBase::Data>(m, " Data" )
324
+ .def (pybind11::init<>());
325
+
326
+ m.def (" add2" , [](const AdderBase::Data& first, const AdderBase::Data& second,
327
+ const AdderBase& adder, const AdderBase::DataVisitor& visitor) {
328
+ adder (first, second, visitor);
329
+ });
330
+
331
+ m.def (" add3" , [](const AdderBase::Data& first, const AdderBase::Data& second, const AdderBase::Data& third,
332
+ const AdderBase& adder, const AdderBase::DataVisitor& visitor) {
333
+ adder (first, second, [&] (const AdderBase::Data& first_plus_second) {
334
+ adder (first_plus_second, third, visitor);
335
+ });
336
+ });
337
+
298
338
// test_override_ref
299
339
// #392/397: overriding reference-returning functions
300
340
class OverrideTest {
0 commit comments