Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:52

0001 import pytest
0002 
0003 import env
0004 from pybind11_tests import ConstructorStats, UserType
0005 from pybind11_tests import class_ as m
0006 
0007 
0008 def test_obj_class_name():
0009     if env.PYPY:
0010         expected_name = "UserType"
0011     else:
0012         expected_name = "pybind11_tests.UserType"
0013     assert m.obj_class_name(UserType(1)) == expected_name
0014     assert m.obj_class_name(UserType) == expected_name
0015 
0016 
0017 def test_repr():
0018     assert "pybind11_type" in repr(type(UserType))
0019     assert "UserType" in repr(UserType)
0020 
0021 
0022 def test_instance(msg):
0023     with pytest.raises(TypeError) as excinfo:
0024         m.NoConstructor()
0025     assert msg(excinfo.value) == "m.class_.NoConstructor: No constructor defined!"
0026 
0027     instance = m.NoConstructor.new_instance()
0028 
0029     cstats = ConstructorStats.get(m.NoConstructor)
0030     assert cstats.alive() == 1
0031     del instance
0032     assert cstats.alive() == 0
0033 
0034 
0035 def test_instance_new(msg):
0036     instance = m.NoConstructorNew()  # .__new__(m.NoConstructor.__class__)
0037     cstats = ConstructorStats.get(m.NoConstructorNew)
0038     assert cstats.alive() == 1
0039     del instance
0040     assert cstats.alive() == 0
0041 
0042 
0043 def test_type():
0044     assert m.check_type(1) == m.DerivedClass1
0045     with pytest.raises(RuntimeError) as execinfo:
0046         m.check_type(0)
0047 
0048     assert "pybind11::detail::get_type_info: unable to find type info" in str(
0049         execinfo.value
0050     )
0051     assert "Invalid" in str(execinfo.value)
0052 
0053     # Currently not supported
0054     # See https://github.com/pybind/pybind11/issues/2486
0055     # assert m.check_type(2) == int
0056 
0057 
0058 def test_type_of_py():
0059     assert m.get_type_of(1) == int
0060     assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1
0061     assert m.get_type_of(int) == type
0062 
0063 
0064 def test_type_of_classic():
0065     assert m.get_type_classic(1) == int
0066     assert m.get_type_classic(m.DerivedClass1()) == m.DerivedClass1
0067     assert m.get_type_classic(int) == type
0068 
0069 
0070 def test_type_of_py_nodelete():
0071     # If the above test deleted the class, this will segfault
0072     assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1
0073 
0074 
0075 def test_as_type_py():
0076     assert m.as_type(int) == int
0077 
0078     with pytest.raises(TypeError):
0079         assert m.as_type(1) == int
0080 
0081     with pytest.raises(TypeError):
0082         assert m.as_type(m.DerivedClass1()) == m.DerivedClass1
0083 
0084 
0085 def test_docstrings(doc):
0086     assert doc(UserType) == "A `py::class_` type for testing"
0087     assert UserType.__name__ == "UserType"
0088     assert UserType.__module__ == "pybind11_tests"
0089     assert UserType.get_value.__name__ == "get_value"
0090     assert UserType.get_value.__module__ == "pybind11_tests"
0091 
0092     assert (
0093         doc(UserType.get_value)
0094         == """
0095         get_value(self: m.UserType) -> int
0096 
0097         Get value using a method
0098     """
0099     )
0100     assert doc(UserType.value) == "Get/set value using a property"
0101 
0102     assert (
0103         doc(m.NoConstructor.new_instance)
0104         == """
0105         new_instance() -> m.class_.NoConstructor
0106 
0107         Return an instance
0108     """
0109     )
0110 
0111 
0112 def test_qualname(doc):
0113     """Tests that a properly qualified name is set in __qualname__ and that
0114     generated docstrings properly use it and the module name"""
0115     assert m.NestBase.__qualname__ == "NestBase"
0116     assert m.NestBase.Nested.__qualname__ == "NestBase.Nested"
0117 
0118     assert (
0119         doc(m.NestBase.__init__)
0120         == """
0121         __init__(self: m.class_.NestBase) -> None
0122     """
0123     )
0124     assert (
0125         doc(m.NestBase.g)
0126         == """
0127         g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None
0128     """
0129     )
0130     assert (
0131         doc(m.NestBase.Nested.__init__)
0132         == """
0133         __init__(self: m.class_.NestBase.Nested) -> None
0134     """
0135     )
0136     assert (
0137         doc(m.NestBase.Nested.fn)
0138         == """
0139         fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
0140     """
0141     )
0142     assert (
0143         doc(m.NestBase.Nested.fa)
0144         == """
0145         fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
0146     """
0147     )
0148     assert m.NestBase.__module__ == "pybind11_tests.class_"
0149     assert m.NestBase.Nested.__module__ == "pybind11_tests.class_"
0150 
0151 
0152 def test_inheritance(msg):
0153     roger = m.Rabbit("Rabbit")
0154     assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot"
0155     assert m.pet_name_species(roger) == "Rabbit is a parrot"
0156 
0157     polly = m.Pet("Polly", "parrot")
0158     assert polly.name() + " is a " + polly.species() == "Polly is a parrot"
0159     assert m.pet_name_species(polly) == "Polly is a parrot"
0160 
0161     molly = m.Dog("Molly")
0162     assert molly.name() + " is a " + molly.species() == "Molly is a dog"
0163     assert m.pet_name_species(molly) == "Molly is a dog"
0164 
0165     fred = m.Hamster("Fred")
0166     assert fred.name() + " is a " + fred.species() == "Fred is a rodent"
0167 
0168     assert m.dog_bark(molly) == "Woof!"
0169 
0170     with pytest.raises(TypeError) as excinfo:
0171         m.dog_bark(polly)
0172     assert (
0173         msg(excinfo.value)
0174         == """
0175         dog_bark(): incompatible function arguments. The following argument types are supported:
0176             1. (arg0: m.class_.Dog) -> str
0177 
0178         Invoked with: <m.class_.Pet object at 0>
0179     """
0180     )
0181 
0182     with pytest.raises(TypeError) as excinfo:
0183         m.Chimera("lion", "goat")
0184     assert "No constructor defined!" in str(excinfo.value)
0185 
0186 
0187 def test_inheritance_init(msg):
0188 
0189     # Single base
0190     class Python(m.Pet):
0191         def __init__(self):
0192             pass
0193 
0194     with pytest.raises(TypeError) as exc_info:
0195         Python()
0196     expected = "m.class_.Pet.__init__() must be called when overriding __init__"
0197     assert msg(exc_info.value) == expected
0198 
0199     # Multiple bases
0200     class RabbitHamster(m.Rabbit, m.Hamster):
0201         def __init__(self):
0202             m.Rabbit.__init__(self, "RabbitHamster")
0203 
0204     with pytest.raises(TypeError) as exc_info:
0205         RabbitHamster()
0206     expected = "m.class_.Hamster.__init__() must be called when overriding __init__"
0207     assert msg(exc_info.value) == expected
0208 
0209 
0210 def test_automatic_upcasting():
0211     assert type(m.return_class_1()).__name__ == "DerivedClass1"
0212     assert type(m.return_class_2()).__name__ == "DerivedClass2"
0213     assert type(m.return_none()).__name__ == "NoneType"
0214     # Repeat these a few times in a random order to ensure no invalid caching is applied
0215     assert type(m.return_class_n(1)).__name__ == "DerivedClass1"
0216     assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
0217     assert type(m.return_class_n(0)).__name__ == "BaseClass"
0218     assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
0219     assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
0220     assert type(m.return_class_n(0)).__name__ == "BaseClass"
0221     assert type(m.return_class_n(1)).__name__ == "DerivedClass1"
0222 
0223 
0224 def test_isinstance():
0225     objects = [tuple(), dict(), m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4
0226     expected = (True, True, True, True, True, False, False)
0227     assert m.check_instances(objects) == expected
0228 
0229 
0230 def test_mismatched_holder():
0231     import re
0232 
0233     with pytest.raises(RuntimeError) as excinfo:
0234         m.mismatched_holder_1()
0235     assert re.match(
0236         'generic_type: type ".*MismatchDerived1" does not have a non-default '
0237         'holder type while its base ".*MismatchBase1" does',
0238         str(excinfo.value),
0239     )
0240 
0241     with pytest.raises(RuntimeError) as excinfo:
0242         m.mismatched_holder_2()
0243     assert re.match(
0244         'generic_type: type ".*MismatchDerived2" has a non-default holder type '
0245         'while its base ".*MismatchBase2" does not',
0246         str(excinfo.value),
0247     )
0248 
0249 
0250 def test_override_static():
0251     """#511: problem with inheritance + overwritten def_static"""
0252     b = m.MyBase.make()
0253     d1 = m.MyDerived.make2()
0254     d2 = m.MyDerived.make()
0255 
0256     assert isinstance(b, m.MyBase)
0257     assert isinstance(d1, m.MyDerived)
0258     assert isinstance(d2, m.MyDerived)
0259 
0260 
0261 def test_implicit_conversion_life_support():
0262     """Ensure the lifetime of temporary objects created for implicit conversions"""
0263     assert m.implicitly_convert_argument(UserType(5)) == 5
0264     assert m.implicitly_convert_variable(UserType(5)) == 5
0265 
0266     assert "outside a bound function" in m.implicitly_convert_variable_fail(UserType(5))
0267 
0268 
0269 def test_operator_new_delete(capture):
0270     """Tests that class-specific operator new/delete functions are invoked"""
0271 
0272     class SubAliased(m.AliasedHasOpNewDelSize):
0273         pass
0274 
0275     with capture:
0276         a = m.HasOpNewDel()
0277         b = m.HasOpNewDelSize()
0278         d = m.HasOpNewDelBoth()
0279     assert (
0280         capture
0281         == """
0282         A new 8
0283         B new 4
0284         D new 32
0285     """
0286     )
0287     sz_alias = str(m.AliasedHasOpNewDelSize.size_alias)
0288     sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias)
0289     with capture:
0290         c = m.AliasedHasOpNewDelSize()
0291         c2 = SubAliased()
0292     assert capture == ("C new " + sz_noalias + "\n" + "C new " + sz_alias + "\n")
0293 
0294     with capture:
0295         del a
0296         pytest.gc_collect()
0297         del b
0298         pytest.gc_collect()
0299         del d
0300         pytest.gc_collect()
0301     assert (
0302         capture
0303         == """
0304         A delete
0305         B delete 4
0306         D delete
0307     """
0308     )
0309 
0310     with capture:
0311         del c
0312         pytest.gc_collect()
0313         del c2
0314         pytest.gc_collect()
0315     assert capture == ("C delete " + sz_noalias + "\n" + "C delete " + sz_alias + "\n")
0316 
0317 
0318 def test_bind_protected_functions():
0319     """Expose protected member functions to Python using a helper class"""
0320     a = m.ProtectedA()
0321     assert a.foo() == 42
0322 
0323     b = m.ProtectedB()
0324     assert b.foo() == 42
0325     assert m.read_foo(b.void_foo()) == 42
0326     assert m.pointers_equal(b.get_self(), b)
0327 
0328     class C(m.ProtectedB):
0329         def __init__(self):
0330             m.ProtectedB.__init__(self)
0331 
0332         def foo(self):
0333             return 0
0334 
0335     c = C()
0336     assert c.foo() == 0
0337 
0338 
0339 def test_brace_initialization():
0340     """Tests that simple POD classes can be constructed using C++11 brace initialization"""
0341     a = m.BraceInitialization(123, "test")
0342     assert a.field1 == 123
0343     assert a.field2 == "test"
0344 
0345     # Tests that a non-simple class doesn't get brace initialization (if the
0346     # class defines an initializer_list constructor, in particular, it would
0347     # win over the expected constructor).
0348     b = m.NoBraceInitialization([123, 456])
0349     assert b.vec == [123, 456]
0350 
0351 
0352 @pytest.mark.xfail("env.PYPY")
0353 def test_class_refcount():
0354     """Instances must correctly increase/decrease the reference count of their types (#1029)"""
0355     from sys import getrefcount
0356 
0357     class PyDog(m.Dog):
0358         pass
0359 
0360     for cls in m.Dog, PyDog:
0361         refcount_1 = getrefcount(cls)
0362         molly = [cls("Molly") for _ in range(10)]
0363         refcount_2 = getrefcount(cls)
0364 
0365         del molly
0366         pytest.gc_collect()
0367         refcount_3 = getrefcount(cls)
0368 
0369         assert refcount_1 == refcount_3
0370         assert refcount_2 > refcount_1
0371 
0372 
0373 def test_reentrant_implicit_conversion_failure(msg):
0374     # ensure that there is no runaway reentrant implicit conversion (#1035)
0375     with pytest.raises(TypeError) as excinfo:
0376         m.BogusImplicitConversion(0)
0377     assert (
0378         msg(excinfo.value)
0379         == """
0380         __init__(): incompatible constructor arguments. The following argument types are supported:
0381             1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)
0382 
0383         Invoked with: 0
0384     """
0385     )
0386 
0387 
0388 def test_error_after_conversions():
0389     with pytest.raises(TypeError) as exc_info:
0390         m.test_error_after_conversions("hello")
0391     assert str(exc_info.value).startswith(
0392         "Unable to convert function return value to a Python type!"
0393     )
0394 
0395 
0396 def test_aligned():
0397     if hasattr(m, "Aligned"):
0398         p = m.Aligned().ptr()
0399         assert p % 1024 == 0
0400 
0401 
0402 # https://foss.heptapod.net/pypy/pypy/-/issues/2742
0403 @pytest.mark.xfail("env.PYPY")
0404 def test_final():
0405     with pytest.raises(TypeError) as exc_info:
0406 
0407         class PyFinalChild(m.IsFinal):
0408             pass
0409 
0410     assert str(exc_info.value).endswith("is not an acceptable base type")
0411 
0412 
0413 # https://foss.heptapod.net/pypy/pypy/-/issues/2742
0414 @pytest.mark.xfail("env.PYPY")
0415 def test_non_final_final():
0416     with pytest.raises(TypeError) as exc_info:
0417 
0418         class PyNonFinalFinalChild(m.IsNonFinalFinal):
0419             pass
0420 
0421     assert str(exc_info.value).endswith("is not an acceptable base type")
0422 
0423 
0424 # https://github.com/pybind/pybind11/issues/1878
0425 def test_exception_rvalue_abort():
0426     with pytest.raises(RuntimeError):
0427         m.PyPrintDestructor().throw_something()
0428 
0429 
0430 # https://github.com/pybind/pybind11/issues/1568
0431 def test_multiple_instances_with_same_pointer(capture):
0432     n = 100
0433     instances = [m.SamePointer() for _ in range(n)]
0434     for i in range(n):
0435         # We need to reuse the same allocated memory for with a different type,
0436         # to ensure the bug in `deregister_instance_impl` is detected. Otherwise
0437         # `Py_TYPE(self) == Py_TYPE(it->second)` will still succeed, even though
0438         # the `instance` is already deleted.
0439         instances[i] = m.Empty()
0440     # No assert: if this does not trigger the error
0441     #   pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
0442     # and just completes without crashing, we're good.
0443 
0444 
0445 # https://github.com/pybind/pybind11/issues/1624
0446 def test_base_and_derived_nested_scope():
0447     assert issubclass(m.DerivedWithNested, m.BaseWithNested)
0448     assert m.BaseWithNested.Nested != m.DerivedWithNested.Nested
0449     assert m.BaseWithNested.Nested.get_name() == "BaseWithNested::Nested"
0450     assert m.DerivedWithNested.Nested.get_name() == "DerivedWithNested::Nested"
0451 
0452 
0453 def test_register_duplicate_class():
0454     import types
0455 
0456     module_scope = types.ModuleType("module_scope")
0457     with pytest.raises(RuntimeError) as exc_info:
0458         m.register_duplicate_class_name(module_scope)
0459     expected = (
0460         'generic_type: cannot initialize type "Duplicate": '
0461         "an object with that name is already defined"
0462     )
0463     assert str(exc_info.value) == expected
0464     with pytest.raises(RuntimeError) as exc_info:
0465         m.register_duplicate_class_type(module_scope)
0466     expected = 'generic_type: type "YetAnotherDuplicate" is already registered!'
0467     assert str(exc_info.value) == expected
0468 
0469     class ClassScope:
0470         pass
0471 
0472     with pytest.raises(RuntimeError) as exc_info:
0473         m.register_duplicate_nested_class_name(ClassScope)
0474     expected = (
0475         'generic_type: cannot initialize type "DuplicateNested": '
0476         "an object with that name is already defined"
0477     )
0478     assert str(exc_info.value) == expected
0479     with pytest.raises(RuntimeError) as exc_info:
0480         m.register_duplicate_nested_class_type(ClassScope)
0481     expected = 'generic_type: type "YetAnotherDuplicateNested" is already registered!'
0482     assert str(exc_info.value) == expected
0483 
0484 
0485 def test_pr4220_tripped_over_this():
0486     assert (
0487         m.Empty0().get_msg()
0488         == "This is really only meant to exercise successful compilation."
0489     )