1
0

builtins.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "test.h"
  2. namespace {
  3. int copy_constructor_calls = 0;
  4. int move_constructor_calls = 0;
  5. int destructor_calls = 0;
  6. struct Point {
  7. int x;
  8. int y;
  9. Point(int x, int y) : x(x), y(y) {}
  10. Point(const Point& other) : x(other.x), y(other.y) { ++copy_constructor_calls; }
  11. Point(Point&& other) : x(other.x), y(other.y) { ++move_constructor_calls; }
  12. ~Point() { ++destructor_calls; }
  13. bool operator== (const Point& p) const { return x == p.x && y == p.y; }
  14. };
  15. TEST_F(PYBIND11_TEST, exec_and_eval) {
  16. auto m = py::module::__main__();
  17. py::dict locals = {py::arg("x") = 1, py::arg("y") = 2};
  18. py::object obj = py::eval("x + y", py::none{}, locals);
  19. EXPECT_EQ(obj.cast<int>(), 3);
  20. py::exec("x = 1 + 2");
  21. EXPECT_EQ(py::eval("x").cast<int>(), 3);
  22. py::exec("y = 1 + 2", m.attr("__dict__"));
  23. EXPECT_EQ(py::eval("y", m.attr("__dict__")).cast<int>(), 3);
  24. EXPECT_EQ(locals["x"].cast<int>(), 1);
  25. EXPECT_EQ(locals["y"].cast<int>(), 2);
  26. }
  27. TEST_F(PYBIND11_TEST, locals_and_globals) {
  28. py::exec("x = 1");
  29. auto globals = py::globals();
  30. EXPECT_EQ(globals["x"].cast<int>(), 1);
  31. globals["y"] = 2;
  32. EXPECT_EQ(py::eval("y").cast<int>(), 2);
  33. }
  34. TEST_F(PYBIND11_TEST, cast) {
  35. auto m = py::module::__main__();
  36. py::class_<Point>(m, "Point")
  37. .def(py::init<int, int>())
  38. .def_readwrite("x", &Point::x)
  39. .def_readwrite("y", &Point::y)
  40. .def("__eq__", &Point::operator==);
  41. Point p(1, 2);
  42. // for py::cast's default policy
  43. // if argument is lvalue, policy is copy
  44. py::object o = py::cast(p);
  45. EXPECT_EQ(py::cast<Point&>(o), p);
  46. EXPECT_EQ(copy_constructor_calls, 1);
  47. EXPECT_EQ(move_constructor_calls, 0);
  48. // if argument is rvalue, policy is move
  49. py::object o2 = py::cast(std::move(p));
  50. EXPECT_EQ(py::cast<Point&>(o2), p);
  51. EXPECT_EQ(copy_constructor_calls, 1);
  52. EXPECT_EQ(move_constructor_calls, 1);
  53. // if argument is pointer, policy is reference(no taking ownership)
  54. py::object o3 = py::cast(&p);
  55. EXPECT_EQ(py::cast<Point&>(o3), p);
  56. EXPECT_EQ(copy_constructor_calls, 1);
  57. EXPECT_EQ(move_constructor_calls, 1);
  58. py::finalize(true);
  59. EXPECT_EQ(destructor_calls, 2);
  60. }
  61. TEST_F(PYBIND11_TEST, cpp_call_py) {
  62. auto m = py::module::__main__();
  63. py::exec(R"(
  64. class Test:
  65. def __init__(self, x, y):
  66. self.x = x
  67. self.y = y
  68. def sum1(self, z):
  69. return self.x + self.y + z
  70. def sum2(self, z, *args):
  71. return self.x + self.y + z + sum(args)
  72. def sum3(self, z, n=0):
  73. return self.x + self.y + z + n
  74. def sum4(self, z, *args, **kwargs):
  75. return self.x + self.y + z + sum(args) + kwargs['a'] + kwargs['b']
  76. )");
  77. auto obj = py::eval("Test(1, 2)");
  78. EXPECT_EQ(obj.attr("sum1")(3).cast<int>(), 6);
  79. EXPECT_EQ(obj.attr("sum2")(3, 4, 5).cast<int>(), 15);
  80. using namespace py::literals;
  81. EXPECT_EQ(obj.attr("sum3")(3, "n"_a = 4).cast<int>(), 10);
  82. EXPECT_EQ(obj.attr("sum4")(3, 4, 5, "a"_a = 6, "b"_a = 7).cast<int>(), 28);
  83. }
  84. } // namespace