mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
functions: Add doc on incorrect argument index (#2979)
test_call_policies: Explicitly check free-functions and static methods
This commit is contained in:
parent
417fd120cc
commit
b6ec0e950c
@ -182,6 +182,9 @@ relies on the ability to create a *weak reference* to the nurse object. When
|
|||||||
the nurse object is not a pybind11-registered type and does not support weak
|
the nurse object is not a pybind11-registered type and does not support weak
|
||||||
references, an exception will be thrown.
|
references, an exception will be thrown.
|
||||||
|
|
||||||
|
If you use an incorrect argument index, you will get a ``RuntimeError`` saying
|
||||||
|
``Could not activate keep_alive!``. You should review the indices you're using.
|
||||||
|
|
||||||
Consider the following example: here, the binding code for a list append
|
Consider the following example: here, the binding code for a list append
|
||||||
operation ties the lifetime of the newly added element to the underlying
|
operation ties the lifetime of the newly added element to the underlying
|
||||||
container:
|
container:
|
||||||
|
@ -51,6 +51,7 @@ TEST_SUBMODULE(call_policies, m) {
|
|||||||
void addChild(Child *) { }
|
void addChild(Child *) { }
|
||||||
Child *returnChild() { return new Child(); }
|
Child *returnChild() { return new Child(); }
|
||||||
Child *returnNullChild() { return nullptr; }
|
Child *returnNullChild() { return nullptr; }
|
||||||
|
static Child *staticFunction(Parent*) { return new Child(); }
|
||||||
};
|
};
|
||||||
py::class_<Parent>(m, "Parent")
|
py::class_<Parent>(m, "Parent")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
@ -60,7 +61,12 @@ TEST_SUBMODULE(call_policies, m) {
|
|||||||
.def("returnChild", &Parent::returnChild)
|
.def("returnChild", &Parent::returnChild)
|
||||||
.def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>())
|
.def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>())
|
||||||
.def("returnNullChildKeepAliveChild", &Parent::returnNullChild, py::keep_alive<1, 0>())
|
.def("returnNullChildKeepAliveChild", &Parent::returnNullChild, py::keep_alive<1, 0>())
|
||||||
.def("returnNullChildKeepAliveParent", &Parent::returnNullChild, py::keep_alive<0, 1>());
|
.def("returnNullChildKeepAliveParent", &Parent::returnNullChild, py::keep_alive<0, 1>())
|
||||||
|
.def_static(
|
||||||
|
"staticFunction", &Parent::staticFunction, py::keep_alive<1, 0>());
|
||||||
|
|
||||||
|
m.def("free_function", [](Parent*, Child*) {}, py::keep_alive<1, 2>());
|
||||||
|
m.def("invalid_arg_index", []{}, py::keep_alive<0, 1>());
|
||||||
|
|
||||||
#if !defined(PYPY_VERSION)
|
#if !defined(PYPY_VERSION)
|
||||||
// test_alive_gc
|
// test_alive_gc
|
||||||
|
@ -46,6 +46,19 @@ def test_keep_alive_argument(capture):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
p = m.Parent()
|
||||||
|
c = m.Child()
|
||||||
|
assert ConstructorStats.detail_reg_inst() == n_inst + 2
|
||||||
|
m.free_function(p, c)
|
||||||
|
del c
|
||||||
|
assert ConstructorStats.detail_reg_inst() == n_inst + 2
|
||||||
|
del p
|
||||||
|
assert ConstructorStats.detail_reg_inst() == n_inst
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
m.invalid_arg_index()
|
||||||
|
assert str(excinfo.value) == "Could not activate keep_alive!"
|
||||||
|
|
||||||
|
|
||||||
def test_keep_alive_return_value(capture):
|
def test_keep_alive_return_value(capture):
|
||||||
n_inst = ConstructorStats.detail_reg_inst()
|
n_inst = ConstructorStats.detail_reg_inst()
|
||||||
@ -85,6 +98,23 @@ def test_keep_alive_return_value(capture):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
p = m.Parent()
|
||||||
|
assert ConstructorStats.detail_reg_inst() == n_inst + 1
|
||||||
|
with capture:
|
||||||
|
m.Parent.staticFunction(p)
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# https://foss.heptapod.net/pypy/pypy/-/issues/2447
|
# https://foss.heptapod.net/pypy/pypy/-/issues/2447
|
||||||
@pytest.mark.xfail("env.PYPY", reason="_PyObject_GetDictPtr is unimplemented")
|
@pytest.mark.xfail("env.PYPY", reason="_PyObject_GetDictPtr is unimplemented")
|
||||||
|
Loading…
Reference in New Issue
Block a user