test_pytypes.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. tests/test_pytypes.cpp -- Python type casters
  3. Copyright (c) 2017 Wenzel Jakob <[email protected]>
  4. All rights reserved. Use of this source code is governed by a
  5. BSD-style license that can be found in the LICENSE file.
  6. */
  7. #include "pybind11_tests.h"
  8. TEST_SUBMODULE(pytypes, m) {
  9. // test_int
  10. m.def("get_int", []{return py::int_(0);});
  11. // test_iterator
  12. m.def("get_iterator", []{return py::iterator();});
  13. // test_iterable
  14. m.def("get_iterable", []{return py::iterable();});
  15. // test_list
  16. m.def("get_list", []() {
  17. py::list list;
  18. list.append("value");
  19. py::print("Entry at position 0:", list[0]);
  20. list[0] = py::str("overwritten");
  21. list.insert(0, "inserted-0");
  22. list.insert(2, "inserted-2");
  23. return list;
  24. });
  25. m.def("print_list", [](py::list list) {
  26. int index = 0;
  27. for (auto item : list)
  28. py::print("list item {}: {}"_s.format(index++, item));
  29. });
  30. // test_none
  31. m.def("get_none", []{return py::none();});
  32. m.def("print_none", [](py::none none) {
  33. py::print("none: {}"_s.format(none));
  34. });
  35. // test_set
  36. m.def("get_set", []() {
  37. py::set set;
  38. set.add(py::str("key1"));
  39. set.add("key2");
  40. set.add(std::string("key3"));
  41. return set;
  42. });
  43. m.def("print_set", [](py::set set) {
  44. for (auto item : set)
  45. py::print("key:", item);
  46. });
  47. m.def("set_contains", [](py::set set, py::object key) {
  48. return set.contains(key);
  49. });
  50. m.def("set_contains", [](py::set set, const char* key) {
  51. return set.contains(key);
  52. });
  53. // test_dict
  54. m.def("get_dict", []() { return py::dict("key"_a="value"); });
  55. m.def("print_dict", [](py::dict dict) {
  56. for (auto item : dict)
  57. py::print("key: {}, value={}"_s.format(item.first, item.second));
  58. });
  59. m.def("dict_keyword_constructor", []() {
  60. auto d1 = py::dict("x"_a=1, "y"_a=2);
  61. auto d2 = py::dict("z"_a=3, **d1);
  62. return d2;
  63. });
  64. m.def("dict_contains", [](py::dict dict, py::object val) {
  65. return dict.contains(val);
  66. });
  67. m.def("dict_contains", [](py::dict dict, const char* val) {
  68. return dict.contains(val);
  69. });
  70. // test_str
  71. m.def("str_from_string", []() { return py::str(std::string("baz")); });
  72. m.def("str_from_bytes", []() { return py::str(py::bytes("boo", 3)); });
  73. m.def("str_from_object", [](const py::object& obj) { return py::str(obj); });
  74. m.def("repr_from_object", [](const py::object& obj) { return py::repr(obj); });
  75. m.def("str_from_handle", [](py::handle h) { return py::str(h); });
  76. m.def("str_format", []() {
  77. auto s1 = "{} + {} = {}"_s.format(1, 2, 3);
  78. auto s2 = "{a} + {b} = {c}"_s.format("a"_a=1, "b"_a=2, "c"_a=3);
  79. return py::make_tuple(s1, s2);
  80. });
  81. // test_bytes
  82. m.def("bytes_from_string", []() { return py::bytes(std::string("foo")); });
  83. m.def("bytes_from_str", []() { return py::bytes(py::str("bar", 3)); });
  84. // test_capsule
  85. m.def("return_capsule_with_destructor", []() {
  86. py::print("creating capsule");
  87. return py::capsule([]() {
  88. py::print("destructing capsule");
  89. });
  90. });
  91. m.def("return_capsule_with_destructor_2", []() {
  92. py::print("creating capsule");
  93. return py::capsule((void *) 1234, [](void *ptr) {
  94. py::print("destructing capsule: {}"_s.format((size_t) ptr));
  95. });
  96. });
  97. m.def("return_capsule_with_name_and_destructor", []() {
  98. auto capsule = py::capsule((void *) 12345, "pointer type description", [](PyObject *ptr) {
  99. if (ptr) {
  100. auto name = PyCapsule_GetName(ptr);
  101. py::print("destructing capsule ({}, '{}')"_s.format(
  102. (size_t) PyCapsule_GetPointer(ptr, name), name
  103. ));
  104. }
  105. });
  106. capsule.set_pointer((void *) 1234);
  107. // Using get_pointer<T>()
  108. void* contents1 = static_cast<void*>(capsule);
  109. void* contents2 = capsule.get_pointer();
  110. void* contents3 = capsule.get_pointer<void>();
  111. auto result1 = reinterpret_cast<size_t>(contents1);
  112. auto result2 = reinterpret_cast<size_t>(contents2);
  113. auto result3 = reinterpret_cast<size_t>(contents3);
  114. py::print("created capsule ({}, '{}')"_s.format(result1 & result2 & result3, capsule.name()));
  115. return capsule;
  116. });
  117. // test_accessors
  118. m.def("accessor_api", [](py::object o) {
  119. auto d = py::dict();
  120. d["basic_attr"] = o.attr("basic_attr");
  121. auto l = py::list();
  122. for (auto item : o.attr("begin_end")) {
  123. l.append(item);
  124. }
  125. d["begin_end"] = l;
  126. d["operator[object]"] = o.attr("d")["operator[object]"_s];
  127. d["operator[char *]"] = o.attr("d")["operator[char *]"];
  128. d["attr(object)"] = o.attr("sub").attr("attr_obj");
  129. d["attr(char *)"] = o.attr("sub").attr("attr_char");
  130. try {
  131. o.attr("sub").attr("missing").ptr();
  132. } catch (const py::error_already_set &) {
  133. d["missing_attr_ptr"] = "raised"_s;
  134. }
  135. try {
  136. o.attr("missing").attr("doesn't matter");
  137. } catch (const py::error_already_set &) {
  138. d["missing_attr_chain"] = "raised"_s;
  139. }
  140. d["is_none"] = o.attr("basic_attr").is_none();
  141. d["operator()"] = o.attr("func")(1);
  142. d["operator*"] = o.attr("func")(*o.attr("begin_end"));
  143. // Test implicit conversion
  144. py::list implicit_list = o.attr("begin_end");
  145. d["implicit_list"] = implicit_list;
  146. py::dict implicit_dict = o.attr("__dict__");
  147. d["implicit_dict"] = implicit_dict;
  148. return d;
  149. });
  150. m.def("tuple_accessor", [](py::tuple existing_t) {
  151. try {
  152. existing_t[0] = 1;
  153. } catch (const py::error_already_set &) {
  154. // --> Python system error
  155. // Only new tuples (refcount == 1) are mutable
  156. auto new_t = py::tuple(3);
  157. for (size_t i = 0; i < new_t.size(); ++i) {
  158. new_t[i] = i;
  159. }
  160. return new_t;
  161. }
  162. return py::tuple();
  163. });
  164. m.def("accessor_assignment", []() {
  165. auto l = py::list(1);
  166. l[0] = 0;
  167. auto d = py::dict();
  168. d["get"] = l[0];
  169. auto var = l[0];
  170. d["deferred_get"] = var;
  171. l[0] = 1;
  172. d["set"] = l[0];
  173. var = 99; // this assignment should not overwrite l[0]
  174. d["deferred_set"] = l[0];
  175. d["var"] = var;
  176. return d;
  177. });
  178. // test_constructors
  179. m.def("default_constructors", []() {
  180. return py::dict(
  181. "bytes"_a=py::bytes(),
  182. "str"_a=py::str(),
  183. "bool"_a=py::bool_(),
  184. "int"_a=py::int_(),
  185. "float"_a=py::float_(),
  186. "tuple"_a=py::tuple(),
  187. "list"_a=py::list(),
  188. "dict"_a=py::dict(),
  189. "set"_a=py::set()
  190. );
  191. });
  192. m.def("converting_constructors", [](py::dict d) {
  193. return py::dict(
  194. "bytes"_a=py::bytes(d["bytes"]),
  195. "str"_a=py::str(d["str"]),
  196. "bool"_a=py::bool_(d["bool"]),
  197. "int"_a=py::int_(d["int"]),
  198. "float"_a=py::float_(d["float"]),
  199. "tuple"_a=py::tuple(d["tuple"]),
  200. "list"_a=py::list(d["list"]),
  201. "dict"_a=py::dict(d["dict"]),
  202. "set"_a=py::set(d["set"]),
  203. "memoryview"_a=py::memoryview(d["memoryview"])
  204. );
  205. });
  206. m.def("cast_functions", [](py::dict d) {
  207. // When converting between Python types, obj.cast<T>() should be the same as T(obj)
  208. return py::dict(
  209. "bytes"_a=d["bytes"].cast<py::bytes>(),
  210. "str"_a=d["str"].cast<py::str>(),
  211. "bool"_a=d["bool"].cast<py::bool_>(),
  212. "int"_a=d["int"].cast<py::int_>(),
  213. "float"_a=d["float"].cast<py::float_>(),
  214. "tuple"_a=d["tuple"].cast<py::tuple>(),
  215. "list"_a=d["list"].cast<py::list>(),
  216. "dict"_a=d["dict"].cast<py::dict>(),
  217. "set"_a=d["set"].cast<py::set>(),
  218. "memoryview"_a=d["memoryview"].cast<py::memoryview>()
  219. );
  220. });
  221. m.def("convert_to_pybind11_str", [](py::object o) { return py::str(o); });
  222. m.def("nonconverting_constructor", [](std::string type, py::object value, bool move) -> py::object {
  223. if (type == "bytes") {
  224. return move ? py::bytes(std::move(value)) : py::bytes(value);
  225. }
  226. else if (type == "none") {
  227. return move ? py::none(std::move(value)) : py::none(value);
  228. }
  229. else if (type == "ellipsis") {
  230. return move ? py::ellipsis(std::move(value)) : py::ellipsis(value);
  231. }
  232. else if (type == "type") {
  233. return move ? py::type(std::move(value)) : py::type(value);
  234. }
  235. throw std::runtime_error("Invalid type");
  236. });
  237. m.def("get_implicit_casting", []() {
  238. py::dict d;
  239. d["char*_i1"] = "abc";
  240. const char *c2 = "abc";
  241. d["char*_i2"] = c2;
  242. d["char*_e"] = py::cast(c2);
  243. d["char*_p"] = py::str(c2);
  244. d["int_i1"] = 42;
  245. int i = 42;
  246. d["int_i2"] = i;
  247. i++;
  248. d["int_e"] = py::cast(i);
  249. i++;
  250. d["int_p"] = py::int_(i);
  251. d["str_i1"] = std::string("str");
  252. std::string s2("str1");
  253. d["str_i2"] = s2;
  254. s2[3] = '2';
  255. d["str_e"] = py::cast(s2);
  256. s2[3] = '3';
  257. d["str_p"] = py::str(s2);
  258. py::list l(2);
  259. l[0] = 3;
  260. l[1] = py::cast(6);
  261. l.append(9);
  262. l.append(py::cast(12));
  263. l.append(py::int_(15));
  264. return py::dict(
  265. "d"_a=d,
  266. "l"_a=l
  267. );
  268. });
  269. // test_print
  270. m.def("print_function", []() {
  271. py::print("Hello, World!");
  272. py::print(1, 2.0, "three", true, std::string("-- multiple args"));
  273. auto args = py::make_tuple("and", "a", "custom", "separator");
  274. py::print("*args", *args, "sep"_a="-");
  275. py::print("no new line here", "end"_a=" -- ");
  276. py::print("next print");
  277. auto py_stderr = py::module_::import("sys").attr("stderr");
  278. py::print("this goes to stderr", "file"_a=py_stderr);
  279. py::print("flush", "flush"_a=true);
  280. py::print("{a} + {b} = {c}"_s.format("a"_a="py::print", "b"_a="str.format", "c"_a="this"));
  281. });
  282. m.def("print_failure", []() { py::print(42, UnregisteredType()); });
  283. m.def("hash_function", [](py::object obj) { return py::hash(obj); });
  284. m.def("test_number_protocol", [](py::object a, py::object b) {
  285. py::list l;
  286. l.append(a.equal(b));
  287. l.append(a.not_equal(b));
  288. l.append(a < b);
  289. l.append(a <= b);
  290. l.append(a > b);
  291. l.append(a >= b);
  292. l.append(a + b);
  293. l.append(a - b);
  294. l.append(a * b);
  295. l.append(a / b);
  296. l.append(a | b);
  297. l.append(a & b);
  298. l.append(a ^ b);
  299. l.append(a >> b);
  300. l.append(a << b);
  301. return l;
  302. });
  303. m.def("test_list_slicing", [](py::list a) {
  304. return a[py::slice(0, -1, 2)];
  305. });
  306. // See #2361
  307. m.def("issue2361_str_implicit_copy_none", []() {
  308. py::str is_this_none = py::none();
  309. return is_this_none;
  310. });
  311. m.def("issue2361_dict_implicit_copy_none", []() {
  312. py::dict is_this_none = py::none();
  313. return is_this_none;
  314. });
  315. m.def("test_memoryview_object", [](py::buffer b) {
  316. return py::memoryview(b);
  317. });
  318. m.def("test_memoryview_buffer_info", [](py::buffer b) {
  319. return py::memoryview(b.request());
  320. });
  321. m.def("test_memoryview_from_buffer", [](bool is_unsigned) {
  322. static const int16_t si16[] = { 3, 1, 4, 1, 5 };
  323. static const uint16_t ui16[] = { 2, 7, 1, 8 };
  324. if (is_unsigned)
  325. return py::memoryview::from_buffer(
  326. ui16, { 4 }, { sizeof(uint16_t) });
  327. else
  328. return py::memoryview::from_buffer(
  329. si16, { 5 }, { sizeof(int16_t) });
  330. });
  331. m.def("test_memoryview_from_buffer_nativeformat", []() {
  332. static const char* format = "@i";
  333. static const int32_t arr[] = { 4, 7, 5 };
  334. return py::memoryview::from_buffer(
  335. arr, sizeof(int32_t), format, { 3 }, { sizeof(int32_t) });
  336. });
  337. m.def("test_memoryview_from_buffer_empty_shape", []() {
  338. static const char* buf = "";
  339. return py::memoryview::from_buffer(buf, 1, "B", { }, { });
  340. });
  341. m.def("test_memoryview_from_buffer_invalid_strides", []() {
  342. static const char* buf = "\x02\x03\x04";
  343. return py::memoryview::from_buffer(buf, 1, "B", { 3 }, { });
  344. });
  345. m.def("test_memoryview_from_buffer_nullptr", []() {
  346. return py::memoryview::from_buffer(
  347. static_cast<void*>(nullptr), 1, "B", { }, { });
  348. });
  349. #if PY_MAJOR_VERSION >= 3
  350. m.def("test_memoryview_from_memory", []() {
  351. const char* buf = "\xff\xe1\xab\x37";
  352. return py::memoryview::from_memory(
  353. buf, static_cast<py::ssize_t>(strlen(buf)));
  354. });
  355. #endif
  356. // test_builtin_functions
  357. m.def("get_len", [](py::handle h) { return py::len(h); });
  358. }