You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.0 KiB

2 months ago
  1. import pytest
  2. def test_keep_alive_argument(capture):
  3. from pybind11_tests import Parent, Child, ConstructorStats
  4. n_inst = ConstructorStats.detail_reg_inst()
  5. with capture:
  6. p = Parent()
  7. assert capture == "Allocating parent."
  8. with capture:
  9. p.addChild(Child())
  10. assert ConstructorStats.detail_reg_inst() == n_inst + 1
  11. assert capture == """
  12. Allocating child.
  13. Releasing child.
  14. """
  15. with capture:
  16. del p
  17. assert ConstructorStats.detail_reg_inst() == n_inst
  18. assert capture == "Releasing parent."
  19. with capture:
  20. p = Parent()
  21. assert capture == "Allocating parent."
  22. with capture:
  23. p.addChildKeepAlive(Child())
  24. assert ConstructorStats.detail_reg_inst() == n_inst + 2
  25. assert capture == "Allocating child."
  26. with capture:
  27. del p
  28. assert ConstructorStats.detail_reg_inst() == n_inst
  29. assert capture == """
  30. Releasing parent.
  31. Releasing child.
  32. """
  33. def test_keep_alive_return_value(capture):
  34. from pybind11_tests import Parent, ConstructorStats
  35. n_inst = ConstructorStats.detail_reg_inst()
  36. with capture:
  37. p = Parent()
  38. assert capture == "Allocating parent."
  39. with capture:
  40. p.returnChild()
  41. assert ConstructorStats.detail_reg_inst() == n_inst + 1
  42. assert capture == """
  43. Allocating child.
  44. Releasing child.
  45. """
  46. with capture:
  47. del p
  48. assert ConstructorStats.detail_reg_inst() == n_inst
  49. assert capture == "Releasing parent."
  50. with capture:
  51. p = Parent()
  52. assert capture == "Allocating parent."
  53. with capture:
  54. p.returnChildKeepAlive()
  55. assert ConstructorStats.detail_reg_inst() == n_inst + 2
  56. assert capture == "Allocating child."
  57. with capture:
  58. del p
  59. assert ConstructorStats.detail_reg_inst() == n_inst
  60. assert capture == """
  61. Releasing parent.
  62. Releasing child.
  63. """
  64. # https://bitbucket.org/pypy/pypy/issues/2447
  65. @pytest.unsupported_on_pypy
  66. def test_alive_gc(capture):
  67. from pybind11_tests import ParentGC, Child, ConstructorStats
  68. n_inst = ConstructorStats.detail_reg_inst()
  69. p = ParentGC()
  70. p.addChildKeepAlive(Child())
  71. assert ConstructorStats.detail_reg_inst() == n_inst + 2
  72. lst = [p]
  73. lst.append(lst) # creates a circular reference
  74. with capture:
  75. del p, lst
  76. assert ConstructorStats.detail_reg_inst() == n_inst
  77. assert capture == """
  78. Releasing parent.
  79. Releasing child.
  80. """
  81. def test_alive_gc_derived(capture):
  82. from pybind11_tests import Parent, Child, ConstructorStats
  83. class Derived(Parent):
  84. pass
  85. n_inst = ConstructorStats.detail_reg_inst()
  86. p = Derived()
  87. p.addChildKeepAlive(Child())
  88. assert ConstructorStats.detail_reg_inst() == n_inst + 2
  89. lst = [p]
  90. lst.append(lst) # creates a circular reference
  91. with capture:
  92. del p, lst
  93. assert ConstructorStats.detail_reg_inst() == n_inst
  94. assert capture == """
  95. Releasing parent.
  96. Releasing child.
  97. """
  98. def test_alive_gc_multi_derived(capture):
  99. from pybind11_tests import Parent, Child, ConstructorStats
  100. class Derived(Parent, Child):
  101. pass
  102. n_inst = ConstructorStats.detail_reg_inst()
  103. p = Derived()
  104. p.addChildKeepAlive(Child())
  105. # +3 rather than +2 because Derived corresponds to two registered instances
  106. assert ConstructorStats.detail_reg_inst() == n_inst + 3
  107. lst = [p]
  108. lst.append(lst) # creates a circular reference
  109. with capture:
  110. del p, lst
  111. assert ConstructorStats.detail_reg_inst() == n_inst
  112. assert capture == """
  113. Releasing parent.
  114. Releasing child.
  115. """
  116. def test_return_none(capture):
  117. from pybind11_tests import Parent, ConstructorStats
  118. n_inst = ConstructorStats.detail_reg_inst()
  119. with capture:
  120. p = Parent()
  121. assert capture == "Allocating parent."
  122. with capture:
  123. p.returnNullChildKeepAliveChild()
  124. assert ConstructorStats.detail_reg_inst() == n_inst + 1
  125. assert capture == ""
  126. with capture:
  127. del p
  128. assert ConstructorStats.detail_reg_inst() == n_inst
  129. assert capture == "Releasing parent."
  130. with capture:
  131. p = Parent()
  132. assert capture == "Allocating parent."
  133. with capture:
  134. p.returnNullChildKeepAliveParent()
  135. assert ConstructorStats.detail_reg_inst() == n_inst + 1
  136. assert capture == ""
  137. with capture:
  138. del p
  139. assert ConstructorStats.detail_reg_inst() == n_inst
  140. assert capture == "Releasing parent."
  141. def test_call_guard():
  142. from pybind11_tests import call_policies
  143. assert call_policies.unguarded_call() == "unguarded"
  144. assert call_policies.guarded_call() == "guarded"
  145. assert call_policies.multiple_guards_correct_order() == "guarded & guarded"
  146. assert call_policies.multiple_guards_wrong_order() == "unguarded & guarded"
  147. if hasattr(call_policies, "with_gil"):
  148. assert call_policies.with_gil() == "GIL held"
  149. assert call_policies.without_gil() == "GIL released"