412d6798e9eb7141f490950a7c7dbcc588f75009
3 from pybind11_tests
import class_
as m
4 from pybind11_tests
import UserType
, ConstructorStats
8 # In Python 3.3+, repr() accesses __qualname__
9 assert "pybind11_type" in repr(type(UserType
))
10 assert "UserType" in repr(UserType
)
13 def test_instance(msg
):
14 with pytest
.raises(TypeError) as excinfo
:
16 assert msg(excinfo
.value
) == "m.class_.NoConstructor: No constructor defined!"
18 instance
= m
.NoConstructor
.new_instance()
20 cstats
= ConstructorStats
.get(m
.NoConstructor
)
21 assert cstats
.alive() == 1
23 assert cstats
.alive() == 0
26 def test_docstrings(doc
):
27 assert doc(UserType
) == "A `py::class_` type for testing"
28 assert UserType
.__name
__ == "UserType"
29 assert UserType
.__module
__ == "pybind11_tests"
30 assert UserType
.get_value
.__name
__ == "get_value"
31 assert UserType
.get_value
.__module
__ == "pybind11_tests"
33 assert doc(UserType
.get_value
) == """
34 get_value(self: m.UserType) -> int
36 Get value using a method
38 assert doc(UserType
.value
) == "Get/set value using a property"
40 assert doc(m
.NoConstructor
.new_instance
) == """
41 new_instance() -> m.class_.NoConstructor
47 def test_inheritance(msg
):
48 roger
= m
.Rabbit('Rabbit')
49 assert roger
.name() + " is a " + roger
.species() == "Rabbit is a parrot"
50 assert m
.pet_name_species(roger
) == "Rabbit is a parrot"
52 polly
= m
.Pet('Polly', 'parrot')
53 assert polly
.name() + " is a " + polly
.species() == "Polly is a parrot"
54 assert m
.pet_name_species(polly
) == "Polly is a parrot"
56 molly
= m
.Dog('Molly')
57 assert molly
.name() + " is a " + molly
.species() == "Molly is a dog"
58 assert m
.pet_name_species(molly
) == "Molly is a dog"
60 fred
= m
.Hamster('Fred')
61 assert fred
.name() + " is a " + fred
.species() == "Fred is a rodent"
63 assert m
.dog_bark(molly
) == "Woof!"
65 with pytest
.raises(TypeError) as excinfo
:
67 assert msg(excinfo
.value
) == """
68 dog_bark(): incompatible function arguments. The following argument types are supported:
69 1. (arg0: m.class_.Dog) -> str
71 Invoked with: <m.class_.Pet object at 0>
74 with pytest
.raises(TypeError) as excinfo
:
75 m
.Chimera("lion", "goat")
76 assert "No constructor defined!" in str(excinfo
.value
)
79 def test_automatic_upcasting():
80 assert type(m
.return_class_1()).__name
__ == "DerivedClass1"
81 assert type(m
.return_class_2()).__name
__ == "DerivedClass2"
82 assert type(m
.return_none()).__name
__ == "NoneType"
83 # Repeat these a few times in a random order to ensure no invalid caching is applied
84 assert type(m
.return_class_n(1)).__name
__ == "DerivedClass1"
85 assert type(m
.return_class_n(2)).__name
__ == "DerivedClass2"
86 assert type(m
.return_class_n(0)).__name
__ == "BaseClass"
87 assert type(m
.return_class_n(2)).__name
__ == "DerivedClass2"
88 assert type(m
.return_class_n(2)).__name
__ == "DerivedClass2"
89 assert type(m
.return_class_n(0)).__name
__ == "BaseClass"
90 assert type(m
.return_class_n(1)).__name
__ == "DerivedClass1"
93 def test_isinstance():
94 objects
= [tuple(), dict(), m
.Pet("Polly", "parrot")] + [m
.Dog("Molly")] * 4
95 expected
= (True, True, True, True, True, False, False)
96 assert m
.check_instances(objects
) == expected
99 def test_mismatched_holder():
102 with pytest
.raises(RuntimeError) as excinfo
:
103 m
.mismatched_holder_1()
104 assert re
.match('generic_type: type ".*MismatchDerived1" does not have a non-default '
105 'holder type while its base ".*MismatchBase1" does', str(excinfo
.value
))
107 with pytest
.raises(RuntimeError) as excinfo
:
108 m
.mismatched_holder_2()
109 assert re
.match('generic_type: type ".*MismatchDerived2" has a non-default holder type '
110 'while its base ".*MismatchBase2" does not', str(excinfo
.value
))
113 def test_override_static():
114 """#511: problem with inheritance + overwritten def_static"""
116 d1
= m
.MyDerived
.make2()
117 d2
= m
.MyDerived
.make()
119 assert isinstance(b
, m
.MyBase
)
120 assert isinstance(d1
, m
.MyDerived
)
121 assert isinstance(d2
, m
.MyDerived
)
124 def test_implicit_conversion_life_support():
125 """Ensure the lifetime of temporary objects created for implicit conversions"""
126 assert m
.implicitly_convert_argument(UserType(5)) == 5
127 assert m
.implicitly_convert_variable(UserType(5)) == 5
129 assert "outside a bound function" in m
.implicitly_convert_variable_fail(UserType(5))
132 def test_operator_new_delete(capture
):
133 """Tests that class-specific operator new/delete functions are invoked"""
135 class SubAliased(m
.AliasedHasOpNewDelSize
):
140 b
= m
.HasOpNewDelSize()
141 d
= m
.HasOpNewDelBoth()
142 assert capture
== """
147 sz_alias
= str(m
.AliasedHasOpNewDelSize
.size_alias
)
148 sz_noalias
= str(m
.AliasedHasOpNewDelSize
.size_noalias
)
150 c
= m
.AliasedHasOpNewDelSize()
153 "C new " + sz_noalias
+ "\n" +
154 "C new " + sz_alias
+ "\n"
164 assert capture
== """
176 "C delete " + sz_noalias
+ "\n" +
177 "C delete " + sz_alias
+ "\n"
181 def test_bind_protected_functions():
182 """Expose protected member functions to Python using a helper class"""
189 class C(m
.ProtectedB
):
191 m
.ProtectedB
.__init
__(self
)
200 def test_brace_initialization():
201 """ Tests that simple POD classes can be constructed using C++11 brace initialization """
202 a
= m
.BraceInitialization(123, "test")
203 assert a
.field1
== 123
204 assert a
.field2
== "test"
207 @pytest.unsupported_on_pypy
208 def test_class_refcount():
209 """Instances must correctly increase/decrease the reference count of their types (#1029)"""
210 from sys
import getrefcount
215 for cls
in m
.Dog
, PyDog
:
216 refcount_1
= getrefcount(cls
)
217 molly
= [cls("Molly") for _
in range(10)]
218 refcount_2
= getrefcount(cls
)
222 refcount_3
= getrefcount(cls
)
224 assert refcount_1
== refcount_3
225 assert refcount_2
> refcount_1
228 def test_reentrant_implicit_conversion_failure(msg
):
229 # ensure that there is no runaway reentrant implicit conversion (#1035)
230 with pytest
.raises(TypeError) as excinfo
:
231 m
.BogusImplicitConversion(0)
232 assert msg(excinfo
.value
) == '''__init__(): incompatible constructor arguments. The following argument types are supported:
233 1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)