mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Support take_ownership for custom type casters given a pointer
This changes the pointer `cast()` in `PYBIND11_TYPE_CASTER` to recognize
the `take_ownership` policy: if casting a pointer with take-ownership,
the `cast()` now recalls `cast()` with a dereferenced rvalue (rather
than the previous code, which was always calling it with a const lvalue
reference), and deletes the pointer after the chained `cast()` is
complete.
This makes code like:
m.def("f", []() { return new std::vector<int>(100, 1); },
py::return_value_policy::take_ownership);
do the expected thing by taking over ownership of the returned pointer
(which is deleted once the chained cast completes).
This commit is contained in:
@@ -477,3 +477,30 @@ def test_unregistered_base_implementations():
|
||||
assert a.rw_value_prop == 49
|
||||
a.increase_value()
|
||||
assert a.ro_value_prop == 1.75
|
||||
|
||||
|
||||
def test_custom_caster_destruction():
|
||||
"""
|
||||
Tests that returning a pointer to a type that gets converted with a custom type caster gets
|
||||
destroyed when the function has py::return_value_policy::take_ownership policy applied.
|
||||
"""
|
||||
import pybind11_tests as m
|
||||
|
||||
cstats = m.destruction_tester_cstats()
|
||||
# This one *doesn't* have take_ownership: the pointer should be used but not destroyed:
|
||||
z = m.custom_caster_no_destroy()
|
||||
assert cstats.alive() == 1 and cstats.default_constructions == 1
|
||||
assert z
|
||||
|
||||
# take_ownership applied: this constructs a new object, casts it, then destroys it:
|
||||
z = m.custom_caster_destroy()
|
||||
assert z
|
||||
assert cstats.default_constructions == 2
|
||||
|
||||
# Same, but with a const pointer return (which should *not* inhibit destruction):
|
||||
z = m.custom_caster_destroy_const()
|
||||
assert z
|
||||
assert cstats.default_constructions == 3
|
||||
|
||||
# Make sure we still only have the original object (from ..._no_destroy()) alive:
|
||||
assert cstats.alive() == 1
|
||||
|
||||
Reference in New Issue
Block a user