Skip to content

Commit f15ba34

Browse files
committed
array: set exception message on failure
When attempting to get a raw array pointer we return nullptr if given a nullptr, which triggers an error_already_set(), but we haven't set an exception message, which results in "Unknown internal error". Callers that want explicit allowing of a nullptr here already handle it (by clearing the exception after the call).
1 parent 4c72ec2 commit f15ba34

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

include/pybind11/numpy.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,10 @@ class array : public buffer {
702702

703703
/// Create array from any object -- always returns a new reference
704704
static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) {
705-
if (ptr == nullptr)
705+
if (ptr == nullptr) {
706+
PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array from a nullptr");
706707
return nullptr;
708+
}
707709
return detail::npy_api::get().PyArray_FromAny_(
708710
ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);
709711
}
@@ -808,8 +810,10 @@ template <typename T, int ExtraFlags = array::forcecast> class array_t : public
808810
protected:
809811
/// Create array from any object -- always returns a new reference
810812
static PyObject *raw_array_t(PyObject *ptr) {
811-
if (ptr == nullptr)
813+
if (ptr == nullptr) {
814+
PyErr_SetString(PyExc_ValueError, "cannot create a pybind11::array_t from a nullptr");
812815
return nullptr;
816+
}
813817
return detail::npy_api::get().PyArray_FromAny_(
814818
ptr, dtype::of<T>().release().ptr(), 0, 0,
815819
detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);

tests/test_numpy_array.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,4 +264,8 @@ test_initializer numpy_array([](py::module &m) {
264264
sm.def("array_auxiliaries2", [](py::array_t<double> a) {
265265
return auxiliaries(a, a);
266266
});
267+
268+
// Issue #785: Uninformative "Unknown internal error" exception when constructing array from empty object:
269+
sm.def("array_fail_test", []() { return py::array(py::object()); });
270+
sm.def("array_t_fail_test", []() { return py::array_t<double>(py::object()); });
267271
});

tests/test_numpy_array.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,15 @@ def test_array_unchecked_dyn_dims(msg):
377377

378378
assert proxy_auxiliaries2_dyn(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]
379379
assert proxy_auxiliaries2_dyn(z1) == array_auxiliaries2(z1)
380+
381+
382+
def test_array_failure():
383+
from pybind11_tests.array import array_fail_test, array_t_fail_test
384+
385+
with pytest.raises(ValueError) as excinfo:
386+
array_fail_test()
387+
assert str(excinfo.value) == 'cannot create a pybind11::array from a nullptr'
388+
389+
with pytest.raises(ValueError) as excinfo:
390+
array_t_fail_test()
391+
assert str(excinfo.value) == 'cannot create a pybind11::array_t from a nullptr'

0 commit comments

Comments
 (0)