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      )