[Mlir-commits] [mlir] [mlir][Python] add docs about downstream type/attr implementation (PR #175259)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Jan 9 21:17:45 PST 2026
================
@@ -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.
----------------
PragmaTwice wrote:
off-topic: I think now we can rename it to just `PythonTestModule.cpp`?
https://github.com/llvm/llvm-project/pull/175259
More information about the Mlir-commits
mailing list