[Mlir-commits] [mlir] bd9651b - [mlir][py] avoid crashing on None contexts in custom `get`s (#171140)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Dec 9 23:37:50 PST 2025
Author: Oleksandr "Alex" Zinenko
Date: 2025-12-10T08:37:45+01:00
New Revision: bd9651bf78f2b1713a8203e0bd5b97f7ff199924
URL: https://github.com/llvm/llvm-project/commit/bd9651bf78f2b1713a8203e0bd5b97f7ff199924
DIFF: https://github.com/llvm/llvm-project/commit/bd9651bf78f2b1713a8203e0bd5b97f7ff199924.diff
LOG: [mlir][py] avoid crashing on None contexts in custom `get`s (#171140)
Following a series of refactorings, MLIR Python bindings would crash if
a
dialect object requiring a context defined using
mlir_attribute/type_subclass
was constructed outside of the `ir.Context` context manager. The type
caster
for `MlirContext` would try using `ir.Context.current` when the default
`None`
value was provided to the `get`, which would also just return `None`.
The
caster would then attempt to obtain the MLIR capsule for that `None`,
fail,
but access it anyway without checking, leading to a C++ assertion
failure or
segfault.
Guard against this case in nanobind adaptors. Also emit a warning to the
user
to clarify expectations, as the default message confusingly says that
`None` is
accepted as context and then fails with a type error. Using Python C API
is
currently recommended by nanobind in this case since the surrounding
function
must be marked `noexcept`.
The corresponding test is in the PDL dialect since it is where I first
observed
the behavior. Core types are not using the `mlir_type_subclass`
mechanism and
are immune to the problem, so cannot be used for checking.
Added:
Modified:
mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
mlir/test/python/dialects/pdl_types.py
Removed:
################################################################################
diff --git a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
index 847951ab5fd46..6594670abaaa7 100644
--- a/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
+++ b/mlir/include/mlir/Bindings/Python/NanobindAdaptors.h
@@ -181,14 +181,22 @@ struct type_caster<MlirContext> {
bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
if (src.is_none()) {
// Gets the current thread-bound context.
- // TODO: This raises an error of "No current context" currently.
- // Update the implementation to pretty-print the helpful error that the
- // core implementations print in this case.
src = mlir::python::irModule().attr("Context").attr("current");
}
- std::optional<nanobind::object> capsule = mlirApiObjectToCapsule(src);
- value = mlirPythonCapsuleToContext(capsule->ptr());
- return !mlirContextIsNull(value);
+ // If there is no context, including thread-bound, emit a warning (since
+ // this function is not allowed to throw) and fail to cast.
+ if (src.is_none()) {
+ PyErr_Warn(
+ PyExc_RuntimeWarning,
+ "Passing None as MLIR Context is only allowed inside "
+ "the " MAKE_MLIR_PYTHON_QUALNAME("ir.Context") " context manager.");
+ return false;
+ }
+ if (std::optional<nanobind::object> capsule = mlirApiObjectToCapsule(src)) {
+ value = mlirPythonCapsuleToContext(capsule->ptr());
+ return !mlirContextIsNull(value);
+ }
+ return false;
}
};
diff --git a/mlir/test/python/dialects/pdl_types.py b/mlir/test/python/dialects/pdl_types.py
index 16a41e2a4c1ce..dfba2a36b8980 100644
--- a/mlir/test/python/dialects/pdl_types.py
+++ b/mlir/test/python/dialects/pdl_types.py
@@ -148,3 +148,16 @@ def test_value_type():
print(parsedType)
# CHECK: !pdl.value
print(constructedType)
+
+
+# CHECK-LABEL: TEST: test_type_without_context
+ at run
+def test_type_without_context():
+ # Constructing a type without the surrounding ir.Context context manager
+ # should raise an exception but not crash.
+ try:
+ constructedType = pdl.ValueType.get()
+ except TypeError:
+ pass
+ else:
+ assert False, "Expected TypeError to be raised."
More information about the Mlir-commits
mailing list