)]}'
{
  "commit": "363be141eb198ab4526ae9d6dedb02b7aa462475",
  "tree": "bff4f86ffbe832d7a36c0d76ff3c1f20951d544c",
  "parents": [
    "cbd8c82b7426322f51654bc54c6dad963f84999a"
  ],
  "author": {
    "name": "Ivan Levkivskyi",
    "email": "levkivskyi@gmail.com",
    "time": "Wed Jun 03 11:22:13 2026 +0100"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed Jun 03 11:22:13 2026 +0100"
  },
  "message": "Fix crash on invalid recursive variadic alias (#21572)\n\nFixes https://github.com/python/mypy/issues/21125\n\nThis one was tricky. This is because the above issue actually exposed\n_two_ different crash scenarios:\n* A crash on invalid constructs like `*tuple[Ts]` (must be\n`*tuple[*Ts]`).\n* An infinite recursion when trying to detect pathological and divergent\naliases.\n\nAnd while working on this I discovered two more cases:\n* A crash where an invalid type (like a union) appears in unpack in a\nrecursive alias definition.\n* A crash on non-normalizeable recursive tuple.\n\nI fix the first by tightening logic in `typeanal.py` w.r.t. where\nexactly a `TypeVarTuple` is allowed. I fix the second and third by\navoiding `get_proper_type()` calls in `expand_type()` for recursive\ntuples. The fourth is the most problematic, and is kind of a fundamental\nthing. This PR only avoids an immediate crash for such aliases. We will\nstill need to update various call sites where we special-case tuples to\nexpect non-normal ones.\n\nCouple more related things:\n* I fix couple issues with `is_recursive` cache invalidation.\n* I added a fast path to `detect_diverging_alias()` to avoid creating\nsets unless really needed.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "b576d9f97d8e5effb220351b0003511e07451673",
      "old_mode": 33188,
      "old_path": "mypy/expandtype.py",
      "new_id": "186429abd36a9978d833e2af7a460037d274bc7f",
      "new_mode": 33188,
      "new_path": "mypy/expandtype.py"
    },
    {
      "type": "modify",
      "old_id": "58c152fa066e76573584cc4d6e4345c2568eacb7",
      "old_mode": 33188,
      "old_path": "mypy/semanal.py",
      "new_id": "e010273b0781f18d89d5571b9b960cd9a7267d0a",
      "new_mode": 33188,
      "new_path": "mypy/semanal.py"
    },
    {
      "type": "modify",
      "old_id": "0f62a4aa8b1a2ea8d71ef25988dc0c4d8b3d71df",
      "old_mode": 33188,
      "old_path": "mypy/semanal_typeargs.py",
      "new_id": "5b6d9b16273ef46bcc0fde719acc5b569cdaedf9",
      "new_mode": 33188,
      "new_path": "mypy/semanal_typeargs.py"
    },
    {
      "type": "modify",
      "old_id": "075bf7cb540bf453398069de9f215743a0a4074c",
      "old_mode": 33188,
      "old_path": "mypy/server/astmerge.py",
      "new_id": "5b723711405a1fcfa6b0d321fac46fc29e3ce666",
      "new_mode": 33188,
      "new_path": "mypy/server/astmerge.py"
    },
    {
      "type": "modify",
      "old_id": "a303621d75ef2edb40c8b95a6eef65438d8b5a9c",
      "old_mode": 33188,
      "old_path": "mypy/typeanal.py",
      "new_id": "aa5d14bddc65ad57e949e6747f2b14ead3f6697f",
      "new_mode": 33188,
      "new_path": "mypy/typeanal.py"
    },
    {
      "type": "modify",
      "old_id": "129d98894770f8d86737d48eceea5ed4e6211bf8",
      "old_mode": 33188,
      "old_path": "mypy/types.py",
      "new_id": "324135df014d3bf83740efbd19813eff73c0570f",
      "new_mode": 33188,
      "new_path": "mypy/types.py"
    },
    {
      "type": "modify",
      "old_id": "3f0765ba5c770a4148dafb6c9d55758dea8dc713",
      "old_mode": 33188,
      "old_path": "test-data/unit/check-typevar-tuple.test",
      "new_id": "55f125d1fc036e513918249fc7f6d7515da6b808",
      "new_mode": 33188,
      "new_path": "test-data/unit/check-typevar-tuple.test"
    }
  ]
}
