mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Fix dtype string leak
`PyArray_DescrConverter_` doesn't steal a reference to the argument, and so the passed arguments shouldn't be `.release()`d.
This commit is contained in:
parent
0aef6422a3
commit
c6a57c10d1
@ -440,7 +440,7 @@ public:
|
|||||||
/// This is essentially the same as calling numpy.dtype(args) in Python.
|
/// This is essentially the same as calling numpy.dtype(args) in Python.
|
||||||
static dtype from_args(object args) {
|
static dtype from_args(object args) {
|
||||||
PyObject *ptr = nullptr;
|
PyObject *ptr = nullptr;
|
||||||
if (!detail::npy_api::get().PyArray_DescrConverter_(args.release().ptr(), &ptr) || !ptr)
|
if (!detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) || !ptr)
|
||||||
throw error_already_set();
|
throw error_already_set();
|
||||||
return reinterpret_steal<dtype>(ptr);
|
return reinterpret_steal<dtype>(ptr);
|
||||||
}
|
}
|
||||||
|
@ -448,4 +448,7 @@ TEST_SUBMODULE(numpy_dtypes, m) {
|
|||||||
|
|
||||||
// test_register_dtype
|
// test_register_dtype
|
||||||
m.def("register_dtype", []() { PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_); });
|
m.def("register_dtype", []() { PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_); });
|
||||||
|
|
||||||
|
// test_str_leak
|
||||||
|
m.def("dtype_wrapper", [](py::object d) { return py::dtype::from_args(std::move(d)); });
|
||||||
}
|
}
|
||||||
|
@ -293,6 +293,19 @@ def test_register_dtype():
|
|||||||
assert 'dtype is already registered' in str(excinfo.value)
|
assert 'dtype is already registered' in str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.unsupported_on_pypy
|
||||||
|
def test_str_leak():
|
||||||
|
from sys import getrefcount
|
||||||
|
fmt = "f4"
|
||||||
|
pytest.gc_collect()
|
||||||
|
start = getrefcount(fmt)
|
||||||
|
d = m.dtype_wrapper(fmt)
|
||||||
|
assert d is np.dtype("f4")
|
||||||
|
del d
|
||||||
|
pytest.gc_collect()
|
||||||
|
assert getrefcount(fmt) == start
|
||||||
|
|
||||||
|
|
||||||
@pytest.requires_numpy
|
@pytest.requires_numpy
|
||||||
def test_compare_buffer_info():
|
def test_compare_buffer_info():
|
||||||
assert all(m.compare_buffer_info())
|
assert all(m.compare_buffer_info())
|
||||||
|
Loading…
Reference in New Issue
Block a user