blob: 1c75c47de647166a7d75d05d61f11ddcfd890c3a [file] [log] [blame]
Dean Moldovan83e328f2017-06-09 00:44:49 +02001import pytest
2import sys
3
4from pybind11_tests import pytypes as m
5from pybind11_tests import debug_enabled
6
7
8def test_list(capture, doc):
9 with capture:
10 l = m.get_list()
11 assert l == ["overwritten"]
12
13 l.append("value2")
14 m.print_list(l)
15 assert capture.unordered == """
16 Entry at position 0: value
17 list item 0: overwritten
18 list item 1: value2
19 """
20
21 assert doc(m.get_list) == "get_list() -> list"
22 assert doc(m.print_list) == "print_list(arg0: list) -> None"
23
24
25def test_set(capture, doc):
26 s = m.get_set()
27 assert s == {"key1", "key2", "key3"}
28
29 with capture:
30 s.add("key4")
31 m.print_set(s)
32 assert capture.unordered == """
33 key: key1
34 key: key2
35 key: key3
36 key: key4
37 """
38
39 assert doc(m.get_list) == "get_list() -> list"
40 assert doc(m.print_list) == "print_list(arg0: list) -> None"
41
42
43def test_dict(capture, doc):
44 d = m.get_dict()
45 assert d == {"key": "value"}
46
47 with capture:
48 d["key2"] = "value2"
49 m.print_dict(d)
50 assert capture.unordered == """
51 key: key, value=value
52 key: key2, value=value2
53 """
54
55 assert doc(m.get_dict) == "get_dict() -> dict"
56 assert doc(m.print_dict) == "print_dict(arg0: dict) -> None"
57
58 assert m.dict_keyword_constructor() == {"x": 1, "y": 2, "z": 3}
59
60
61def test_str(doc):
62 assert m.str_from_string().encode().decode() == "baz"
63 assert m.str_from_bytes().encode().decode() == "boo"
64
65 assert doc(m.str_from_bytes) == "str_from_bytes() -> str"
66
67 class A(object):
68 def __str__(self):
69 return "this is a str"
70
71 def __repr__(self):
72 return "this is a repr"
73
74 assert m.str_from_object(A()) == "this is a str"
75 assert m.repr_from_object(A()) == "this is a repr"
76
77 s1, s2 = m.str_format()
78 assert s1 == "1 + 2 = 3"
79 assert s1 == s2
80
81
82def test_bytes(doc):
83 assert m.bytes_from_string().decode() == "foo"
84 assert m.bytes_from_str().decode() == "bar"
85
86 assert doc(m.bytes_from_str) == "bytes_from_str() -> {}".format(
87 "bytes" if sys.version_info[0] == 3 else "str"
88 )
89
90
91def test_capsule(capture):
92 pytest.gc_collect()
93 with capture:
94 a = m.return_capsule_with_destructor()
95 del a
96 pytest.gc_collect()
97 assert capture.unordered == """
98 creating capsule
99 destructing capsule
100 """
101
102 with capture:
103 a = m.return_capsule_with_destructor_2()
104 del a
105 pytest.gc_collect()
106 assert capture.unordered == """
107 creating capsule
108 destructing capsule: 1234
109 """
110
111 with capture:
112 a = m.return_capsule_with_name_and_destructor()
113 del a
114 pytest.gc_collect()
115 assert capture.unordered == """
116 created capsule (1234, 'pointer type description')
117 destructing capsule (1234, 'pointer type description')
118 """
119
120
121def test_accessors():
122 class SubTestObject:
123 attr_obj = 1
124 attr_char = 2
125
126 class TestObject:
127 basic_attr = 1
128 begin_end = [1, 2, 3]
129 d = {"operator[object]": 1, "operator[char *]": 2}
130 sub = SubTestObject()
131
132 def func(self, x, *args):
133 return self.basic_attr + x + sum(args)
134
135 d = m.accessor_api(TestObject())
136 assert d["basic_attr"] == 1
137 assert d["begin_end"] == [1, 2, 3]
138 assert d["operator[object]"] == 1
139 assert d["operator[char *]"] == 2
140 assert d["attr(object)"] == 1
141 assert d["attr(char *)"] == 2
142 assert d["missing_attr_ptr"] == "raised"
143 assert d["missing_attr_chain"] == "raised"
144 assert d["is_none"] is False
145 assert d["operator()"] == 2
146 assert d["operator*"] == 7
147
148 assert m.tuple_accessor(tuple()) == (0, 1, 2)
149
150 d = m.accessor_assignment()
151 assert d["get"] == 0
152 assert d["deferred_get"] == 0
153 assert d["set"] == 1
154 assert d["deferred_set"] == 1
155 assert d["var"] == 99
156
157
158def test_constructors():
159 """C++ default and converting constructors are equivalent to type calls in Python"""
160 types = [str, bool, int, float, tuple, list, dict, set]
161 expected = {t.__name__: t() for t in types}
162 assert m.default_constructors() == expected
163
164 data = {
165 str: 42,
166 bool: "Not empty",
167 int: "42",
168 float: "+1e3",
169 tuple: range(3),
170 list: range(3),
171 dict: [("two", 2), ("one", 1), ("three", 3)],
172 set: [4, 4, 5, 6, 6, 6],
173 memoryview: b'abc'
174 }
175 inputs = {k.__name__: v for k, v in data.items()}
176 expected = {k.__name__: k(v) for k, v in data.items()}
177 assert m.converting_constructors(inputs) == expected
178 assert m.cast_functions(inputs) == expected
179
180
181def test_implicit_casting():
182 """Tests implicit casting when assigning or appending to dicts and lists."""
183 z = m.get_implicit_casting()
184 assert z['d'] == {
185 'char*_i1': 'abc', 'char*_i2': 'abc', 'char*_e': 'abc', 'char*_p': 'abc',
186 'str_i1': 'str', 'str_i2': 'str1', 'str_e': 'str2', 'str_p': 'str3',
187 'int_i1': 42, 'int_i2': 42, 'int_e': 43, 'int_p': 44
188 }
189 assert z['l'] == [3, 6, 9, 12, 15]
190
191
192def test_print(capture):
193 with capture:
194 m.print_function()
195 assert capture == """
196 Hello, World!
197 1 2.0 three True -- multiple args
198 *args-and-a-custom-separator
199 no new line here -- next print
200 flush
201 py::print + str.format = this
202 """
203 assert capture.stderr == "this goes to stderr"
204
205 with pytest.raises(RuntimeError) as excinfo:
206 m.print_failure()
207 assert str(excinfo.value) == "make_tuple(): unable to convert " + (
208 "argument of type 'UnregisteredType' to Python object"
209 if debug_enabled else
210 "arguments to Python object (compile in debug mode for details)"
211 )