github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/tests/test_class.py (about) 1 import pytest 2 3 import env 4 from pybind11_tests import ConstructorStats, UserType 5 from pybind11_tests import class_ as m 6 7 8 def test_obj_class_name(): 9 if env.PYPY: 10 expected_name = "UserType" 11 else: 12 expected_name = "pybind11_tests.UserType" 13 assert m.obj_class_name(UserType(1)) == expected_name 14 assert m.obj_class_name(UserType) == expected_name 15 16 17 def test_repr(): 18 assert "pybind11_type" in repr(type(UserType)) 19 assert "UserType" in repr(UserType) 20 21 22 def test_instance(msg): 23 with pytest.raises(TypeError) as excinfo: 24 m.NoConstructor() 25 assert msg(excinfo.value) == "m.class_.NoConstructor: No constructor defined!" 26 27 instance = m.NoConstructor.new_instance() 28 29 cstats = ConstructorStats.get(m.NoConstructor) 30 assert cstats.alive() == 1 31 del instance 32 assert cstats.alive() == 0 33 34 35 def test_instance_new(msg): 36 instance = m.NoConstructorNew() # .__new__(m.NoConstructor.__class__) 37 cstats = ConstructorStats.get(m.NoConstructorNew) 38 assert cstats.alive() == 1 39 del instance 40 assert cstats.alive() == 0 41 42 43 def test_type(): 44 assert m.check_type(1) == m.DerivedClass1 45 with pytest.raises(RuntimeError) as execinfo: 46 m.check_type(0) 47 48 assert "pybind11::detail::get_type_info: unable to find type info" in str( 49 execinfo.value 50 ) 51 assert "Invalid" in str(execinfo.value) 52 53 # Currently not supported 54 # See https://github.com/pybind/pybind11/issues/2486 55 # assert m.check_type(2) == int 56 57 58 def test_type_of_py(): 59 assert m.get_type_of(1) == int 60 assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1 61 assert m.get_type_of(int) == type 62 63 64 def test_type_of_classic(): 65 assert m.get_type_classic(1) == int 66 assert m.get_type_classic(m.DerivedClass1()) == m.DerivedClass1 67 assert m.get_type_classic(int) == type 68 69 70 def test_type_of_py_nodelete(): 71 # If the above test deleted the class, this will segfault 72 assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1 73 74 75 def test_as_type_py(): 76 assert m.as_type(int) == int 77 78 with pytest.raises(TypeError): 79 assert m.as_type(1) == int 80 81 with pytest.raises(TypeError): 82 assert m.as_type(m.DerivedClass1()) == m.DerivedClass1 83 84 85 def test_docstrings(doc): 86 assert doc(UserType) == "A `py::class_` type for testing" 87 assert UserType.__name__ == "UserType" 88 assert UserType.__module__ == "pybind11_tests" 89 assert UserType.get_value.__name__ == "get_value" 90 assert UserType.get_value.__module__ == "pybind11_tests" 91 92 assert ( 93 doc(UserType.get_value) 94 == """ 95 get_value(self: m.UserType) -> int 96 97 Get value using a method 98 """ 99 ) 100 assert doc(UserType.value) == "Get/set value using a property" 101 102 assert ( 103 doc(m.NoConstructor.new_instance) 104 == """ 105 new_instance() -> m.class_.NoConstructor 106 107 Return an instance 108 """ 109 ) 110 111 112 def test_qualname(doc): 113 """Tests that a properly qualified name is set in __qualname__ and that 114 generated docstrings properly use it and the module name""" 115 assert m.NestBase.__qualname__ == "NestBase" 116 assert m.NestBase.Nested.__qualname__ == "NestBase.Nested" 117 118 assert ( 119 doc(m.NestBase.__init__) 120 == """ 121 __init__(self: m.class_.NestBase) -> None 122 """ 123 ) 124 assert ( 125 doc(m.NestBase.g) 126 == """ 127 g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None 128 """ 129 ) 130 assert ( 131 doc(m.NestBase.Nested.__init__) 132 == """ 133 __init__(self: m.class_.NestBase.Nested) -> None 134 """ 135 ) 136 assert ( 137 doc(m.NestBase.Nested.fn) 138 == """ 139 fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None 140 """ 141 ) 142 assert ( 143 doc(m.NestBase.Nested.fa) 144 == """ 145 fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None 146 """ 147 ) 148 assert m.NestBase.__module__ == "pybind11_tests.class_" 149 assert m.NestBase.Nested.__module__ == "pybind11_tests.class_" 150 151 152 def test_inheritance(msg): 153 roger = m.Rabbit("Rabbit") 154 assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot" 155 assert m.pet_name_species(roger) == "Rabbit is a parrot" 156 157 polly = m.Pet("Polly", "parrot") 158 assert polly.name() + " is a " + polly.species() == "Polly is a parrot" 159 assert m.pet_name_species(polly) == "Polly is a parrot" 160 161 molly = m.Dog("Molly") 162 assert molly.name() + " is a " + molly.species() == "Molly is a dog" 163 assert m.pet_name_species(molly) == "Molly is a dog" 164 165 fred = m.Hamster("Fred") 166 assert fred.name() + " is a " + fred.species() == "Fred is a rodent" 167 168 assert m.dog_bark(molly) == "Woof!" 169 170 with pytest.raises(TypeError) as excinfo: 171 m.dog_bark(polly) 172 assert ( 173 msg(excinfo.value) 174 == """ 175 dog_bark(): incompatible function arguments. The following argument types are supported: 176 1. (arg0: m.class_.Dog) -> str 177 178 Invoked with: <m.class_.Pet object at 0> 179 """ 180 ) 181 182 with pytest.raises(TypeError) as excinfo: 183 m.Chimera("lion", "goat") 184 assert "No constructor defined!" in str(excinfo.value) 185 186 187 def test_inheritance_init(msg): 188 # Single base 189 class Python(m.Pet): 190 def __init__(self): 191 pass 192 193 with pytest.raises(TypeError) as exc_info: 194 Python() 195 expected = "m.class_.Pet.__init__() must be called when overriding __init__" 196 assert msg(exc_info.value) == expected 197 198 # Multiple bases 199 class RabbitHamster(m.Rabbit, m.Hamster): 200 def __init__(self): 201 m.Rabbit.__init__(self, "RabbitHamster") 202 203 with pytest.raises(TypeError) as exc_info: 204 RabbitHamster() 205 expected = "m.class_.Hamster.__init__() must be called when overriding __init__" 206 assert msg(exc_info.value) == expected 207 208 209 def test_automatic_upcasting(): 210 assert type(m.return_class_1()).__name__ == "DerivedClass1" 211 assert type(m.return_class_2()).__name__ == "DerivedClass2" 212 assert type(m.return_none()).__name__ == "NoneType" 213 # Repeat these a few times in a random order to ensure no invalid caching is applied 214 assert type(m.return_class_n(1)).__name__ == "DerivedClass1" 215 assert type(m.return_class_n(2)).__name__ == "DerivedClass2" 216 assert type(m.return_class_n(0)).__name__ == "BaseClass" 217 assert type(m.return_class_n(2)).__name__ == "DerivedClass2" 218 assert type(m.return_class_n(2)).__name__ == "DerivedClass2" 219 assert type(m.return_class_n(0)).__name__ == "BaseClass" 220 assert type(m.return_class_n(1)).__name__ == "DerivedClass1" 221 222 223 def test_isinstance(): 224 objects = [tuple(), dict(), m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4 225 expected = (True, True, True, True, True, False, False) 226 assert m.check_instances(objects) == expected 227 228 229 def test_mismatched_holder(): 230 import re 231 232 with pytest.raises(RuntimeError) as excinfo: 233 m.mismatched_holder_1() 234 assert re.match( 235 'generic_type: type ".*MismatchDerived1" does not have a non-default ' 236 'holder type while its base ".*MismatchBase1" does', 237 str(excinfo.value), 238 ) 239 240 with pytest.raises(RuntimeError) as excinfo: 241 m.mismatched_holder_2() 242 assert re.match( 243 'generic_type: type ".*MismatchDerived2" has a non-default holder type ' 244 'while its base ".*MismatchBase2" does not', 245 str(excinfo.value), 246 ) 247 248 249 def test_override_static(): 250 """#511: problem with inheritance + overwritten def_static""" 251 b = m.MyBase.make() 252 d1 = m.MyDerived.make2() 253 d2 = m.MyDerived.make() 254 255 assert isinstance(b, m.MyBase) 256 assert isinstance(d1, m.MyDerived) 257 assert isinstance(d2, m.MyDerived) 258 259 260 def test_implicit_conversion_life_support(): 261 """Ensure the lifetime of temporary objects created for implicit conversions""" 262 assert m.implicitly_convert_argument(UserType(5)) == 5 263 assert m.implicitly_convert_variable(UserType(5)) == 5 264 265 assert "outside a bound function" in m.implicitly_convert_variable_fail(UserType(5)) 266 267 268 def test_operator_new_delete(capture): 269 """Tests that class-specific operator new/delete functions are invoked""" 270 271 class SubAliased(m.AliasedHasOpNewDelSize): 272 pass 273 274 with capture: 275 a = m.HasOpNewDel() 276 b = m.HasOpNewDelSize() 277 d = m.HasOpNewDelBoth() 278 assert ( 279 capture 280 == """ 281 A new 8 282 B new 4 283 D new 32 284 """ 285 ) 286 sz_alias = str(m.AliasedHasOpNewDelSize.size_alias) 287 sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias) 288 with capture: 289 c = m.AliasedHasOpNewDelSize() 290 c2 = SubAliased() 291 assert capture == ("C new " + sz_noalias + "\n" + "C new " + sz_alias + "\n") 292 293 with capture: 294 del a 295 pytest.gc_collect() 296 del b 297 pytest.gc_collect() 298 del d 299 pytest.gc_collect() 300 assert ( 301 capture 302 == """ 303 A delete 304 B delete 4 305 D delete 306 """ 307 ) 308 309 with capture: 310 del c 311 pytest.gc_collect() 312 del c2 313 pytest.gc_collect() 314 assert capture == ("C delete " + sz_noalias + "\n" + "C delete " + sz_alias + "\n") 315 316 317 def test_bind_protected_functions(): 318 """Expose protected member functions to Python using a helper class""" 319 a = m.ProtectedA() 320 assert a.foo() == 42 321 322 b = m.ProtectedB() 323 assert b.foo() == 42 324 assert m.read_foo(b.void_foo()) == 42 325 assert m.pointers_equal(b.get_self(), b) 326 327 class C(m.ProtectedB): 328 def __init__(self): 329 m.ProtectedB.__init__(self) 330 331 def foo(self): 332 return 0 333 334 c = C() 335 assert c.foo() == 0 336 337 338 def test_brace_initialization(): 339 """Tests that simple POD classes can be constructed using C++11 brace initialization""" 340 a = m.BraceInitialization(123, "test") 341 assert a.field1 == 123 342 assert a.field2 == "test" 343 344 # Tests that a non-simple class doesn't get brace initialization (if the 345 # class defines an initializer_list constructor, in particular, it would 346 # win over the expected constructor). 347 b = m.NoBraceInitialization([123, 456]) 348 assert b.vec == [123, 456] 349 350 351 @pytest.mark.xfail("env.PYPY") 352 def test_class_refcount(): 353 """Instances must correctly increase/decrease the reference count of their types (#1029)""" 354 from sys import getrefcount 355 356 class PyDog(m.Dog): 357 pass 358 359 for cls in m.Dog, PyDog: 360 refcount_1 = getrefcount(cls) 361 molly = [cls("Molly") for _ in range(10)] 362 refcount_2 = getrefcount(cls) 363 364 del molly 365 pytest.gc_collect() 366 refcount_3 = getrefcount(cls) 367 368 assert refcount_1 == refcount_3 369 assert refcount_2 > refcount_1 370 371 372 def test_reentrant_implicit_conversion_failure(msg): 373 # ensure that there is no runaway reentrant implicit conversion (#1035) 374 with pytest.raises(TypeError) as excinfo: 375 m.BogusImplicitConversion(0) 376 assert ( 377 msg(excinfo.value) 378 == """ 379 __init__(): incompatible constructor arguments. The following argument types are supported: 380 1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion) 381 382 Invoked with: 0 383 """ 384 ) 385 386 387 def test_error_after_conversions(): 388 with pytest.raises(TypeError) as exc_info: 389 m.test_error_after_conversions("hello") 390 assert str(exc_info.value).startswith( 391 "Unable to convert function return value to a Python type!" 392 ) 393 394 395 def test_aligned(): 396 if hasattr(m, "Aligned"): 397 p = m.Aligned().ptr() 398 assert p % 1024 == 0 399 400 401 # https://foss.heptapod.net/pypy/pypy/-/issues/2742 402 @pytest.mark.xfail("env.PYPY") 403 def test_final(): 404 with pytest.raises(TypeError) as exc_info: 405 406 class PyFinalChild(m.IsFinal): 407 pass 408 409 assert str(exc_info.value).endswith("is not an acceptable base type") 410 411 412 # https://foss.heptapod.net/pypy/pypy/-/issues/2742 413 @pytest.mark.xfail("env.PYPY") 414 def test_non_final_final(): 415 with pytest.raises(TypeError) as exc_info: 416 417 class PyNonFinalFinalChild(m.IsNonFinalFinal): 418 pass 419 420 assert str(exc_info.value).endswith("is not an acceptable base type") 421 422 423 # https://github.com/pybind/pybind11/issues/1878 424 def test_exception_rvalue_abort(): 425 with pytest.raises(RuntimeError): 426 m.PyPrintDestructor().throw_something() 427 428 429 # https://github.com/pybind/pybind11/issues/1568 430 def test_multiple_instances_with_same_pointer(capture): 431 n = 100 432 instances = [m.SamePointer() for _ in range(n)] 433 for i in range(n): 434 # We need to reuse the same allocated memory for with a different type, 435 # to ensure the bug in `deregister_instance_impl` is detected. Otherwise 436 # `Py_TYPE(self) == Py_TYPE(it->second)` will still succeed, even though 437 # the `instance` is already deleted. 438 instances[i] = m.Empty() 439 # No assert: if this does not trigger the error 440 # pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!"); 441 # and just completes without crashing, we're good. 442 443 444 # https://github.com/pybind/pybind11/issues/1624 445 def test_base_and_derived_nested_scope(): 446 assert issubclass(m.DerivedWithNested, m.BaseWithNested) 447 assert m.BaseWithNested.Nested != m.DerivedWithNested.Nested 448 assert m.BaseWithNested.Nested.get_name() == "BaseWithNested::Nested" 449 assert m.DerivedWithNested.Nested.get_name() == "DerivedWithNested::Nested" 450 451 452 def test_register_duplicate_class(): 453 import types 454 455 module_scope = types.ModuleType("module_scope") 456 with pytest.raises(RuntimeError) as exc_info: 457 m.register_duplicate_class_name(module_scope) 458 expected = ( 459 'generic_type: cannot initialize type "Duplicate": ' 460 "an object with that name is already defined" 461 ) 462 assert str(exc_info.value) == expected 463 with pytest.raises(RuntimeError) as exc_info: 464 m.register_duplicate_class_type(module_scope) 465 expected = 'generic_type: type "YetAnotherDuplicate" is already registered!' 466 assert str(exc_info.value) == expected 467 468 class ClassScope: 469 pass 470 471 with pytest.raises(RuntimeError) as exc_info: 472 m.register_duplicate_nested_class_name(ClassScope) 473 expected = ( 474 'generic_type: cannot initialize type "DuplicateNested": ' 475 "an object with that name is already defined" 476 ) 477 assert str(exc_info.value) == expected 478 with pytest.raises(RuntimeError) as exc_info: 479 m.register_duplicate_nested_class_type(ClassScope) 480 expected = 'generic_type: type "YetAnotherDuplicateNested" is already registered!' 481 assert str(exc_info.value) == expected 482 483 484 def test_pr4220_tripped_over_this(): 485 assert ( 486 m.Empty0().get_msg() 487 == "This is really only meant to exercise successful compilation." 488 )