<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/54932>54932</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [MLIR:Python] Improve ergonomics of op constructor APIs in Python bindings
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          hawkinsp
      </td>
    </tr>
</table>

<pre>
    We've made extensive use of the MLIR Python bindings to build IR in the MHLO dialect (in the TensorFlow tree) in JAX (https://github.com/google/jax).

The experience has been fairly positive overall, but there are two things that would probably significantly improve the ergonomics of building IR in an MLIR dialect via the Python bindings. While this request comes from experience with the out-of-tree MHLO dialect, I strongly suspect the same is true for any dialect, not just that one.

a) support default arguments to op constructors.

Even if an operator has defaults in its tablegen specification, e.g., via `DefaultValuedAttr`, these defaults aren't available or used by the Python constructors. A natural change would be to make operator arguments that have defaults into Python keyword arguments with default values. This would allow users to omit these attributes, which is important both for ergonomics and for compatibility if the dialect changes. Currently adding a new attribute, even one with a default value, is always a breaking change for Python code.

b) support automatic casts from standard Python types (e.g., integers, lists, ...) into corresponding attributes when passed to op constructors.

If an operator accepts, say, a `BoolAttr` as an argument to its constructor, it would be very nice to pass a Python bool (e.g., `False`) rather than writing out `mlir.ir.BoolAttr.get(False)`. The same thing applies for integer attributes from Python integers, string attributes from Python strings, and dense elements attributes from Python lists. The reason to do this is primarily ergonomics: currently it is very verbose to have to write out attribute types each time.

@stellaraccident 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyFVdFu4zYQ_Br7hYjgSPYlfvCD71KjKa7ooQju-rqSVhITSlRJyj7_fWcp2ZEDtAUUK5KWuzOzw2Vuy_PuBy_ShyOrlkpW_DNw5zUeB8_KVio0rH7_-vyn-nYOje1UrrtSd7VXwap80KZU-Ka7Me7Xr3-oUpPhIqhF-ji9fkFG6w7GnlRwjGpbWfDb_i-JaULo_SLbL9IDrlqHZsiTwrbyYG1tEH54pZ9YlCxWT4vVfvx9aQRrz05zV7BqyKucuVMVaWfOqrdeB2Fhj-zImEX6BWiDwHGsCH_hZPE0MmkoqJMdwKV3NqccCbyuO13pgrqAJ93iA7IJG3a17WyrCy_yRAmQZVKBulGsiwhHTXHRB_ES9aPRRvJprxz_PbAPCqTZq8rZds7sBEViCjuEO1vdiYI3Qgu1Z-WDs10twAffS2VZ4qllhQrBDawq6wDvPF_W2aBeBx9GBWzHNxKTNMoPfW9dUCVXNJgA6eqh5S7E_tseoDuUHopgnb9Z_csR3dCVKGJBhhAQuzQl8qKWljSQm2vECuyoeNC2E3Sc1IncRcPFp9XTuPA7mYHLfQgO7-QziMKp17ToLVY_AOmRtJHkCpVh5lLl53kvbpCrveooDLCKKhrqap78kLPwbOmN31nMJBDZGjrynBXipwpvfD5ZV84WxGZepDwKE5R-EROM5eBUbBKAdaO-rQ4TPwJhDQezF86nRheNdBbGRHdgUpVbpJYez_xJXRlfwVk9ZM210eEsTREZLhYd-QLHl8FBO7E7ldHSpDo-vVeOPZGuwigjE7rlIgHAROZEZ9xU7pjeJNEkqUC5il_emi2fm42GYFsALlRBPkx7woNmSZBzShHOPbYLJsjFJ5AeRnJRIKOxTv5JkmScN5CzsCDoe9uN7K6KQk6w6smLSf7H1s-3jqai4H6s5Okst-jVz9aayaKKpA9XD0h-sf2sQMQe3g2HiXVWnS6i9QQVcl7mB_LOKSP_gYznuBW2Cpgw38SWnTo5DEDQxNiQsNZol-C6IEtqxgh4HFenW0SIEaeREeeior43WiYSeE7azkWLTZlwzaUHrQ_yziPHrzFQ3FniaMBINTzuj39ZFLs54oOlvDTfqtKO4xNX73RLTsO57-bHkaKKq6OhL-KisvjJrY_ixq2Lu2gVB-w7gMleTNhnQbe3Zl2sVz6wMeTQf11KW5flLiu32ZaWQQfDu8XmsxwEQDFyWGye1PN0ityeILduU_tvz3E2fjgxloMzu_84K405Xm53qPIaJ_xBez_IxDhs1tssXTa7dFtm2boqshVzWuVcULVJt_cZPWyr-2p9v8TEZOMFPhAv9S5dpelqfb-5zzbbbJPQ46dtVqyJs2yVU7GBEtxiziZSOLGuXrpdxJAPaPJ6NXbu-hFmxrnKfMmPjd5Yt2vohDnh-2XEu4tg_wF6BANx">