Merge branch 'master' into sh_merge_master

This commit is contained in:
Ralf W. Grosse-Kunstleve
2022-04-17 22:16:08 -07:00
7 changed files with 144 additions and 12 deletions

View File

@@ -1004,6 +1004,7 @@ constexpr const char
struct error_scope {
PyObject *type, *value, *trace;
error_scope() { PyErr_Fetch(&type, &value, &trace); }
error_scope(const error_scope &) = delete;
~error_scope() { PyErr_Restore(type, value, trace); }
};

View File

@@ -540,18 +540,16 @@ public:
PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);
explicit dtype(const buffer_info &info) {
dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format)));
dtype descr(_dtype_from_pep3118()(pybind11::str(info.format)));
// If info.itemsize == 0, use the value calculated from the format string
m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize())
.release()
.ptr();
}
explicit dtype(const std::string &format) {
m_ptr = from_args(pybind11::str(format)).release().ptr();
}
explicit dtype(const std::string &format) : dtype(from_args(pybind11::str(format))) {}
explicit dtype(const char *format) : dtype(std::string(format)) {}
explicit dtype(const char *format) : dtype(from_args(pybind11::str(format))) {}
dtype(list names, list formats, list offsets, ssize_t itemsize) {
dict args;
@@ -562,6 +560,13 @@ public:
m_ptr = from_args(std::move(args)).release().ptr();
}
explicit dtype(int typenum)
: object(detail::npy_api::get().PyArray_DescrFromType_(typenum), stolen_t{}) {
if (m_ptr == nullptr) {
throw error_already_set();
}
}
/// This is essentially the same as calling numpy.dtype(args) in Python.
static dtype from_args(object args) {
PyObject *ptr = nullptr;
@@ -596,6 +601,23 @@ public:
return detail::array_descriptor_proxy(m_ptr)->type;
}
/// type number of dtype.
ssize_t num() const {
// Note: The signature, `dtype::num` follows the naming of NumPy's public
// Python API (i.e., ``dtype.num``), rather than its internal
// C API (``PyArray_Descr::type_num``).
return detail::array_descriptor_proxy(m_ptr)->type_num;
}
/// Single character for byteorder
char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; }
/// Alignment of the data type
int alignment() const { return detail::array_descriptor_proxy(m_ptr)->alignment; }
/// Flags for the array descriptor
char flags() const { return detail::array_descriptor_proxy(m_ptr)->flags; }
private:
static object _dtype_from_pep3118() {
static PyObject *obj = module_::import("numpy.core._internal")
@@ -614,7 +636,7 @@ private:
}
struct field_descr {
PYBIND11_STR_TYPE name;
pybind11::str name;
object format;
pybind11::int_ offset;
};
@@ -629,7 +651,7 @@ private:
continue;
}
field_descriptors.push_back(
{(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset});
{(pybind11::str) name, format.strip_padding(format.itemsize()), offset});
}
std::sort(field_descriptors.begin(),
@@ -1335,7 +1357,7 @@ PYBIND11_NOINLINE void register_structured_dtype(any_container<field_descriptor>
pybind11_fail(std::string("NumPy: unsupported field dtype: `") + field.name + "` @ "
+ tinfo.name());
}
names.append(PYBIND11_STR_TYPE(field.name));
names.append(pybind11::str(field.name));
formats.append(field.descr);
offsets.append(pybind11::int_(field.offset));
}

View File

@@ -1588,7 +1588,8 @@ public:
}
pybind11_fail("Unable to get capsule context");
}
void *ptr = PyCapsule_GetPointer(o, nullptr);
const char *name = get_name_in_error_scope(o);
void *ptr = PyCapsule_GetPointer(o, name);
if (ptr == nullptr) {
throw error_already_set();
}
@@ -1602,7 +1603,8 @@ public:
explicit capsule(void (*destructor)()) {
m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {
auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, nullptr));
const char *name = get_name_in_error_scope(o);
auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, name));
if (destructor == nullptr) {
throw error_already_set();
}
@@ -1637,7 +1639,33 @@ public:
}
}
const char *name() const { return PyCapsule_GetName(m_ptr); }
const char *name() const {
const char *name = PyCapsule_GetName(m_ptr);
if ((name == nullptr) && PyErr_Occurred()) {
throw error_already_set();
}
return name;
}
/// Replaces a capsule's name *without* calling the destructor on the existing one.
void set_name(const char *new_name) {
if (PyCapsule_SetName(m_ptr, new_name) != 0) {
throw error_already_set();
}
}
private:
static const char *get_name_in_error_scope(PyObject *o) {
error_scope error_guard;
const char *name = PyCapsule_GetName(o);
if ((name == nullptr) && PyErr_Occurred()) {
// write out and consume error raised by call to PyCapsule_GetName
PyErr_WriteUnraisable(o);
}
return name;
}
};
class tuple : public object {