diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp --- a/mlir/lib/Bindings/Python/IRCore.cpp +++ b/mlir/lib/Bindings/Python/IRCore.cpp @@ -2546,10 +2546,25 @@ }, py::arg("name"), py::arg("childLoc") = py::none(), py::arg("context") = py::none(), kContextGetNameLocationDocString) + .def_static( + "from_attr", + [](PyAttribute &attribute, DefaultingPyMlirContext context) { + return PyLocation(context->getRef(), + mlirLocationFromAttribute(attribute)); + }, + py::arg("attribute"), py::arg("context") = py::none(), + "Gets a Location from a LocationAttr") .def_property_readonly( "context", [](PyLocation &self) { return self.getContext().getObject(); }, "Context that owns the Location") + .def_property_readonly( + "attr", + [](PyLocation &self) { + return PyAttribute(self.getContext(), + mlirLocationGetAttribute(self)); + }, + "Get the underlying LocationAttr") .def( "emit_error", [](PyLocation &self, std::string message) { diff --git a/mlir/test/python/ir/location.py b/mlir/test/python/ir/location.py --- a/mlir/test/python/ir/location.py +++ b/mlir/test/python/ir/location.py @@ -25,6 +25,21 @@ run(testUnknown) +# CHECK-LABEL: TEST: testLocationAttr +def testLocationAttr(): + with Context() as ctxt: + loc = Location.unknown() + attr = loc.get_attr() + clone = Location.from_attr(attr) + gc.collect() + # CHECK: loc: loc(unknown) + print("loc:", str(loc)) + # CHECK: clone: loc(unknown) + print("clone:", str(clone)) + assert loc == clone + +run(testLocationAttr) + # CHECK-LABEL: TEST: testFileLineCol def testFileLineCol(): with Context() as ctx: