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  # noqa: F401
0004 from pybind11_tests import ConstructorStats
0005 from pybind11_tests import call_policies as m
0006 
0007 
0008 @pytest.mark.xfail("env.PYPY", reason="sometimes comes out 1 off on PyPy", strict=False)
0009 def test_keep_alive_argument(capture):
0010     n_inst = ConstructorStats.detail_reg_inst()
0011     with capture:
0012         p = m.Parent()
0013     assert capture == "Allocating parent."
0014     with capture:
0015         p.addChild(m.Child())
0016         assert ConstructorStats.detail_reg_inst() == n_inst + 1
0017     assert (
0018         capture
0019         == """
0020         Allocating child.
0021         Releasing child.
0022     """
0023     )
0024     with capture:
0025         del p
0026         assert ConstructorStats.detail_reg_inst() == n_inst
0027     assert capture == "Releasing parent."
0028 
0029     with capture:
0030         p = m.Parent()
0031     assert capture == "Allocating parent."
0032     with capture:
0033         p.addChildKeepAlive(m.Child())
0034         assert ConstructorStats.detail_reg_inst() == n_inst + 2
0035     assert capture == "Allocating child."
0036     with capture:
0037         del p
0038         assert ConstructorStats.detail_reg_inst() == n_inst
0039     assert (
0040         capture
0041         == """
0042         Releasing parent.
0043         Releasing child.
0044     """
0045     )
0046 
0047     p = m.Parent()
0048     c = m.Child()
0049     assert ConstructorStats.detail_reg_inst() == n_inst + 2
0050     m.free_function(p, c)
0051     del c
0052     assert ConstructorStats.detail_reg_inst() == n_inst + 2
0053     del p
0054     assert ConstructorStats.detail_reg_inst() == n_inst
0055 
0056     with pytest.raises(RuntimeError) as excinfo:
0057         m.invalid_arg_index()
0058     assert str(excinfo.value) == "Could not activate keep_alive!"
0059 
0060 
0061 def test_keep_alive_return_value(capture):
0062     n_inst = ConstructorStats.detail_reg_inst()
0063     with capture:
0064         p = m.Parent()
0065     assert capture == "Allocating parent."
0066     with capture:
0067         p.returnChild()
0068         assert ConstructorStats.detail_reg_inst() == n_inst + 1
0069     assert (
0070         capture
0071         == """
0072         Allocating child.
0073         Releasing child.
0074     """
0075     )
0076     with capture:
0077         del p
0078         assert ConstructorStats.detail_reg_inst() == n_inst
0079     assert capture == "Releasing parent."
0080 
0081     with capture:
0082         p = m.Parent()
0083     assert capture == "Allocating parent."
0084     with capture:
0085         p.returnChildKeepAlive()
0086         assert ConstructorStats.detail_reg_inst() == n_inst + 2
0087     assert capture == "Allocating child."
0088     with capture:
0089         del p
0090         assert ConstructorStats.detail_reg_inst() == n_inst
0091     assert (
0092         capture
0093         == """
0094         Releasing parent.
0095         Releasing child.
0096     """
0097     )
0098 
0099     p = m.Parent()
0100     assert ConstructorStats.detail_reg_inst() == n_inst + 1
0101     with capture:
0102         m.Parent.staticFunction(p)
0103         assert ConstructorStats.detail_reg_inst() == n_inst + 2
0104     assert capture == "Allocating child."
0105     with capture:
0106         del p
0107         assert ConstructorStats.detail_reg_inst() == n_inst
0108     assert (
0109         capture
0110         == """
0111         Releasing parent.
0112         Releasing child.
0113     """
0114     )
0115 
0116 
0117 # https://foss.heptapod.net/pypy/pypy/-/issues/2447
0118 @pytest.mark.xfail("env.PYPY", reason="_PyObject_GetDictPtr is unimplemented")
0119 def test_alive_gc(capture):
0120     n_inst = ConstructorStats.detail_reg_inst()
0121     p = m.ParentGC()
0122     p.addChildKeepAlive(m.Child())
0123     assert ConstructorStats.detail_reg_inst() == n_inst + 2
0124     lst = [p]
0125     lst.append(lst)  # creates a circular reference
0126     with capture:
0127         del p, lst
0128         assert ConstructorStats.detail_reg_inst() == n_inst
0129     assert (
0130         capture
0131         == """
0132         Releasing parent.
0133         Releasing child.
0134     """
0135     )
0136 
0137 
0138 def test_alive_gc_derived(capture):
0139     class Derived(m.Parent):
0140         pass
0141 
0142     n_inst = ConstructorStats.detail_reg_inst()
0143     p = Derived()
0144     p.addChildKeepAlive(m.Child())
0145     assert ConstructorStats.detail_reg_inst() == n_inst + 2
0146     lst = [p]
0147     lst.append(lst)  # creates a circular reference
0148     with capture:
0149         del p, lst
0150         assert ConstructorStats.detail_reg_inst() == n_inst
0151     assert (
0152         capture
0153         == """
0154         Releasing parent.
0155         Releasing child.
0156     """
0157     )
0158 
0159 
0160 def test_alive_gc_multi_derived(capture):
0161     class Derived(m.Parent, m.Child):
0162         def __init__(self):
0163             m.Parent.__init__(self)
0164             m.Child.__init__(self)
0165 
0166     n_inst = ConstructorStats.detail_reg_inst()
0167     p = Derived()
0168     p.addChildKeepAlive(m.Child())
0169     # +3 rather than +2 because Derived corresponds to two registered instances
0170     assert ConstructorStats.detail_reg_inst() == n_inst + 3
0171     lst = [p]
0172     lst.append(lst)  # creates a circular reference
0173     with capture:
0174         del p, lst
0175         assert ConstructorStats.detail_reg_inst() == n_inst
0176     assert (
0177         capture
0178         == """
0179         Releasing parent.
0180         Releasing child.
0181         Releasing child.
0182     """
0183     )
0184 
0185 
0186 def test_return_none(capture):
0187     n_inst = ConstructorStats.detail_reg_inst()
0188     with capture:
0189         p = m.Parent()
0190     assert capture == "Allocating parent."
0191     with capture:
0192         p.returnNullChildKeepAliveChild()
0193         assert ConstructorStats.detail_reg_inst() == n_inst + 1
0194     assert capture == ""
0195     with capture:
0196         del p
0197         assert ConstructorStats.detail_reg_inst() == n_inst
0198     assert capture == "Releasing parent."
0199 
0200     with capture:
0201         p = m.Parent()
0202     assert capture == "Allocating parent."
0203     with capture:
0204         p.returnNullChildKeepAliveParent()
0205         assert ConstructorStats.detail_reg_inst() == n_inst + 1
0206     assert capture == ""
0207     with capture:
0208         del p
0209         assert ConstructorStats.detail_reg_inst() == n_inst
0210     assert capture == "Releasing parent."
0211 
0212 
0213 def test_keep_alive_constructor(capture):
0214     n_inst = ConstructorStats.detail_reg_inst()
0215 
0216     with capture:
0217         p = m.Parent(m.Child())
0218         assert ConstructorStats.detail_reg_inst() == n_inst + 2
0219     assert (
0220         capture
0221         == """
0222         Allocating child.
0223         Allocating parent.
0224     """
0225     )
0226     with capture:
0227         del p
0228         assert ConstructorStats.detail_reg_inst() == n_inst
0229     assert (
0230         capture
0231         == """
0232         Releasing parent.
0233         Releasing child.
0234     """
0235     )
0236 
0237 
0238 def test_call_guard():
0239     assert m.unguarded_call() == "unguarded"
0240     assert m.guarded_call() == "guarded"
0241 
0242     assert m.multiple_guards_correct_order() == "guarded & guarded"
0243     assert m.multiple_guards_wrong_order() == "unguarded & guarded"
0244 
0245     if hasattr(m, "with_gil"):
0246         assert m.with_gil() == "GIL held"
0247         assert m.without_gil() == "GIL released"