mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
fix: better exception and error handling for capsules (#3825)
* Make capsule errors better match python
This commit is contained in:
parent
47079b9e7b
commit
146695a904
@ -1288,7 +1288,8 @@ public:
|
|||||||
static pybind11::dtype dtype() {
|
static pybind11::dtype dtype() {
|
||||||
list shape;
|
list shape;
|
||||||
array_info<T>::append_extents(shape);
|
array_info<T>::append_extents(shape);
|
||||||
return pybind11::dtype::from_args(pybind11::make_tuple(base_descr::dtype(), shape));
|
return pybind11::dtype::from_args(
|
||||||
|
pybind11::make_tuple(base_descr::dtype(), std::move(shape)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1574,7 +1574,7 @@ public:
|
|||||||
void (*destructor)(PyObject *) = nullptr)
|
void (*destructor)(PyObject *) = nullptr)
|
||||||
: object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {
|
: object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1582,34 +1582,42 @@ public:
|
|||||||
capsule(const void *value, void (*destruct)(PyObject *))
|
capsule(const void *value, void (*destruct)(PyObject *))
|
||||||
: object(PyCapsule_New(const_cast<void *>(value), nullptr, destruct), stolen_t{}) {
|
: object(PyCapsule_New(const_cast<void *>(value), nullptr, destruct), stolen_t{}) {
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
capsule(const void *value, void (*destructor)(void *)) {
|
capsule(const void *value, void (*destructor)(void *)) {
|
||||||
m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {
|
m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {
|
||||||
auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
|
auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));
|
||||||
|
if (destructor == nullptr) {
|
||||||
|
if (PyErr_Occurred()) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
|
pybind11_fail("Unable to get capsule context");
|
||||||
|
}
|
||||||
void *ptr = PyCapsule_GetPointer(o, nullptr);
|
void *ptr = PyCapsule_GetPointer(o, nullptr);
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
destructor(ptr);
|
destructor(ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_ptr) {
|
if (!m_ptr || PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
|
||||||
|
|
||||||
if (PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) {
|
|
||||||
pybind11_fail("Could not set capsule context!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit capsule(void (*destructor)()) {
|
explicit capsule(void (*destructor)()) {
|
||||||
m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {
|
m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {
|
||||||
auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, nullptr));
|
auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, nullptr));
|
||||||
|
if (destructor == nullptr) {
|
||||||
|
throw error_already_set();
|
||||||
|
}
|
||||||
destructor();
|
destructor();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!m_ptr) {
|
if (!m_ptr) {
|
||||||
pybind11_fail("Could not allocate capsule object!");
|
throw error_already_set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1624,8 +1632,7 @@ public:
|
|||||||
const auto *name = this->name();
|
const auto *name = this->name();
|
||||||
T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));
|
T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
PyErr_Clear();
|
throw error_already_set();
|
||||||
pybind11_fail("Unable to extract capsule contents!");
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1633,8 +1640,7 @@ public:
|
|||||||
/// Replaces a capsule's pointer *without* calling the destructor on the existing one.
|
/// Replaces a capsule's pointer *without* calling the destructor on the existing one.
|
||||||
void set_pointer(const void *value) {
|
void set_pointer(const void *value) {
|
||||||
if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {
|
if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {
|
||||||
PyErr_Clear();
|
throw error_already_set();
|
||||||
pybind11_fail("Could not set capsule pointer");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user