112391Sjason@lowepower.comimport pytest 212391Sjason@lowepower.com 312391Sjason@lowepower.comfrom pybind11_tests import class_ as m 412391Sjason@lowepower.comfrom pybind11_tests import UserType, ConstructorStats 512391Sjason@lowepower.com 612391Sjason@lowepower.com 712391Sjason@lowepower.comdef test_repr(): 812391Sjason@lowepower.com # In Python 3.3+, repr() accesses __qualname__ 912391Sjason@lowepower.com assert "pybind11_type" in repr(type(UserType)) 1012391Sjason@lowepower.com assert "UserType" in repr(UserType) 1112391Sjason@lowepower.com 1212391Sjason@lowepower.com 1312391Sjason@lowepower.comdef test_instance(msg): 1412391Sjason@lowepower.com with pytest.raises(TypeError) as excinfo: 1512391Sjason@lowepower.com m.NoConstructor() 1612391Sjason@lowepower.com assert msg(excinfo.value) == "m.class_.NoConstructor: No constructor defined!" 1712391Sjason@lowepower.com 1812391Sjason@lowepower.com instance = m.NoConstructor.new_instance() 1912391Sjason@lowepower.com 2012391Sjason@lowepower.com cstats = ConstructorStats.get(m.NoConstructor) 2112391Sjason@lowepower.com assert cstats.alive() == 1 2212391Sjason@lowepower.com del instance 2312391Sjason@lowepower.com assert cstats.alive() == 0 2412391Sjason@lowepower.com 2512391Sjason@lowepower.com 2612391Sjason@lowepower.comdef test_docstrings(doc): 2712391Sjason@lowepower.com assert doc(UserType) == "A `py::class_` type for testing" 2812391Sjason@lowepower.com assert UserType.__name__ == "UserType" 2912391Sjason@lowepower.com assert UserType.__module__ == "pybind11_tests" 3012391Sjason@lowepower.com assert UserType.get_value.__name__ == "get_value" 3112391Sjason@lowepower.com assert UserType.get_value.__module__ == "pybind11_tests" 3212391Sjason@lowepower.com 3312391Sjason@lowepower.com assert doc(UserType.get_value) == """ 3412391Sjason@lowepower.com get_value(self: m.UserType) -> int 3512391Sjason@lowepower.com 3612391Sjason@lowepower.com Get value using a method 3712391Sjason@lowepower.com """ 3812391Sjason@lowepower.com assert doc(UserType.value) == "Get/set value using a property" 3912391Sjason@lowepower.com 4012391Sjason@lowepower.com assert doc(m.NoConstructor.new_instance) == """ 4112391Sjason@lowepower.com new_instance() -> m.class_.NoConstructor 4212391Sjason@lowepower.com 4312391Sjason@lowepower.com Return an instance 4412391Sjason@lowepower.com """ 4512391Sjason@lowepower.com 4612391Sjason@lowepower.com 4714299Sbbruce@ucdavis.edudef test_qualname(doc): 4814299Sbbruce@ucdavis.edu """Tests that a properly qualified name is set in __qualname__ (even in pre-3.3, where we 4914299Sbbruce@ucdavis.edu backport the attribute) and that generated docstrings properly use it and the module name""" 5014299Sbbruce@ucdavis.edu assert m.NestBase.__qualname__ == "NestBase" 5114299Sbbruce@ucdavis.edu assert m.NestBase.Nested.__qualname__ == "NestBase.Nested" 5214299Sbbruce@ucdavis.edu 5314299Sbbruce@ucdavis.edu assert doc(m.NestBase.__init__) == """ 5414299Sbbruce@ucdavis.edu __init__(self: m.class_.NestBase) -> None 5514299Sbbruce@ucdavis.edu """ 5614299Sbbruce@ucdavis.edu assert doc(m.NestBase.g) == """ 5714299Sbbruce@ucdavis.edu g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None 5814299Sbbruce@ucdavis.edu """ 5914299Sbbruce@ucdavis.edu assert doc(m.NestBase.Nested.__init__) == """ 6014299Sbbruce@ucdavis.edu __init__(self: m.class_.NestBase.Nested) -> None 6114299Sbbruce@ucdavis.edu """ 6214299Sbbruce@ucdavis.edu assert doc(m.NestBase.Nested.fn) == """ 6314299Sbbruce@ucdavis.edu fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None 6414299Sbbruce@ucdavis.edu """ # noqa: E501 line too long 6514299Sbbruce@ucdavis.edu assert doc(m.NestBase.Nested.fa) == """ 6614299Sbbruce@ucdavis.edu fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None 6714299Sbbruce@ucdavis.edu """ # noqa: E501 line too long 6814299Sbbruce@ucdavis.edu assert m.NestBase.__module__ == "pybind11_tests.class_" 6914299Sbbruce@ucdavis.edu assert m.NestBase.Nested.__module__ == "pybind11_tests.class_" 7014299Sbbruce@ucdavis.edu 7114299Sbbruce@ucdavis.edu 7212391Sjason@lowepower.comdef test_inheritance(msg): 7312391Sjason@lowepower.com roger = m.Rabbit('Rabbit') 7412391Sjason@lowepower.com assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot" 7512391Sjason@lowepower.com assert m.pet_name_species(roger) == "Rabbit is a parrot" 7612391Sjason@lowepower.com 7712391Sjason@lowepower.com polly = m.Pet('Polly', 'parrot') 7812391Sjason@lowepower.com assert polly.name() + " is a " + polly.species() == "Polly is a parrot" 7912391Sjason@lowepower.com assert m.pet_name_species(polly) == "Polly is a parrot" 8012391Sjason@lowepower.com 8112391Sjason@lowepower.com molly = m.Dog('Molly') 8212391Sjason@lowepower.com assert molly.name() + " is a " + molly.species() == "Molly is a dog" 8312391Sjason@lowepower.com assert m.pet_name_species(molly) == "Molly is a dog" 8412391Sjason@lowepower.com 8512391Sjason@lowepower.com fred = m.Hamster('Fred') 8612391Sjason@lowepower.com assert fred.name() + " is a " + fred.species() == "Fred is a rodent" 8712391Sjason@lowepower.com 8812391Sjason@lowepower.com assert m.dog_bark(molly) == "Woof!" 8912391Sjason@lowepower.com 9012391Sjason@lowepower.com with pytest.raises(TypeError) as excinfo: 9112391Sjason@lowepower.com m.dog_bark(polly) 9212391Sjason@lowepower.com assert msg(excinfo.value) == """ 9312391Sjason@lowepower.com dog_bark(): incompatible function arguments. The following argument types are supported: 9412391Sjason@lowepower.com 1. (arg0: m.class_.Dog) -> str 9512391Sjason@lowepower.com 9612391Sjason@lowepower.com Invoked with: <m.class_.Pet object at 0> 9712391Sjason@lowepower.com """ 9812391Sjason@lowepower.com 9912391Sjason@lowepower.com with pytest.raises(TypeError) as excinfo: 10012391Sjason@lowepower.com m.Chimera("lion", "goat") 10112391Sjason@lowepower.com assert "No constructor defined!" in str(excinfo.value) 10212391Sjason@lowepower.com 10312391Sjason@lowepower.com 10412391Sjason@lowepower.comdef test_automatic_upcasting(): 10512391Sjason@lowepower.com assert type(m.return_class_1()).__name__ == "DerivedClass1" 10612391Sjason@lowepower.com assert type(m.return_class_2()).__name__ == "DerivedClass2" 10712391Sjason@lowepower.com assert type(m.return_none()).__name__ == "NoneType" 10812391Sjason@lowepower.com # Repeat these a few times in a random order to ensure no invalid caching is applied 10912391Sjason@lowepower.com assert type(m.return_class_n(1)).__name__ == "DerivedClass1" 11012391Sjason@lowepower.com assert type(m.return_class_n(2)).__name__ == "DerivedClass2" 11112391Sjason@lowepower.com assert type(m.return_class_n(0)).__name__ == "BaseClass" 11212391Sjason@lowepower.com assert type(m.return_class_n(2)).__name__ == "DerivedClass2" 11312391Sjason@lowepower.com assert type(m.return_class_n(2)).__name__ == "DerivedClass2" 11412391Sjason@lowepower.com assert type(m.return_class_n(0)).__name__ == "BaseClass" 11512391Sjason@lowepower.com assert type(m.return_class_n(1)).__name__ == "DerivedClass1" 11612391Sjason@lowepower.com 11712391Sjason@lowepower.com 11812391Sjason@lowepower.comdef test_isinstance(): 11912391Sjason@lowepower.com objects = [tuple(), dict(), m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4 12012391Sjason@lowepower.com expected = (True, True, True, True, True, False, False) 12112391Sjason@lowepower.com assert m.check_instances(objects) == expected 12212391Sjason@lowepower.com 12312391Sjason@lowepower.com 12412391Sjason@lowepower.comdef test_mismatched_holder(): 12512391Sjason@lowepower.com import re 12612391Sjason@lowepower.com 12712391Sjason@lowepower.com with pytest.raises(RuntimeError) as excinfo: 12812391Sjason@lowepower.com m.mismatched_holder_1() 12912391Sjason@lowepower.com assert re.match('generic_type: type ".*MismatchDerived1" does not have a non-default ' 13012391Sjason@lowepower.com 'holder type while its base ".*MismatchBase1" does', str(excinfo.value)) 13112391Sjason@lowepower.com 13212391Sjason@lowepower.com with pytest.raises(RuntimeError) as excinfo: 13312391Sjason@lowepower.com m.mismatched_holder_2() 13412391Sjason@lowepower.com assert re.match('generic_type: type ".*MismatchDerived2" has a non-default holder type ' 13512391Sjason@lowepower.com 'while its base ".*MismatchBase2" does not', str(excinfo.value)) 13612391Sjason@lowepower.com 13712391Sjason@lowepower.com 13812391Sjason@lowepower.comdef test_override_static(): 13912391Sjason@lowepower.com """#511: problem with inheritance + overwritten def_static""" 14012391Sjason@lowepower.com b = m.MyBase.make() 14112391Sjason@lowepower.com d1 = m.MyDerived.make2() 14212391Sjason@lowepower.com d2 = m.MyDerived.make() 14312391Sjason@lowepower.com 14412391Sjason@lowepower.com assert isinstance(b, m.MyBase) 14512391Sjason@lowepower.com assert isinstance(d1, m.MyDerived) 14612391Sjason@lowepower.com assert isinstance(d2, m.MyDerived) 14712391Sjason@lowepower.com 14812391Sjason@lowepower.com 14912391Sjason@lowepower.comdef test_implicit_conversion_life_support(): 15012391Sjason@lowepower.com """Ensure the lifetime of temporary objects created for implicit conversions""" 15112391Sjason@lowepower.com assert m.implicitly_convert_argument(UserType(5)) == 5 15212391Sjason@lowepower.com assert m.implicitly_convert_variable(UserType(5)) == 5 15312391Sjason@lowepower.com 15412391Sjason@lowepower.com assert "outside a bound function" in m.implicitly_convert_variable_fail(UserType(5)) 15512391Sjason@lowepower.com 15612391Sjason@lowepower.com 15712391Sjason@lowepower.comdef test_operator_new_delete(capture): 15812391Sjason@lowepower.com """Tests that class-specific operator new/delete functions are invoked""" 15912391Sjason@lowepower.com 16012391Sjason@lowepower.com class SubAliased(m.AliasedHasOpNewDelSize): 16112391Sjason@lowepower.com pass 16212391Sjason@lowepower.com 16312391Sjason@lowepower.com with capture: 16412391Sjason@lowepower.com a = m.HasOpNewDel() 16512391Sjason@lowepower.com b = m.HasOpNewDelSize() 16612391Sjason@lowepower.com d = m.HasOpNewDelBoth() 16712391Sjason@lowepower.com assert capture == """ 16812391Sjason@lowepower.com A new 8 16912391Sjason@lowepower.com B new 4 17012391Sjason@lowepower.com D new 32 17112391Sjason@lowepower.com """ 17212391Sjason@lowepower.com sz_alias = str(m.AliasedHasOpNewDelSize.size_alias) 17312391Sjason@lowepower.com sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias) 17412391Sjason@lowepower.com with capture: 17512391Sjason@lowepower.com c = m.AliasedHasOpNewDelSize() 17612391Sjason@lowepower.com c2 = SubAliased() 17712391Sjason@lowepower.com assert capture == ( 17812391Sjason@lowepower.com "C new " + sz_noalias + "\n" + 17912391Sjason@lowepower.com "C new " + sz_alias + "\n" 18012391Sjason@lowepower.com ) 18112391Sjason@lowepower.com 18212391Sjason@lowepower.com with capture: 18312391Sjason@lowepower.com del a 18412391Sjason@lowepower.com pytest.gc_collect() 18512391Sjason@lowepower.com del b 18612391Sjason@lowepower.com pytest.gc_collect() 18712391Sjason@lowepower.com del d 18812391Sjason@lowepower.com pytest.gc_collect() 18912391Sjason@lowepower.com assert capture == """ 19012391Sjason@lowepower.com A delete 19112391Sjason@lowepower.com B delete 4 19212391Sjason@lowepower.com D delete 19312391Sjason@lowepower.com """ 19412391Sjason@lowepower.com 19512391Sjason@lowepower.com with capture: 19612391Sjason@lowepower.com del c 19712391Sjason@lowepower.com pytest.gc_collect() 19812391Sjason@lowepower.com del c2 19912391Sjason@lowepower.com pytest.gc_collect() 20012391Sjason@lowepower.com assert capture == ( 20112391Sjason@lowepower.com "C delete " + sz_noalias + "\n" + 20212391Sjason@lowepower.com "C delete " + sz_alias + "\n" 20312391Sjason@lowepower.com ) 20412391Sjason@lowepower.com 20512391Sjason@lowepower.com 20612391Sjason@lowepower.comdef test_bind_protected_functions(): 20712391Sjason@lowepower.com """Expose protected member functions to Python using a helper class""" 20812391Sjason@lowepower.com a = m.ProtectedA() 20912391Sjason@lowepower.com assert a.foo() == 42 21012391Sjason@lowepower.com 21112391Sjason@lowepower.com b = m.ProtectedB() 21212391Sjason@lowepower.com assert b.foo() == 42 21312391Sjason@lowepower.com 21412391Sjason@lowepower.com class C(m.ProtectedB): 21512391Sjason@lowepower.com def __init__(self): 21612391Sjason@lowepower.com m.ProtectedB.__init__(self) 21712391Sjason@lowepower.com 21812391Sjason@lowepower.com def foo(self): 21912391Sjason@lowepower.com return 0 22012391Sjason@lowepower.com 22112391Sjason@lowepower.com c = C() 22212391Sjason@lowepower.com assert c.foo() == 0 22312391Sjason@lowepower.com 22412391Sjason@lowepower.com 22512391Sjason@lowepower.comdef test_brace_initialization(): 22612391Sjason@lowepower.com """ Tests that simple POD classes can be constructed using C++11 brace initialization """ 22712391Sjason@lowepower.com a = m.BraceInitialization(123, "test") 22812391Sjason@lowepower.com assert a.field1 == 123 22912391Sjason@lowepower.com assert a.field2 == "test" 23012391Sjason@lowepower.com 23114299Sbbruce@ucdavis.edu # Tests that a non-simple class doesn't get brace initialization (if the 23214299Sbbruce@ucdavis.edu # class defines an initializer_list constructor, in particular, it would 23314299Sbbruce@ucdavis.edu # win over the expected constructor). 23414299Sbbruce@ucdavis.edu b = m.NoBraceInitialization([123, 456]) 23514299Sbbruce@ucdavis.edu assert b.vec == [123, 456] 23614299Sbbruce@ucdavis.edu 23712391Sjason@lowepower.com 23812391Sjason@lowepower.com@pytest.unsupported_on_pypy 23912391Sjason@lowepower.comdef test_class_refcount(): 24012391Sjason@lowepower.com """Instances must correctly increase/decrease the reference count of their types (#1029)""" 24112391Sjason@lowepower.com from sys import getrefcount 24212391Sjason@lowepower.com 24312391Sjason@lowepower.com class PyDog(m.Dog): 24412391Sjason@lowepower.com pass 24512391Sjason@lowepower.com 24612391Sjason@lowepower.com for cls in m.Dog, PyDog: 24712391Sjason@lowepower.com refcount_1 = getrefcount(cls) 24812391Sjason@lowepower.com molly = [cls("Molly") for _ in range(10)] 24912391Sjason@lowepower.com refcount_2 = getrefcount(cls) 25012391Sjason@lowepower.com 25112391Sjason@lowepower.com del molly 25212391Sjason@lowepower.com pytest.gc_collect() 25312391Sjason@lowepower.com refcount_3 = getrefcount(cls) 25412391Sjason@lowepower.com 25512391Sjason@lowepower.com assert refcount_1 == refcount_3 25612391Sjason@lowepower.com assert refcount_2 > refcount_1 25712391Sjason@lowepower.com 25812391Sjason@lowepower.com 25912391Sjason@lowepower.comdef test_reentrant_implicit_conversion_failure(msg): 26012391Sjason@lowepower.com # ensure that there is no runaway reentrant implicit conversion (#1035) 26112391Sjason@lowepower.com with pytest.raises(TypeError) as excinfo: 26212391Sjason@lowepower.com m.BogusImplicitConversion(0) 26314299Sbbruce@ucdavis.edu assert msg(excinfo.value) == ''' 26414299Sbbruce@ucdavis.edu __init__(): incompatible constructor arguments. The following argument types are supported: 26514299Sbbruce@ucdavis.edu 1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion) 26612391Sjason@lowepower.com 26714299Sbbruce@ucdavis.edu Invoked with: 0 26814299Sbbruce@ucdavis.edu ''' 26914299Sbbruce@ucdavis.edu 27014299Sbbruce@ucdavis.edu 27114299Sbbruce@ucdavis.edudef test_error_after_conversions(): 27214299Sbbruce@ucdavis.edu with pytest.raises(TypeError) as exc_info: 27314299Sbbruce@ucdavis.edu m.test_error_after_conversions("hello") 27414299Sbbruce@ucdavis.edu assert str(exc_info.value).startswith( 27514299Sbbruce@ucdavis.edu "Unable to convert function return value to a Python type!") 27614299Sbbruce@ucdavis.edu 27714299Sbbruce@ucdavis.edu 27814299Sbbruce@ucdavis.edudef test_aligned(): 27914299Sbbruce@ucdavis.edu if hasattr(m, "Aligned"): 28014299Sbbruce@ucdavis.edu p = m.Aligned().ptr() 28114299Sbbruce@ucdavis.edu assert p % 1024 == 0 282