test_methods_and_attributes.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 import pytest
3 
4 import env # noqa: F401
5 
6 from pybind11_tests import methods_and_attributes as m
7 from pybind11_tests import ConstructorStats
8 
9 
11  instance1 = m.ExampleMandA()
12  instance2 = m.ExampleMandA(32)
13 
14  instance1.add1(instance2)
15  instance1.add2(instance2)
16  instance1.add3(instance2)
17  instance1.add4(instance2)
18  instance1.add5(instance2)
19  instance1.add6(32)
20  instance1.add7(32)
21  instance1.add8(32)
22  instance1.add9(32)
23  instance1.add10(32)
24 
25  assert str(instance1) == "ExampleMandA[value=320]"
26  assert str(instance2) == "ExampleMandA[value=32]"
27  assert str(instance1.self1()) == "ExampleMandA[value=320]"
28  assert str(instance1.self2()) == "ExampleMandA[value=320]"
29  assert str(instance1.self3()) == "ExampleMandA[value=320]"
30  assert str(instance1.self4()) == "ExampleMandA[value=320]"
31  assert str(instance1.self5()) == "ExampleMandA[value=320]"
32 
33  assert instance1.internal1() == 320
34  assert instance1.internal2() == 320
35  assert instance1.internal3() == 320
36  assert instance1.internal4() == 320
37  assert instance1.internal5() == 320
38 
39  assert instance1.overloaded() == "()"
40  assert instance1.overloaded(0) == "(int)"
41  assert instance1.overloaded(1, 1.0) == "(int, float)"
42  assert instance1.overloaded(2.0, 2) == "(float, int)"
43  assert instance1.overloaded(3, 3) == "(int, int)"
44  assert instance1.overloaded(4., 4.) == "(float, float)"
45  assert instance1.overloaded_const(-3) == "(int) const"
46  assert instance1.overloaded_const(5, 5.0) == "(int, float) const"
47  assert instance1.overloaded_const(6.0, 6) == "(float, int) const"
48  assert instance1.overloaded_const(7, 7) == "(int, int) const"
49  assert instance1.overloaded_const(8., 8.) == "(float, float) const"
50  assert instance1.overloaded_float(1, 1) == "(float, float)"
51  assert instance1.overloaded_float(1, 1.) == "(float, float)"
52  assert instance1.overloaded_float(1., 1) == "(float, float)"
53  assert instance1.overloaded_float(1., 1.) == "(float, float)"
54 
55  assert instance1.value == 320
56  instance1.value = 100
57  assert str(instance1) == "ExampleMandA[value=100]"
58 
59  cstats = ConstructorStats.get(m.ExampleMandA)
60  assert cstats.alive() == 2
61  del instance1, instance2
62  assert cstats.alive() == 0
63  assert cstats.values() == ["32"]
64  assert cstats.default_constructions == 1
65  assert cstats.copy_constructions == 2
66  assert cstats.move_constructions >= 2
67  assert cstats.copy_assignments == 0
68  assert cstats.move_assignments == 0
69 
70 
72  """Issue #443: calling copied methods fails in Python 3"""
73 
74  m.ExampleMandA.add2c = m.ExampleMandA.add2
75  m.ExampleMandA.add2d = m.ExampleMandA.add2b
76  a = m.ExampleMandA(123)
77  assert a.value == 123
78  a.add2(m.ExampleMandA(-100))
79  assert a.value == 23
80  a.add2b(m.ExampleMandA(20))
81  assert a.value == 43
82  a.add2c(m.ExampleMandA(6))
83  assert a.value == 49
84  a.add2d(m.ExampleMandA(-7))
85  assert a.value == 42
86 
87 
89  instance = m.TestProperties()
90 
91  assert instance.def_readonly == 1
92  with pytest.raises(AttributeError):
93  instance.def_readonly = 2
94 
95  instance.def_readwrite = 2
96  assert instance.def_readwrite == 2
97 
98  assert instance.def_property_readonly == 2
99  with pytest.raises(AttributeError):
100  instance.def_property_readonly = 3
101 
102  instance.def_property = 3
103  assert instance.def_property == 3
104 
105  with pytest.raises(AttributeError) as excinfo:
106  dummy = instance.def_property_writeonly # noqa: F841 unused var
107  assert "unreadable attribute" in str(excinfo.value)
108 
109  instance.def_property_writeonly = 4
110  assert instance.def_property_readonly == 4
111 
112  with pytest.raises(AttributeError) as excinfo:
113  dummy = instance.def_property_impossible # noqa: F841 unused var
114  assert "unreadable attribute" in str(excinfo.value)
115 
116  with pytest.raises(AttributeError) as excinfo:
117  instance.def_property_impossible = 5
118  assert "can't set attribute" in str(excinfo.value)
119 
120 
122  assert m.TestProperties.def_readonly_static == 1
123  with pytest.raises(AttributeError) as excinfo:
124  m.TestProperties.def_readonly_static = 2
125  assert "can't set attribute" in str(excinfo.value)
126 
127  m.TestProperties.def_readwrite_static = 2
128  assert m.TestProperties.def_readwrite_static == 2
129 
130  with pytest.raises(AttributeError) as excinfo:
131  dummy = m.TestProperties.def_writeonly_static # noqa: F841 unused var
132  assert "unreadable attribute" in str(excinfo.value)
133 
134  m.TestProperties.def_writeonly_static = 3
135  assert m.TestProperties.def_readonly_static == 3
136 
137  assert m.TestProperties.def_property_readonly_static == 3
138  with pytest.raises(AttributeError) as excinfo:
139  m.TestProperties.def_property_readonly_static = 99
140  assert "can't set attribute" in str(excinfo.value)
141 
142  m.TestProperties.def_property_static = 4
143  assert m.TestProperties.def_property_static == 4
144 
145  with pytest.raises(AttributeError) as excinfo:
146  dummy = m.TestProperties.def_property_writeonly_static
147  assert "unreadable attribute" in str(excinfo.value)
148 
149  m.TestProperties.def_property_writeonly_static = 5
150  assert m.TestProperties.def_property_static == 5
151 
152  # Static property read and write via instance
153  instance = m.TestProperties()
154 
155  m.TestProperties.def_readwrite_static = 0
156  assert m.TestProperties.def_readwrite_static == 0
157  assert instance.def_readwrite_static == 0
158 
159  instance.def_readwrite_static = 2
160  assert m.TestProperties.def_readwrite_static == 2
161  assert instance.def_readwrite_static == 2
162 
163  with pytest.raises(AttributeError) as excinfo:
164  dummy = instance.def_property_writeonly_static # noqa: F841 unused var
165  assert "unreadable attribute" in str(excinfo.value)
166 
167  instance.def_property_writeonly_static = 4
168  assert instance.def_property_static == 4
169 
170  # It should be possible to override properties in derived classes
171  assert m.TestPropertiesOverride().def_readonly == 99
172  assert m.TestPropertiesOverride.def_readonly_static == 99
173 
174 
176  """Static property getter and setters expect the type object as the their only argument"""
177 
178  instance = m.TestProperties()
179  assert m.TestProperties.static_cls is m.TestProperties
180  assert instance.static_cls is m.TestProperties
181 
182  def check_self(self):
183  assert self is m.TestProperties
184 
185  m.TestProperties.static_cls = check_self
186  instance.static_cls = check_self
187 
188 
190  """Overriding pybind11's default metaclass changes the behavior of `static_property`"""
191 
192  assert type(m.ExampleMandA).__name__ == "pybind11_type"
193  assert type(m.MetaclassOverride).__name__ == "type"
194 
195  assert m.MetaclassOverride.readonly == 1
196  assert type(m.MetaclassOverride.__dict__["readonly"]).__name__ == "pybind11_static_property"
197 
198  # Regular `type` replaces the property instead of calling `__set__()`
199  m.MetaclassOverride.readonly = 2
200  assert m.MetaclassOverride.readonly == 2
201  assert isinstance(m.MetaclassOverride.__dict__["readonly"], int)
202 
203 
205  from pybind11_tests import debug_enabled
206 
207  with pytest.raises(RuntimeError) as excinfo:
208  m.ExampleMandA.add_mixed_overloads1()
209  assert (str(excinfo.value) ==
210  "overloading a method with both static and instance methods is not supported; " +
211  ("compile in debug mode for more details" if not debug_enabled else
212  "error while attempting to bind static method ExampleMandA.overload_mixed1"
213  "(arg0: float) -> str")
214  )
215 
216  with pytest.raises(RuntimeError) as excinfo:
217  m.ExampleMandA.add_mixed_overloads2()
218  assert (str(excinfo.value) ==
219  "overloading a method with both static and instance methods is not supported; " +
220  ("compile in debug mode for more details" if not debug_enabled else
221  "error while attempting to bind instance method ExampleMandA.overload_mixed2"
222  "(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
223  " -> str")
224  )
225 
226 
227 @pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
229  if not access.startswith("static"):
230  obj = m.TestPropRVP()
231  else:
232  obj = m.TestPropRVP
233 
234  ref = getattr(obj, access + "_ref")
235  assert ref.value == 1
236  ref.value = 2
237  assert getattr(obj, access + "_ref").value == 2
238  ref.value = 1 # restore original value for static properties
239 
240  copy = getattr(obj, access + "_copy")
241  assert copy.value == 1
242  copy.value = 2
243  assert getattr(obj, access + "_copy").value == 1
244 
245  copy = getattr(obj, access + "_func")
246  assert copy.value == 1
247  copy.value = 2
248  assert getattr(obj, access + "_func").value == 1
249 
250 
252  """When returning an rvalue, the return value policy is automatically changed from
253  `reference(_internal)` to `move`. The following would not work otherwise."""
254 
255  instance = m.TestPropRVP()
256  o = instance.rvalue
257  assert o.value == 1
258 
259  os = m.TestPropRVP.static_rvalue
260  assert os.value == 1
261 
262 
263 # https://foss.heptapod.net/pypy/pypy/-/issues/2447
264 @pytest.mark.xfail("env.PYPY")
266  instance = m.DynamicClass()
267  assert not hasattr(instance, "foo")
268  assert "foo" not in dir(instance)
269 
270  # Dynamically add attribute
271  instance.foo = 42
272  assert hasattr(instance, "foo")
273  assert instance.foo == 42
274  assert "foo" in dir(instance)
275 
276  # __dict__ should be accessible and replaceable
277  assert "foo" in instance.__dict__
278  instance.__dict__ = {"bar": True}
279  assert not hasattr(instance, "foo")
280  assert hasattr(instance, "bar")
281 
282  with pytest.raises(TypeError) as excinfo:
283  instance.__dict__ = []
284  assert str(excinfo.value) == "__dict__ must be set to a dictionary, not a 'list'"
285 
286  cstats = ConstructorStats.get(m.DynamicClass)
287  assert cstats.alive() == 1
288  del instance
289  assert cstats.alive() == 0
290 
291  # Derived classes should work as well
292  class PythonDerivedDynamicClass(m.DynamicClass):
293  pass
294 
295  for cls in m.CppDerivedDynamicClass, PythonDerivedDynamicClass:
296  derived = cls()
297  derived.foobar = 100
298  assert derived.foobar == 100
299 
300  assert cstats.alive() == 1
301  del derived
302  assert cstats.alive() == 0
303 
304 
305 # https://foss.heptapod.net/pypy/pypy/-/issues/2447
306 @pytest.mark.xfail("env.PYPY")
308  # One object references itself
309  instance = m.DynamicClass()
310  instance.circular_reference = instance
311 
312  cstats = ConstructorStats.get(m.DynamicClass)
313  assert cstats.alive() == 1
314  del instance
315  assert cstats.alive() == 0
316 
317  # Two object reference each other
318  i1 = m.DynamicClass()
319  i2 = m.DynamicClass()
320  i1.cycle = i2
321  i2.cycle = i1
322 
323  assert cstats.alive() == 2
324  del i1, i2
325  assert cstats.alive() == 0
326 
327 
329  from pybind11_tests import debug_enabled
330 
331  with pytest.raises(RuntimeError) as excinfo:
332  m.bad_arg_def_named()
333  assert msg(excinfo.value) == (
334  "arg(): could not convert default argument 'a: UnregisteredType' in function "
335  "'should_fail' into a Python object (type not registered yet?)"
336  if debug_enabled else
337  "arg(): could not convert default argument into a Python object (type not registered "
338  "yet?). Compile in debug mode for more information."
339  )
340 
341  with pytest.raises(RuntimeError) as excinfo:
342  m.bad_arg_def_unnamed()
343  assert msg(excinfo.value) == (
344  "arg(): could not convert default argument 'UnregisteredType' in function "
345  "'should_fail' into a Python object (type not registered yet?)"
346  if debug_enabled else
347  "arg(): could not convert default argument into a Python object (type not registered "
348  "yet?). Compile in debug mode for more information."
349  )
350 
351 
353  a = m.NoneTester()
354  assert m.no_none1(a) == 42
355  assert m.no_none2(a) == 42
356  assert m.no_none3(a) == 42
357  assert m.no_none4(a) == 42
358  assert m.no_none5(a) == 42
359  assert m.ok_none1(a) == 42
360  assert m.ok_none2(a) == 42
361  assert m.ok_none3(a) == 42
362  assert m.ok_none4(a) == 42
363  assert m.ok_none5(a) == 42
364 
365  with pytest.raises(TypeError) as excinfo:
366  m.no_none1(None)
367  assert "incompatible function arguments" in str(excinfo.value)
368  with pytest.raises(TypeError) as excinfo:
369  m.no_none2(None)
370  assert "incompatible function arguments" in str(excinfo.value)
371  with pytest.raises(TypeError) as excinfo:
372  m.no_none3(None)
373  assert "incompatible function arguments" in str(excinfo.value)
374  with pytest.raises(TypeError) as excinfo:
375  m.no_none4(None)
376  assert "incompatible function arguments" in str(excinfo.value)
377  with pytest.raises(TypeError) as excinfo:
378  m.no_none5(None)
379  assert "incompatible function arguments" in str(excinfo.value)
380 
381  # The first one still raises because you can't pass None as a lvalue reference arg:
382  with pytest.raises(TypeError) as excinfo:
383  assert m.ok_none1(None) == -1
384  assert msg(excinfo.value) == """
385  ok_none1(): incompatible function arguments. The following argument types are supported:
386  1. (arg0: m.methods_and_attributes.NoneTester) -> int
387 
388  Invoked with: None
389  """
390 
391  # The rest take the argument as pointer or holder, and accept None:
392  assert m.ok_none2(None) == -1
393  assert m.ok_none3(None) == -1
394  assert m.ok_none4(None) == -1
395  assert m.ok_none5(None) == -1
396 
397 
398 def test_str_issue(msg):
399  """#283: __str__ called on uninitialized instance when constructor arguments invalid"""
400 
401  assert str(m.StrIssue(3)) == "StrIssue[3]"
402 
403  with pytest.raises(TypeError) as excinfo:
404  str(m.StrIssue("no", "such", "constructor"))
405  assert msg(excinfo.value) == """
406  __init__(): incompatible constructor arguments. The following argument types are supported:
407  1. m.methods_and_attributes.StrIssue(arg0: int)
408  2. m.methods_and_attributes.StrIssue()
409 
410  Invoked with: 'no', 'such', 'constructor'
411  """
412 
413 
415  a = m.RegisteredDerived()
416  a.do_nothing()
417  assert a.rw_value == 42
418  assert a.ro_value == 1.25
419  a.rw_value += 5
420  assert a.sum() == 48.25
421  a.increase_value()
422  assert a.rw_value == 48
423  assert a.ro_value == 1.5
424  assert a.sum() == 49.5
425  assert a.rw_value_prop == 48
426  a.rw_value_prop += 1
427  assert a.rw_value_prop == 49
428  a.increase_value()
429  assert a.ro_value_prop == 1.75
430 
431 
433  """Tests that explicit lvalue ref-qualified methods can be called just like their
434  non ref-qualified counterparts."""
435 
436  r = m.RefQualified()
437  assert r.value == 0
438  r.refQualified(17)
439  assert r.value == 17
440  assert r.constRefQualified(23) == 40
bool hasattr(handle obj, handle name)
Definition: pytypes.h:403
bool isinstance(handle obj)
Definition: pytypes.h:384
Unit3 dir(nM)
static ConstructorStats & get(std::type_index type)
Definition: pytypes.h:928
object getattr(handle obj, handle name)
Definition: pytypes.h:419
Definition: pytypes.h:897


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:46:03