[Mlir-commits] [mlir] [mlir:python] Set `__module__` classes generated by nanobind adaptors. (PR #127584)

Ingo Müller llvmlistbot at llvm.org
Tue Feb 18 04:22:06 PST 2025


https://github.com/ingomueller-net updated https://github.com/llvm/llvm-project/pull/127584

>From e0d5ad7a7c6cae9b87b568718032978e69acfc2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ingo=20M=C3=BCller?= <ingomueller at google.com>
Date: Tue, 18 Feb 2025 07:40:45 +0000
Subject: [PATCH 1/3] [mlir:python] Set `__module__` classes generated by
 nanobind adaptors.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This PR sets the `__module__` attribute of the classes generated by the
nanobind adaptors for attributes, types, and values (via
`mlir_(attribute|type|value)_subclass`). By default, the `__module__`
property is set to `importlib._bootstrap`, which isn't where we want the
new class to live. The new logic sets the property to the name of the
module provided as `scope` instead. This also makes nanobind's `stubgen`
generate stubs for those classes properly, which ignores classes whose
`__module__` does not correspond to the module it is generating stubs
for. This resolves #127518.

Signed-off-by: Ingo Müller <ingomueller at google.com>
---
 mlir/include/mlir/Bindings/Python/NanobindAdaptors.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
index 517351cac6dbc..11338b2d49308 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
@@ -349,6 +349,7 @@ class pure_subclass {
     thisClass = metaclass(derivedClassName, nanobind::make_tuple(superClass),
                           attributes);
     scope.attr(derivedClassName) = thisClass;
+    thisClass.attr("__module__") = scope.attr("__name__");
   }
 
   template <typename Func, typename... Extra>

>From b1d185bbdfae78eb6513f1e78e620c710d85e7a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ingo=20M=C3=BCller?= <ingomueller at google.com>
Date: Tue, 18 Feb 2025 11:17:52 +0000
Subject: [PATCH 2/3] Fix signature of `isinstance` bindings.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit overwrites the signature of the `isinstance` member
functions created by `mlir_(attribute|type|value)_subclass` by adding a
`nanobind::signature` argument to the `def` call that creates the
functions. This improves the typing information that `stubgen` creates
for such classes.

Signed-off-by: Ingo Müller <ingomueller at google.com>
---
 .../mlir/Bindings/Python/NanobindAdaptors.h   | 20 ++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
index 11338b2d49308..d54f355fca783 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
@@ -466,10 +466,13 @@ class mlir_attribute_subclass : public pure_subclass {
     thisClass.attr("__new__") = newCf;
 
     // 'isinstance' method.
+    static const char kIsinstanceSig[] =
+        "def isinstance(other_attribute: " MAKE_MLIR_PYTHON_QUALNAME(
+            "ir") ".Attribute) -> bool";
     def_staticmethod(
         "isinstance",
         [isaFunction](MlirAttribute other) { return isaFunction(other); },
-        nanobind::arg("other_attribute"));
+        nanobind::arg("other_attribute"), nanobind::sig(kIsinstanceSig));
     def("__repr__", [superCls, captureTypeName](nanobind::object self) {
       return nanobind::repr(superCls(self))
           .attr("replace")(superCls.attr("__name__"), captureTypeName);
@@ -543,13 +546,17 @@ class mlir_type_subclass : public pure_subclass {
     thisClass.attr("__new__") = newCf;
 
     // 'isinstance' method.
+    static const char kIsinstanceSig[] =
+        "def isinstance(other_type: " MAKE_MLIR_PYTHON_QUALNAME(
+            "ir") ".Type) -> bool";
     def_staticmethod(
         "isinstance",
         [isaFunction](MlirType other) { return isaFunction(other); },
-        nanobind::arg("other_type"));
+        nanobind::arg("other_type"), nanobind::sig(kIsinstanceSig));
     def("__repr__", [superCls, captureTypeName](nanobind::object self) {
-      return nanobind::repr(superCls(self))
-          .attr("replace")(superCls.attr("__name__"), captureTypeName);
+      return nanobind::cast<std::string>(
+          nanobind::repr(superCls(self))
+              .attr("replace")(superCls.attr("__name__"), captureTypeName));
     });
     if (getTypeIDFunction) {
       // 'get_static_typeid' method.
@@ -621,10 +628,13 @@ class mlir_value_subclass : public pure_subclass {
     thisClass.attr("__new__") = newCf;
 
     // 'isinstance' method.
+    static const char kIsinstanceSig[] =
+        "def isinstance(other_value: " MAKE_MLIR_PYTHON_QUALNAME(
+            "ir") ".Value) -> bool";
     def_staticmethod(
         "isinstance",
         [isaFunction](MlirValue other) { return isaFunction(other); },
-        nanobind::arg("other_value"));
+        nanobind::arg("other_value"), nanobind::sig(kIsinstanceSig));
   }
 };
 

>From 5991abedd0edc6e8277e58f8d8911526afe94f9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ingo=20M=C3=BCller?= <ingomueller at google.com>
Date: Tue, 18 Feb 2025 12:18:36 +0000
Subject: [PATCH 3/3] Minor unrelated doc and formatting improvements (NFC).
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit fixes three occurrences of the same grammar issue in some
comment and adds a clang-format suppression for a specific ordering of
includes.

Signed-off-by: Ingo Müller <ingomueller at google.com>
---
 mlir/include/mlir/Bindings/Python/NanobindAdaptors.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
index d54f355fca783..0608182f00b7e 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
@@ -23,8 +23,10 @@
 
 #include "mlir-c/Diagnostics.h"
 #include "mlir-c/IR.h"
+// clang-format off
 #include "mlir/Bindings/Python/Nanobind.h"
 #include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind.
+// clang-format on
 #include "llvm/ADT/Twine.h"
 
 // Raw CAPI type casters need to be declared before use, so always include them
@@ -435,7 +437,7 @@ class mlir_attribute_subclass : public pure_subclass {
                           const nanobind::object &superCls,
                           GetTypeIDFunctionTy getTypeIDFunction = nullptr)
       : pure_subclass(scope, typeClassName, superCls) {
-    // Casting constructor. Note that it hard, if not impossible, to properly
+    // Casting constructor. Note that it is hard, if not impossible, to properly
     // call chain to parent `__init__` in nanobind due to its special handling
     // for init functions that don't have a fully constructed self-reference,
     // which makes it impossible to forward it to `__init__` of a superclass.
@@ -516,7 +518,7 @@ class mlir_type_subclass : public pure_subclass {
                      const nanobind::object &superCls,
                      GetTypeIDFunctionTy getTypeIDFunction = nullptr)
       : pure_subclass(scope, typeClassName, superCls) {
-    // Casting constructor. Note that it hard, if not impossible, to properly
+    // Casting constructor. Note that it is hard, if not impossible, to properly
     // call chain to parent `__init__` in nanobind due to its special handling
     // for init functions that don't have a fully constructed self-reference,
     // which makes it impossible to forward it to `__init__` of a superclass.
@@ -598,7 +600,7 @@ class mlir_value_subclass : public pure_subclass {
                       IsAFunctionTy isaFunction,
                       const nanobind::object &superCls)
       : pure_subclass(scope, valueClassName, superCls) {
-    // Casting constructor. Note that it hard, if not impossible, to properly
+    // Casting constructor. Note that it is hard, if not impossible, to properly
     // call chain to parent `__init__` in nanobind due to its special handling
     // for init functions that don't have a fully constructed self-reference,
     // which makes it impossible to forward it to `__init__` of a superclass.



More information about the Mlir-commits mailing list