123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- import pytest
- from pybind11_tests import call_policies as m
- from pybind11_tests import ConstructorStats, UserType
- def test_keep_alive_argument(capture):
- n_inst = ConstructorStats.detail_reg_inst()
- with capture:
- p = m.Parent()
- assert capture == "Allocating parent."
- with capture:
- p.addChild(m.Child())
- assert ConstructorStats.detail_reg_inst() == n_inst + 1
- assert capture == """
- Allocating child.
- Releasing child.
- """
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == "Releasing parent."
- with capture:
- p = m.Parent()
- assert capture == "Allocating parent."
- with capture:
- p.addChildKeepAlive(m.Child())
- assert ConstructorStats.detail_reg_inst() == n_inst + 2
- assert capture == "Allocating child."
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == """
- Releasing parent.
- Releasing child.
- """
- def test_keep_alive_return_value(capture):
- n_inst = ConstructorStats.detail_reg_inst()
- with capture:
- p = m.Parent()
- assert capture == "Allocating parent."
- with capture:
- p.returnChild()
- assert ConstructorStats.detail_reg_inst() == n_inst + 1
- assert capture == """
- Allocating child.
- Releasing child.
- """
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == "Releasing parent."
- with capture:
- p = m.Parent()
- assert capture == "Allocating parent."
- with capture:
- p.returnChildKeepAlive()
- assert ConstructorStats.detail_reg_inst() == n_inst + 2
- assert capture == "Allocating child."
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == """
- Releasing parent.
- Releasing child.
- """
- def test_keep_alive_single():
- """Issue #1251 - patients are stored multiple times when given to the same nurse"""
- nurse, p1, p2 = UserType(), UserType(), UserType()
- b = m.refcount(nurse)
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b, b]
- m.add_patient(nurse, p1)
- assert m.get_patients(nurse) == [p1, ]
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b + 1, b]
- m.add_patient(nurse, p1)
- assert m.get_patients(nurse) == [p1, ]
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b + 1, b]
- m.add_patient(nurse, p1)
- assert m.get_patients(nurse) == [p1, ]
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b + 1, b]
- m.add_patient(nurse, p2)
- assert m.get_patients(nurse) == [p1, p2]
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b + 1, b + 1]
- m.add_patient(nurse, p2)
- assert m.get_patients(nurse) == [p1, p2]
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b + 1, b + 1]
- m.add_patient(nurse, p2)
- m.add_patient(nurse, p1)
- assert m.get_patients(nurse) == [p1, p2]
- assert [m.refcount(nurse), m.refcount(p1), m.refcount(p2)] == [b, b + 1, b + 1]
- del nurse
- assert [m.refcount(p1), m.refcount(p2)] == [b, b]
- # https://bitbucket.org/pypy/pypy/issues/2447
- @pytest.unsupported_on_pypy
- def test_alive_gc(capture):
- n_inst = ConstructorStats.detail_reg_inst()
- p = m.ParentGC()
- p.addChildKeepAlive(m.Child())
- assert ConstructorStats.detail_reg_inst() == n_inst + 2
- lst = [p]
- lst.append(lst) # creates a circular reference
- with capture:
- del p, lst
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == """
- Releasing parent.
- Releasing child.
- """
- def test_alive_gc_derived(capture):
- class Derived(m.Parent):
- pass
- n_inst = ConstructorStats.detail_reg_inst()
- p = Derived()
- p.addChildKeepAlive(m.Child())
- assert ConstructorStats.detail_reg_inst() == n_inst + 2
- lst = [p]
- lst.append(lst) # creates a circular reference
- with capture:
- del p, lst
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == """
- Releasing parent.
- Releasing child.
- """
- def test_alive_gc_multi_derived(capture):
- class Derived(m.Parent, m.Child):
- def __init__(self):
- m.Parent.__init__(self)
- m.Child.__init__(self)
- n_inst = ConstructorStats.detail_reg_inst()
- p = Derived()
- p.addChildKeepAlive(m.Child())
- # +3 rather than +2 because Derived corresponds to two registered instances
- assert ConstructorStats.detail_reg_inst() == n_inst + 3
- lst = [p]
- lst.append(lst) # creates a circular reference
- with capture:
- del p, lst
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == """
- Releasing parent.
- Releasing child.
- Releasing child.
- """
- def test_return_none(capture):
- n_inst = ConstructorStats.detail_reg_inst()
- with capture:
- p = m.Parent()
- assert capture == "Allocating parent."
- with capture:
- p.returnNullChildKeepAliveChild()
- assert ConstructorStats.detail_reg_inst() == n_inst + 1
- assert capture == ""
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == "Releasing parent."
- with capture:
- p = m.Parent()
- assert capture == "Allocating parent."
- with capture:
- p.returnNullChildKeepAliveParent()
- assert ConstructorStats.detail_reg_inst() == n_inst + 1
- assert capture == ""
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == "Releasing parent."
- def test_keep_alive_constructor(capture):
- n_inst = ConstructorStats.detail_reg_inst()
- with capture:
- p = m.Parent(m.Child())
- assert ConstructorStats.detail_reg_inst() == n_inst + 2
- assert capture == """
- Allocating child.
- Allocating parent.
- """
- with capture:
- del p
- assert ConstructorStats.detail_reg_inst() == n_inst
- assert capture == """
- Releasing parent.
- Releasing child.
- """
- def test_call_guard():
- assert m.unguarded_call() == "unguarded"
- assert m.guarded_call() == "guarded"
- assert m.multiple_guards_correct_order() == "guarded & guarded"
- assert m.multiple_guards_wrong_order() == "unguarded & guarded"
- if hasattr(m, "with_gil"):
- assert m.with_gil() == "GIL held"
- assert m.without_gil() == "GIL released"
|