[Mlir-commits] [mlir] [MLIR][Python] Remove pybind workaround for not throwing IndexError (PR #174139)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sat Jan 10 09:17:55 PST 2026
https://github.com/MaPePeR updated https://github.com/llvm/llvm-project/pull/174139
>From a92eeaab6242f20f0980829b339fcdfbc8534c28 Mon Sep 17 00:00:00 2001
From: MaPePeR <MaPePeR at users.noreply.github.com>
Date: Wed, 31 Dec 2025 20:25:22 +0000
Subject: [PATCH] [MLIR][Python] Remove pybind workaround for not throwing
IndexError
The workaround was required to avoid the throwing of C++ exceptions with
pybind. This is not required anymore, because with nanobind the
`PyErr_SetString` function can be called directly.
---
.../mlir/Bindings/Python/NanobindUtils.h | 50 ++-----------------
1 file changed, 5 insertions(+), 45 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/NanobindUtils.h b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
index aea195fecae82..b0f5069201735 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindUtils.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindUtils.h
@@ -296,9 +296,9 @@ class Sliceable {
/// Returns a new instance of the pseudo-container restricted to the given
/// slice. Returns a nullptr object on failure.
- nanobind::object getItemSlice(PyObject *slice) {
+ nanobind::object getItemSlice(nanobind::slice slice) {
ssize_t start, stop, extraStep, sliceLength;
- if (PySlice_GetIndicesEx(slice, length, &start, &stop, &extraStep,
+ if (PySlice_GetIndicesEx(slice.ptr(), length, &start, &stop, &extraStep,
&sliceLength) != 0) {
PyErr_SetString(PyExc_IndexError, "index out of range");
return {};
@@ -355,51 +355,11 @@ class Sliceable {
nanobind::cast<std::string>(elemTyName) + "])";
auto clazz = nanobind::class_<Derived>(m, Derived::pyClassName,
nanobind::sig(sig.c_str()))
+ .def("__len__", &Sliceable::size)
+ .def("__getitem__", &Sliceable::getItem)
+ .def("__getitem__", &Sliceable::getItemSlice)
.def("__add__", &Sliceable::dunderAdd);
Derived::bindDerived(clazz);
-
- // Manually implement the sequence protocol via the C API. We do this
- // because it is approx 4x faster than via nanobind, largely because that
- // formulation requires a C++ exception to be thrown to detect end of
- // sequence.
- // Since we are in a C-context, any C++ exception that happens here
- // will terminate the program. There is nothing in this implementation
- // that should throw in a non-terminal way, so we forgo further
- // exception marshalling.
- // See: https://github.com/pybind/nanobind/issues/2842
- auto heap_type = reinterpret_cast<PyHeapTypeObject *>(clazz.ptr());
- assert(heap_type->ht_type.tp_flags & Py_TPFLAGS_HEAPTYPE &&
- "must be heap type");
- heap_type->as_sequence.sq_length = +[](PyObject *rawSelf) -> Py_ssize_t {
- auto self = nanobind::cast<Derived *>(nanobind::handle(rawSelf));
- return self->length;
- };
- // sq_item is called as part of the sequence protocol for iteration,
- // list construction, etc.
- heap_type->as_sequence.sq_item =
- +[](PyObject *rawSelf, Py_ssize_t index) -> PyObject * {
- auto self = nanobind::cast<Derived *>(nanobind::handle(rawSelf));
- return self->getItem(index).release().ptr();
- };
- // mp_subscript is used for both slices and integer lookups.
- heap_type->as_mapping.mp_subscript =
- +[](PyObject *rawSelf, PyObject *rawSubscript) -> PyObject * {
- auto self = nanobind::cast<Derived *>(nanobind::handle(rawSelf));
- Py_ssize_t index = PyNumber_AsSsize_t(rawSubscript, PyExc_IndexError);
- if (!PyErr_Occurred()) {
- // Integer indexing.
- return self->getItem(index).release().ptr();
- }
- PyErr_Clear();
-
- // Assume slice-based indexing.
- if (PySlice_Check(rawSubscript)) {
- return self->getItemSlice(rawSubscript).release().ptr();
- }
-
- PyErr_SetString(PyExc_ValueError, "expected integer or slice");
- return nullptr;
- };
}
/// Hook for derived classes willing to bind more methods.
More information about the Mlir-commits
mailing list