[Mlir-commits] [mlir] [mlir][Python] add docs about downstream type/attr implementation (PR #175259)
Maksim Levental
llvmlistbot at llvm.org
Fri Jan 9 21:22:20 PST 2026
https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/175259
>From e6e0fcc5f52eb2ec2a26271f0d7379b94c8cfa9a Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Fri, 9 Jan 2026 14:33:30 -0800
Subject: [PATCH 1/2] [mlir][Python] add docs about downstream type/attr
implementation
---
mlir/docs/Bindings/Python.md | 69 ++++++++++++++++++++++++++++++------
1 file changed, 58 insertions(+), 11 deletions(-)
diff --git a/mlir/docs/Bindings/Python.md b/mlir/docs/Bindings/Python.md
index 161f8b6dff5c2..6508ee6cfb7a2 100644
--- a/mlir/docs/Bindings/Python.md
+++ b/mlir/docs/Bindings/Python.md
@@ -1183,19 +1183,66 @@ mlir.dialects.<dialect-namespace>` in Python.
### Attributes and Types
Dialect attributes and types are provided in Python as subclasses of the
-`mlir.ir.Attribute` and `mlir.ir.Type` classes, respectively. Python APIs for
+`mlir.ir.Attribute` and `mlir.ir.Type` classes, respectively. Bindings APIs for
attributes and types must connect to the relevant C APIs for building and
inspection, which must be provided first. Bindings for `Attribute` and `Type`
-subclasses can be defined using
-[`include/mlir/Bindings/Python/PybindAdaptors.h`](https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Bindings/Python/PybindAdaptors.h)
-or
-[`include/mlir/Bindings/Python/NanobindAdaptors.h`](https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h)
-utilities that mimic pybind11/nanobind APIs for defining functions and
-properties. These bindings are to be included in a separate module. The
-utilities also provide automatic casting between C API handles `MlirAttribute`
-and `MlirType` and their Python counterparts so that the C API handles can be
-used directly in binding implementations. The methods and properties provided by
-the bindings should follow the principles discussed above.
+subclasses can be defined using exactly the same way patterns implemented in the “core” extension:
+
+```c++
+#include "mlir/Bindings/Python/IRCore.h"
+#include "mlir/Bindings/Python/IRTypes.h"
+
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
+
+struct PyTestType : PyConcreteType<PyTestType> {
+ // Required
+ static constexpr IsAFunctionTy isaFunction = mlirTypeIsAPythonTestTestType;
+ // Optional but recommended
+ static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+ mlirPythonTestTestTypeGetTypeID;
+ static constexpr const char *pyClassName = "TestType";
+ using Base::Base;
+
+ static void bindDerived(ClassTy &c) {
+ c.def_static("get",
+ [](DefaultingPyMlirContext context) {
+ return PyTestType(context->getRef(), mlirPythonTestTestTypeGet(context.get()->get()));
+ },
+ nb::arg("context").none() = nb::none());
+ }
+};
+
+class PyTestAttr : public PyConcreteAttribute<PyTestAttr> {
+public:
+ // Required
+ static constexpr IsAFunctionTy isaFunction =
+ mlirAttributeIsAPythonTestTestAttribute;
+ static constexpr const char *pyClassName = "TestAttr";
+ static constexpr GetTypeIDFunctionTy getTypeIdFunction =
+ mlirPythonTestTestAttributeGetTypeID;
+ using Base::Base;
+
+ static void bindDerived(ClassTy &c) {
+ c.def_static(
+ "get",
+ [](DefaultingPyMlirContext context) {
+ return PyTestAttr(context->getRef(), mlirPythonTestTestAttributeGet(context.get()->get()));
+ },
+ nb::arg("context").none() = nb::none());
+ }
+};
+
+NB_MODULE(_mlirPythonTestNanobind, m) {
+ PyTestAttr::bind(m);
+ PyTestType::bind(m);
+}
+```
+
+See [`mlir/test/python/lib/PythonTestModuleNanobind.cpp`] for more examples.
+
+**Note**: if you are defining such types/attributes in a downstream project, it is critical you define
+`MLIR_BINDINGS_PYTHON_NB_DOMAIN` (which is used to determine `MLIR_BINDINGS_PYTHON_DOMAIN`) such that it is unique to
+your project and for every set of bindings built/distributed by your project. See **CMake variables** above.
The attribute and type bindings for a dialect can be located in
`lib/Bindings/Python/Dialect<Name>.cpp` and should be compiled into a separate
>From ad52fa3dbf91abe2b035898f60cc8acc21780614 Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Fri, 9 Jan 2026 21:22:12 -0800
Subject: [PATCH 2/2] Update Python.md
---
mlir/docs/Bindings/Python.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/docs/Bindings/Python.md b/mlir/docs/Bindings/Python.md
index 6508ee6cfb7a2..f75febd1a06e0 100644
--- a/mlir/docs/Bindings/Python.md
+++ b/mlir/docs/Bindings/Python.md
@@ -1185,8 +1185,8 @@ mlir.dialects.<dialect-namespace>` in Python.
Dialect attributes and types are provided in Python as subclasses of the
`mlir.ir.Attribute` and `mlir.ir.Type` classes, respectively. Bindings APIs for
attributes and types must connect to the relevant C APIs for building and
-inspection, which must be provided first. Bindings for `Attribute` and `Type`
-subclasses can be defined using exactly the same way patterns implemented in the “core” extension:
+inspection, which must be provided first. Bindings for downstream/dialect `Attribute` and `Type`
+subclasses can be defined using exactly the same patterns as in the “core” extension:
```c++
#include "mlir/Bindings/Python/IRCore.h"
More information about the Mlir-commits
mailing list