[Mlir-commits] [mlir] [MLIR] [Python] Fixed a long standing bug in the `PyRegionListIterator` (PR #188475)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Mar 25 05:41:28 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Sergei Lebedev (superbobry)
<details>
<summary>Changes</summary>
`PyRegionIterator` did not account for start index/step, so this commit removes it in favor of the sequence iterator provided by CPython.
The previous attempt in #<!-- -->137232 bitrotted, so I decided to open a new PR.
---
Full diff: https://github.com/llvm/llvm-project/pull/188475.diff
3 Files Affected:
- (modified) mlir/include/mlir/Bindings/Python/IRCore.h (-20)
- (modified) mlir/lib/Bindings/Python/IRCore.cpp (-30)
- (modified) mlir/test/python/ir/operation.py (+12-1)
``````````diff
diff --git a/mlir/include/mlir/Bindings/Python/IRCore.h b/mlir/include/mlir/Bindings/Python/IRCore.h
index eefc51d519d62..e834fca61522f 100644
--- a/mlir/include/mlir/Bindings/Python/IRCore.h
+++ b/mlir/include/mlir/Bindings/Python/IRCore.h
@@ -1378,22 +1378,6 @@ struct MLIR_PYTHON_API_EXPORTED PyAttrBuilderMap {
// Collections.
//------------------------------------------------------------------------------
-class MLIR_PYTHON_API_EXPORTED PyRegionIterator {
-public:
- PyRegionIterator(PyOperationRef operation, int nextIndex)
- : operation(std::move(operation)), nextIndex(nextIndex) {}
-
- PyRegionIterator &dunderIter() { return *this; }
-
- nanobind::typed<nanobind::object, PyRegion> dunderNext();
-
- static void bind(nanobind::module_ &m);
-
-private:
- PyOperationRef operation;
- intptr_t nextIndex = 0;
-};
-
/// Regions of an op are fixed length and indexed numerically so are represented
/// with a sequence-like container.
class MLIR_PYTHON_API_EXPORTED PyRegionList
@@ -1404,10 +1388,6 @@ class MLIR_PYTHON_API_EXPORTED PyRegionList
PyRegionList(PyOperationRef operation, intptr_t startIndex = 0,
intptr_t length = -1, intptr_t step = 1);
- PyRegionIterator dunderIter();
-
- static void bindDerived(ClassTy &c);
-
private:
/// Give the parent CRTP class access to hook implementations below.
friend class Sliceable<PyRegionList, PyRegion>;
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index f3f1ee4ce343f..12f06a3cb2b5b 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -189,25 +189,6 @@ nb::object PyBlock::getCapsule() {
// Collections.
//------------------------------------------------------------------------------
-nb::typed<nb::object, PyRegion> PyRegionIterator::dunderNext() {
- operation->checkValid();
- if (nextIndex >= mlirOperationGetNumRegions(operation->get())) {
- PyErr_SetNone(PyExc_StopIteration);
- // python functions should return NULL after setting any exception
- return nb::object();
- }
- MlirRegion region = mlirOperationGetRegion(operation->get(), nextIndex++);
- return nb::cast(PyRegion(operation, region));
-}
-
-void PyRegionIterator::bind(nb::module_ &m) {
- nb::class_<PyRegionIterator>(m, "RegionIterator")
- .def("__iter__", &PyRegionIterator::dunderIter,
- "Returns an iterator over the regions in the operation.")
- .def("__next__", &PyRegionIterator::dunderNext,
- "Returns the next region in the iteration.");
-}
-
PyRegionList::PyRegionList(PyOperationRef operation, intptr_t startIndex,
intptr_t length, intptr_t step)
: Sliceable(startIndex,
@@ -216,16 +197,6 @@ PyRegionList::PyRegionList(PyOperationRef operation, intptr_t startIndex,
step),
operation(std::move(operation)) {}
-PyRegionIterator PyRegionList::dunderIter() {
- operation->checkValid();
- return PyRegionIterator(operation, startIndex);
-}
-
-void PyRegionList::bindDerived(ClassTy &c) {
- c.def("__iter__", &PyRegionList::dunderIter,
- "Returns an iterator over the regions in the sequence.");
-}
-
intptr_t PyRegionList::getRawNumElements() {
operation->checkValid();
return mlirOperationGetNumRegions(operation->get());
@@ -5012,7 +4983,6 @@ void populateIRCore(nb::module_ &m) {
PyOpOperands::bind(m);
PyOpResultList::bind(m);
PyOpSuccessors::bind(m);
- PyRegionIterator::bind(m);
PyRegionList::bind(m);
// Debug bindings.
diff --git a/mlir/test/python/ir/operation.py b/mlir/test/python/ir/operation.py
index f561a1bc624d8..9f1ad01cbcc88 100644
--- a/mlir/test/python/ir/operation.py
+++ b/mlir/test/python/ir/operation.py
@@ -86,7 +86,7 @@ def walk_operations(indent, op):
# CHECK: OP 1: func.return
walk_operations("", op)
- # CHECK: Region iter: <mlir.{{.+}}.RegionIterator
+ # CHECK: Region iter: <iterator
# CHECK: Block iter: <mlir.{{.+}}.BlockIterator
# CHECK: Operation iter: <mlir.{{.+}}.OperationIterator
print(" Region iter:", iter(op.regions))
@@ -109,6 +109,17 @@ def walk_operations(indent, op):
# CHECK: attempt to access out of bounds operation
print(e)
+ # Verify that iterating a sliced region list yields the correct
+ # number of elements (i.e. respects length and step).
+ with Location.unknown(ctx):
+ op4 = Operation.create("custom.op", regions=4)
+ r = op4.regions
+ assert len(list(r[:])) == 4
+ assert len(list(r[1:])) == 3
+ assert len(list(r[::2])) == 2
+ assert len(list(r[1:3])) == 2
+ assert len(list(r[::-1])) == 4
+
# Verify index based traversal of the op/region/block hierarchy.
# CHECK-LABEL: TEST: testTraverseOpRegionBlockIndices
``````````
</details>
https://github.com/llvm/llvm-project/pull/188475
More information about the Mlir-commits
mailing list