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

    <tr>
        <th>Summary</th>
        <td>
            MLIR Enum Python bindings infinite recursion
        </td>
    </tr>

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

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

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

<pre>
    This bug specifically arises when using `I32BitEnumAttrCaseGroup` and python bindings.

## Example repro

Example tablegen:
```td
def TTCore_ChipCapabilityPCIE : I32BitEnumAttrCaseBit<"PCIE", 0, "pcie">;
def TTCore_ChipCapabilityHostMMIO : I32BitEnumAttrCaseBit<"HostMMIO", 1, "host_mmio">;
def TTCore_ChipCapabilityAll : I32BitEnumAttrCaseGroup<"All",
 [TTCore_ChipCapabilityPCIE, TTCore_ChipCapabilityHostMMIO], "all">;

def TTCore_ChipCapability : I32BitEnumAttr<"ChipCapability", "TT Chip Capabilities",
                           [
 TTCore_ChipCapabilityPCIE,
 TTCore_ChipCapabilityHostMMIO,
 TTCore_ChipCapabilityAll,
                           ]> {
  let genSpecializedAttr = 1;
  let cppNamespace = "::mlir::tt::ttcore";
}
```

Generates the following python binding:
```python
class ChipCapability(IntFlag):
    """TT Chip Capabilities"""

    PCIE = 1
    HostMMIO = 2
    All = 3

    def __iter__(self):
        return iter([case for case in type(self) if (self & case) is case])
    def __len__(self):
        return bin(self).count("1")

    def __str__(self):
        if len(self) > 1:
 return "|".join(map(str, self))
        if self is ChipCapability.PCIE:
            return "pcie"
        if self is ChipCapability.HostMMIO:
            return "host_mmio"
        if self is ChipCapability.All:
            return "all"
        raise ValueError("Unknown ChipCapability enum entry.")
```

The following sequence results in infinite recursion:
1. Call to `__str__`, we take the first branch and map over each element of the `IntFlag` enum class.
2. We go into `__iter__`.  It's especially useful to `print(list(case for case in type(self)))` right here, we can see:
```
[<ChipCapability.PCIE: 1>, <ChipCapability.HostMMIO: 2>, <ChipCapability.All: 3>]
```
3. The existence of `<ChipCapability.All: 3>` causes this to be a valid case to be returned from `__iter__` which generates infinite recursion.

## Proposed Fix

Proposed fix is to filter the iteration when the case is not equal to self. 
```python
    def __iter__(self):
        return iter([case for case in type(self) if (self & case) is case and self is not case])
```

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEVltzozYU_jXyy5llQBgcHvzgS7zNTLfdadP2MSPgANoVEiuJJO6v70jC8WUTJ2_1MIFIR-f6feeIGcNbibgk2Zpk2xkbbaf0Upqe287aWanq_fK-4wbKsQUzYMUbXjEh9sA0N2jgqUMJo-GyBZLHdyldc3srx35lrd4wg5-1GgeSx8BkDcPedkpCyWXNZWsiEq_cQ1NCU7h9Zv0gEDQOWoWdw5JlpcAWJUm9fB6Hx9YkXtXYwP39Rml82HR82LCBlVxwu_-6ubsFkq7gZ6fW3JJ0Qyh1MoRSQjcQuz-E0qHi6JbSW5Kur-n_RRn75cvd7-_ZOMhNdpLJTqeMfeh7rj5kbCXEG3ZCgr2llRDBCIlXQLL1m2lxLlyNiWTbyU0WdB4cvObjKw4Gv87FpjwQSu_vwW3Byx5Hcwzg7Z8Da7x6u-qTgusRXpHxeXzXhy1Jb4EsvCsg0EKL8k_HECb4v1i78IGkW0hC5oJMNQy_sR7NwCr0uz65K5KuesF1-LL28K6UDlj0qV9sT8EfivEZJWpm0YDtEBolhHpyXDxn2gVvwiaJV5VgxsBleW7upN0J1hJahIM-XlcXeq1o_okP8hP7XPhh4YQuW6DTYoD1FtLjQQevhwduUT88EHpjUDRnjrifRjtqCU6I0BuSrStmXPQa_AeXYPcDHk8Db2D6DwjNvZRfNuHTob04sy9Qvmu-5PIoEVVqlNZ5Q2nik1FcxmTslZB4AwJP9IFDVzLJTAad2oUjVPRNeds9G9wJqx2hDmpfIpnU-qj5ZZkjT5QzF05CO-mDH9H1Qqor-s763UeUOhZe0Tc1ppOqMG4Q_mZixFutlQ61-Et-l-pJXigHlGMPKK3eR8dinVPr_oxQBn-MKCs3nsworHEg47Lhklu3Vo3acDUNqCSCDRMCrHIz8VD43E-YJzfNvmOgK9fGQqmZrDo_H3s2gHpEDciqDlBgj9KCary0G68TMfM4BOD566YojeAfhFYBlwejE4PyOAK4s4QuDKAJ7UnsYTTYjAcPB809dAU37vUOmaYnj0HztrPQoWtSPrKKSTCIF-3GfWdrkm5eR6BDuZ9IP0uc4Arom1IBKJA6geyyR6YRuELiMzfW1081LuTrWvIYKjYa31W5cVkqERg8MsHrkJWwFNCINTRa9Rdph6eOV50bClOD_hkt5_efr1oNymANO_4cNl5WGv4MwY-GC4va48FZYpYrGe5gbikUzIBUFvDHyHyBXdkieLX__0_91mP9wHrn61kTPq3erF6mdZEWbIbLZJGlRZHk-XzWLRmrE5oumjrGGDNMMC2yIs1KWuRxnsb1jC9pTLN4kSZJkc1pGi3m86qmZUWbIi_m9YLMY-wZF5EQj32kdDvjxoy4TLIku5nPBCtRGH8vptTPZkrdDVkvnfyncmwNmceOMeaowXIrcPnl17s_wN2A4Ov5ffcVCMxGLZadtYNxGac7Qnctt91YRpXqCd051dPr06DVN6wsoTvvqSF0Nzn7uKT_BQAA__9QwZIq">