Scarab  2.8.1
Project 8 C++ Utility Library
test_virtual_functions.cpp
Go to the documentation of this file.
1 /*
2  tests/test_virtual_functions.cpp -- overriding virtual functions from Python
3 
4  Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
5 
6  All rights reserved. Use of this source code is governed by a
7  BSD-style license that can be found in the LICENSE file.
8 */
9 
10 #include "pybind11_tests.h"
11 #include "constructor_stats.h"
12 #include <pybind11/functional.h>
13 #include <thread>
14 
15 /* This is an example class that we'll want to be able to extend from Python */
16 class ExampleVirt {
17 public:
18  ExampleVirt(int state) : state(state) { print_created(this, state); }
20  ExampleVirt(ExampleVirt &&e) : state(e.state) { print_move_created(this); e.state = 0; }
21  virtual ~ExampleVirt() { print_destroyed(this); }
22 
23  virtual int run(int value) {
24  py::print("Original implementation of "
25  "ExampleVirt::run(state={}, value={}, str1={}, str2={})"_s.format(state, value, get_string1(), *get_string2()));
26  return state + value;
27  }
28 
29  virtual bool run_bool() = 0;
30  virtual void pure_virtual() = 0;
31 
32  // Returning a reference/pointer to a type converted from python (numbers, strings, etc.) is a
33  // bit trickier, because the actual int& or std::string& or whatever only exists temporarily, so
34  // we have to handle it specially in the trampoline class (see below).
35  virtual const std::string &get_string1() { return str1; }
36  virtual const std::string *get_string2() { return &str2; }
37 
38 private:
39  int state;
40  const std::string str1{"default1"}, str2{"default2"};
41 };
42 
43 /* This is a wrapper class that must be generated */
44 class PyExampleVirt : public ExampleVirt {
45 public:
46  using ExampleVirt::ExampleVirt; /* Inherit constructors */
47 
48  int run(int value) override {
49  /* Generate wrapping code that enables native function overloading */
51  int, /* Return type */
52  ExampleVirt, /* Parent class */
53  run, /* Name of function */
54  value /* Argument(s) */
55  );
56  }
57 
58  bool run_bool() override {
60  bool, /* Return type */
61  ExampleVirt, /* Parent class */
62  run_bool, /* Name of function */
63  /* This function has no arguments. The trailing comma
64  in the previous line is needed for some compilers */
65  );
66  }
67 
68  void pure_virtual() override {
70  void, /* Return type */
71  ExampleVirt, /* Parent class */
72  pure_virtual, /* Name of function */
73  /* This function has no arguments. The trailing comma
74  in the previous line is needed for some compilers */
75  );
76  }
77 
78  // We can return reference types for compatibility with C++ virtual interfaces that do so, but
79  // note they have some significant limitations (see the documentation).
80  const std::string &get_string1() override {
82  const std::string &, /* Return type */
83  ExampleVirt, /* Parent class */
84  get_string1, /* Name of function */
85  /* (no arguments) */
86  );
87  }
88 
89  const std::string *get_string2() override {
91  const std::string *, /* Return type */
92  ExampleVirt, /* Parent class */
93  get_string2, /* Name of function */
94  /* (no arguments) */
95  );
96  }
97 
98 };
99 
100 class NonCopyable {
101 public:
102  NonCopyable(int a, int b) : value{new int(a*b)} { print_created(this, a, b); }
104  NonCopyable(const NonCopyable &) = delete;
105  NonCopyable() = delete;
106  void operator=(const NonCopyable &) = delete;
107  void operator=(NonCopyable &&) = delete;
108  std::string get_value() const {
109  if (value) return std::to_string(*value); else return "(null)";
110  }
112 
113 private:
114  std::unique_ptr<int> value;
115 };
116 
117 // This is like the above, but is both copy and movable. In effect this means it should get moved
118 // when it is not referenced elsewhere, but copied if it is still referenced.
119 class Movable {
120 public:
121  Movable(int a, int b) : value{a+b} { print_created(this, a, b); }
122  Movable(const Movable &m) { value = m.value; print_copy_created(this); }
123  Movable(Movable &&m) { value = std::move(m.value); print_move_created(this); }
124  std::string get_value() const { return std::to_string(value); }
126 private:
127  int value;
128 };
129 
130 class NCVirt {
131 public:
132  virtual ~NCVirt() { }
133  virtual NonCopyable get_noncopyable(int a, int b) { return NonCopyable(a, b); }
134  virtual Movable get_movable(int a, int b) = 0;
135 
136  std::string print_nc(int a, int b) { return get_noncopyable(a, b).get_value(); }
137  std::string print_movable(int a, int b) { return get_movable(a, b).get_value(); }
138 };
139 class NCVirtTrampoline : public NCVirt {
140 #if !defined(__INTEL_COMPILER)
141  NonCopyable get_noncopyable(int a, int b) override {
142  PYBIND11_OVERLOAD(NonCopyable, NCVirt, get_noncopyable, a, b);
143  }
144 #endif
145  Movable get_movable(int a, int b) override {
146  PYBIND11_OVERLOAD_PURE(Movable, NCVirt, get_movable, a, b);
147  }
148 };
149 
150 struct Base {
151  /* for some reason MSVC2015 can't compile this if the function is pure virtual */
152  virtual std::string dispatch() const { return {}; };
153  virtual ~Base() = default;
154 };
155 
156 struct DispatchIssue : Base {
157  virtual std::string dispatch() const {
158  PYBIND11_OVERLOAD_PURE(std::string, Base, dispatch, /* no arguments */);
159  }
160 };
161 
162 static void test_gil() {
163  {
165  py::print("1st lock acquired");
166 
167  }
168 
169  {
171  py::print("2nd lock acquired");
172  }
173 
174 }
175 
176 static void test_gil_from_thread() {
178 
179  std::thread t(test_gil);
180  t.join();
181 }
182 
183 
184 // Forward declaration (so that we can put the main tests here; the inherited virtual approaches are
185 // rather long).
187 
189  // test_override
191  .def(py::init<int>())
192  /* Reference original class in function definitions */
193  .def("run", &ExampleVirt::run)
194  .def("run_bool", &ExampleVirt::run_bool)
195  .def("pure_virtual", &ExampleVirt::pure_virtual);
196 
197  py::class_<NonCopyable>(m, "NonCopyable")
198  .def(py::init<int, int>());
199 
200  py::class_<Movable>(m, "Movable")
201  .def(py::init<int, int>());
202 
203  // test_move_support
204 #if !defined(__INTEL_COMPILER)
206  .def(py::init<>())
207  .def("get_noncopyable", &NCVirt::get_noncopyable)
208  .def("get_movable", &NCVirt::get_movable)
209  .def("print_nc", &NCVirt::print_nc)
210  .def("print_movable", &NCVirt::print_movable);
211 #endif
212 
213  m.def("runExampleVirt", [](ExampleVirt *ex, int value) { return ex->run(value); });
214  m.def("runExampleVirtBool", [](ExampleVirt* ex) { return ex->run_bool(); });
215  m.def("runExampleVirtVirtual", [](ExampleVirt *ex) { ex->pure_virtual(); });
216 
217  m.def("cstats_debug", &ConstructorStats::get<ExampleVirt>);
219 
220  // test_alias_delay_initialization1
221  // don't invoke Python dispatch classes by default when instantiating C++ classes
222  // that were not extended on the Python side
223  struct A {
224  virtual ~A() {}
225  virtual void f() { py::print("A.f()"); }
226  };
227 
228  struct PyA : A {
229  PyA() { py::print("PyA.PyA()"); }
230  ~PyA() { py::print("PyA.~PyA()"); }
231 
232  void f() override {
233  py::print("PyA.f()");
234  // This convolution just gives a `void`, but tests that PYBIND11_TYPE() works to protect
235  // a type containing a ,
237  }
238  };
239 
240  py::class_<A, PyA>(m, "A")
241  .def(py::init<>())
242  .def("f", &A::f);
243 
244  m.def("call_f", [](A *a) { a->f(); });
245 
246  // test_alias_delay_initialization2
247  // ... unless we explicitly request it, as in this example:
248  struct A2 {
249  virtual ~A2() {}
250  virtual void f() { py::print("A2.f()"); }
251  };
252 
253  struct PyA2 : A2 {
254  PyA2() { py::print("PyA2.PyA2()"); }
255  ~PyA2() { py::print("PyA2.~PyA2()"); }
256  void f() override {
257  py::print("PyA2.f()");
258  PYBIND11_OVERLOAD(void, A2, f);
259  }
260  };
261 
262  py::class_<A2, PyA2>(m, "A2")
263  .def(py::init_alias<>())
264  .def(py::init([](int) { return new PyA2(); }))
265  .def("f", &A2::f);
266 
267  m.def("call_f", [](A2 *a2) { a2->f(); });
268 
269  // test_dispatch_issue
270  // #159: virtual function dispatch has problems with similar-named functions
271  py::class_<Base, DispatchIssue>(m, "DispatchIssue")
272  .def(py::init<>())
273  .def("dispatch", &Base::dispatch);
274 
275  m.def("dispatch_issue_go", [](const Base * b) { return b->dispatch(); });
276 
277  // test_override_ref
278  // #392/397: overriding reference-returning functions
279  class OverrideTest {
280  public:
281  struct A { std::string value = "hi"; };
282  std::string v;
283  A a;
284  explicit OverrideTest(const std::string &v) : v{v} {}
285  virtual std::string str_value() { return v; }
286  virtual std::string &str_ref() { return v; }
287  virtual A A_value() { return a; }
288  virtual A &A_ref() { return a; }
289  virtual ~OverrideTest() = default;
290  };
291 
292  class PyOverrideTest : public OverrideTest {
293  public:
294  using OverrideTest::OverrideTest;
295  std::string str_value() override { PYBIND11_OVERLOAD(std::string, OverrideTest, str_value); }
296  // Not allowed (uncommenting should hit a static_assert failure): we can't get a reference
297  // to a python numeric value, since we only copy values in the numeric type caster:
298 // std::string &str_ref() override { PYBIND11_OVERLOAD(std::string &, OverrideTest, str_ref); }
299  // But we can work around it like this:
300  private:
301  std::string _tmp;
302  std::string str_ref_helper() { PYBIND11_OVERLOAD(std::string, OverrideTest, str_ref); }
303  public:
304  std::string &str_ref() override { return _tmp = str_ref_helper(); }
305 
306  A A_value() override { PYBIND11_OVERLOAD(A, OverrideTest, A_value); }
307  A &A_ref() override { PYBIND11_OVERLOAD(A &, OverrideTest, A_ref); }
308  };
309 
310  py::class_<OverrideTest::A>(m, "OverrideTest_A")
311  .def_readwrite("value", &OverrideTest::A::value);
313  .def(py::init<const std::string &>())
314  .def("str_value", &OverrideTest::str_value)
315 // .def("str_ref", &OverrideTest::str_ref)
316  .def("A_value", &OverrideTest::A_value)
317  .def("A_ref", &OverrideTest::A_ref);
318 }
319 
320 
321 // Inheriting virtual methods. We do two versions here: the repeat-everything version and the
322 // templated trampoline versions mentioned in docs/advanced.rst.
323 //
324 // These base classes are exactly the same, but we technically need distinct
325 // classes for this example code because we need to be able to bind them
326 // properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to
327 // multiple python classes).
328 class A_Repeat {
329 #define A_METHODS \
330 public: \
331  virtual int unlucky_number() = 0; \
332  virtual std::string say_something(unsigned times) { \
333  std::string s = ""; \
334  for (unsigned i = 0; i < times; ++i) \
335  s += "hi"; \
336  return s; \
337  } \
338  std::string say_everything() { \
339  return say_something(1) + " " + std::to_string(unlucky_number()); \
340  }
342  virtual ~A_Repeat() = default;
343 };
344 class B_Repeat : public A_Repeat {
345 #define B_METHODS \
346 public: \
347  int unlucky_number() override { return 13; } \
348  std::string say_something(unsigned times) override { \
349  return "B says hi " + std::to_string(times) + " times"; \
350  } \
351  virtual double lucky_number() { return 7.0; }
353 };
354 class C_Repeat : public B_Repeat {
355 #define C_METHODS \
356 public: \
357  int unlucky_number() override { return 4444; } \
358  double lucky_number() override { return 888; }
360 };
361 class D_Repeat : public C_Repeat {
362 #define D_METHODS // Nothing overridden.
363 D_METHODS
364 };
365 
366 // Base classes for templated inheritance trampolines. Identical to the repeat-everything version:
367 class A_Tpl { A_METHODS; virtual ~A_Tpl() = default; };
368 class B_Tpl : public A_Tpl { B_METHODS };
369 class C_Tpl : public B_Tpl { C_METHODS };
370 class D_Tpl : public C_Tpl { D_METHODS };
371 
372 
373 // Inheritance approach 1: each trampoline gets every virtual method (11 in total)
374 class PyA_Repeat : public A_Repeat {
375 public:
376  using A_Repeat::A_Repeat;
377  int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, A_Repeat, unlucky_number, ); }
378  std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, A_Repeat, say_something, times); }
379 };
380 class PyB_Repeat : public B_Repeat {
381 public:
382  using B_Repeat::B_Repeat;
383  int unlucky_number() override { PYBIND11_OVERLOAD(int, B_Repeat, unlucky_number, ); }
384  std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, B_Repeat, say_something, times); }
385  double lucky_number() override { PYBIND11_OVERLOAD(double, B_Repeat, lucky_number, ); }
386 };
387 class PyC_Repeat : public C_Repeat {
388 public:
389  using C_Repeat::C_Repeat;
390  int unlucky_number() override { PYBIND11_OVERLOAD(int, C_Repeat, unlucky_number, ); }
391  std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, C_Repeat, say_something, times); }
392  double lucky_number() override { PYBIND11_OVERLOAD(double, C_Repeat, lucky_number, ); }
393 };
394 class PyD_Repeat : public D_Repeat {
395 public:
396  using D_Repeat::D_Repeat;
397  int unlucky_number() override { PYBIND11_OVERLOAD(int, D_Repeat, unlucky_number, ); }
398  std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, D_Repeat, say_something, times); }
399  double lucky_number() override { PYBIND11_OVERLOAD(double, D_Repeat, lucky_number, ); }
400 };
401 
402 // Inheritance approach 2: templated trampoline classes.
403 //
404 // Advantages:
405 // - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one for
406 // any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes and 11
407 // methods (repeat).
408 // - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and can
409 // properly inherit constructors.
410 //
411 // Disadvantage:
412 // - the compiler must still generate and compile 14 different methods (more, even, than the 11
413 // required for the repeat approach) instead of the 6 required for MI. (If there was no pure
414 // method (or no pure method override), the number would drop down to the same 11 as the repeat
415 // approach).
416 template <class Base = A_Tpl>
417 class PyA_Tpl : public Base {
418 public:
419  using Base::Base; // Inherit constructors
420  int unlucky_number() override { PYBIND11_OVERLOAD_PURE(int, Base, unlucky_number, ); }
421  std::string say_something(unsigned times) override { PYBIND11_OVERLOAD(std::string, Base, say_something, times); }
422 };
423 template <class Base = B_Tpl>
424 class PyB_Tpl : public PyA_Tpl<Base> {
425 public:
426  using PyA_Tpl<Base>::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors)
427  int unlucky_number() override { PYBIND11_OVERLOAD(int, Base, unlucky_number, ); }
428  double lucky_number() override { PYBIND11_OVERLOAD(double, Base, lucky_number, ); }
429 };
430 // Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these (we can
431 // use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):
432 /*
433 template <class Base = C_Tpl> class PyC_Tpl : public PyB_Tpl<Base> {
434 public:
435  using PyB_Tpl<Base>::PyB_Tpl;
436 };
437 template <class Base = D_Tpl> class PyD_Tpl : public PyC_Tpl<Base> {
438 public:
439  using PyC_Tpl<Base>::PyC_Tpl;
440 };
441 */
442 
444  // test_inherited_virtuals
445 
446  // Method 1: repeat
447  py::class_<A_Repeat, PyA_Repeat>(m, "A_Repeat")
448  .def(py::init<>())
449  .def("unlucky_number", &A_Repeat::unlucky_number)
450  .def("say_something", &A_Repeat::say_something)
451  .def("say_everything", &A_Repeat::say_everything);
453  .def(py::init<>())
454  .def("lucky_number", &B_Repeat::lucky_number);
456  .def(py::init<>());
458  .def(py::init<>());
459 
460  // test_
461  // Method 2: Templated trampolines
462  py::class_<A_Tpl, PyA_Tpl<>>(m, "A_Tpl")
463  .def(py::init<>())
464  .def("unlucky_number", &A_Tpl::unlucky_number)
465  .def("say_something", &A_Tpl::say_something)
466  .def("say_everything", &A_Tpl::say_everything);
468  .def(py::init<>())
469  .def("lucky_number", &B_Tpl::lucky_number);
471  .def(py::init<>());
473  .def(py::init<>());
474 
475 
476  // Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)
477  m.def("test_gil", &test_gil);
478  m.def("test_gil_from_thread", &test_gil_from_thread);
479 };
static void test_gil()
Movable(const Movable &m)
const std::string str2
virtual void pure_virtual()=0
virtual const std::string & get_string1()
std::string say_something(unsigned times) override
#define A_METHODS
virtual const std::string * get_string2()
virtual bool run_bool()=0
string release
Definition: conf.py:66
void initialize_inherited_virtuals(py::module &m)
double lucky_number() override
#define D_METHODS
const std::string * get_string2() override
void print_destroyed(T *inst, Values &&...values)
NonCopyable(int a, int b)
virtual std::string dispatch() const
std::string say_everything()
std::string say_something(unsigned times) override
virtual std::string say_something(unsigned times)
void print_copy_created(T *inst, Values &&...values)
std::string get_value() const
virtual std::string say_something(unsigned times)
int unlucky_number() override
Wrapper for Python extension modules.
Definition: pybind11.h:789
int run(int value) override
int unlucky_number() override
virtual int unlucky_number()=0
std::string print_movable(int a, int b)
static void test_gil_from_thread()
virtual double lucky_number()
#define B_METHODS
std::string get_value() const
detail::initimpl::constructor< Args... > init()
Binds an existing constructor taking arguments Args...
Definition: pybind11.h:1371
#define C_METHODS
virtual int run(int value)
ExampleVirt(const ExampleVirt &e)
double lucky_number() override
NonCopyable get_noncopyable(int a, int b) override
bool run_bool() override
virtual std::string dispatch() const
Movable get_movable(int a, int b) override
Movable(Movable &&m)
virtual NonCopyable get_noncopyable(int a, int b)
ExampleVirt(ExampleVirt &&e)
int unlucky_number() override
std::string say_something(unsigned times) override
Movable(int a, int b)
std::string print_nc(int a, int b)
virtual Movable get_movable(int a, int b)=0
const detail::type_info * type
Definition: cast.h:453
void print_created(T *inst, Values &&...values)
detail::enable_if_t<!detail::move_never< T >::value, T > move(object &&obj)
Definition: cast.h:1685
virtual int unlucky_number()=0
int unlucky_number() override
double lucky_number() override
std::unique_ptr< int > value
virtual double lucky_number()
int unlucky_number() override
int unlucky_number() override
void print(Args &&...args)
Definition: pybind11.h:1849
void print_move_created(T *inst, Values &&...values)
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn,...)
Definition: pybind11.h:2152
const std::string & get_string1() override
#define TEST_SUBMODULE(name, variable)
const std::string str1
#define PYBIND11_TYPE(...)
Definition: cast.h:2128
std::string say_something(unsigned times) override
void pure_virtual() override
bool typename Extra class_ & def(const char *name_, Func &&f, const Extra &... extra)
Definition: pybind11.h:1110
test_initializer virtual_functions("virtual_functions", test_submodule_virtual_functions)
NonCopyable(NonCopyable &&o)
auto to_string(T &&value) -> decltype(std::forward< T >(value))
Convert an object to a string (directly forward if this can become a string)
Definition: CLI11.hpp:1028
double lucky_number() override
std::string say_everything()
#define PYBIND11_OVERLOAD(ret_type, cname, fn,...)
Definition: pybind11.h:2145
std::string say_something(unsigned times) override