)]}'
{
  "commit": "46e199dacf3cf8a1792b0a0ee560a2d865906ab2",
  "tree": "dbd649c129cf5aae090d133d1653ad822f21297c",
  "parents": [
    "8ed851015901574d992778b3b3f783f48b5e514b"
  ],
  "author": {
    "name": "Ryan Heard",
    "email": "ryanwheard@gmail.com",
    "time": "Wed Oct 14 09:46:19 2026 -0400"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed Oct 14 14:46:19 2026 +0100"
  },
  "message": "[mypyc] Fix crash on a property with another decorator (#22157)\n\nFixes mypyc/mypyc#1238.\n\nmypy only rejects decorators on top of `@property`, so it accepts a\nproperty like this:\n\n```python\nclass C:\n    @property\n    @functools.lru_cache(maxsize\u003dNone)\n    def p(self) -\u003e int: ...\n```\n\nIn a native class, `prepare_method_def()` left the getter out of\n`method_decls`, like any decorated method, but still set\n`is_prop_getter` and `property_types`. Reading `c.p` in compiled code\nthen generated a native `GetAttr` with no getter behind it, and the\ncompiler crashed in `emit_method_call` with `KeyError: \"\u0027C\u0027 has no\nattribute \u0027p\u0027\"`. If nothing compiled read the property, the module\ncompiled, but the method was missing from the type\u0027s method table, so\nthe decorator was called with the property\u0027s `getset_descriptor` and its\nresult replaced the property. With `lru_cache` the import failed\n(`TypeError: the first argument must be callable`).\n\nA getter with other decorators is now handled like other decorated\nmethods. `handle_ext_method()` applies the decorators, wraps the result\nwith `builtins.property` and sets it on the class. Non-native classes\nalready did this. The property isn\u0027t a native one, so compiled code\nreads it with a generic attribute lookup and coerces the result to the\ntype mypy inferred, which is the decorated function\u0027s return type.\n`@functools.cached_property` over another decorator takes the same path.\n\nA setter for such a property would need the native setter exposed as a\nPython callable, so for now it\u0027s reported as an error instead of\ncrashing:\n\n```\nerror: Property setter not supported when the getter has other decorators\n```\n\n`@property` over `@abstractmethod`, `@override` or `@final` isn\u0027t\naffected, since mypy removes those from the decorator list.\n\nA decorated property that overrides a native property still fails like a\ndecorated method that overrides a native method (mypyc/mypyc#767). This\nPR doesn\u0027t change that.",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "f24203417f9e200133b68b957447c59f8f01d57e",
      "old_mode": 33188,
      "old_path": "mypyc/irbuild/function.py",
      "new_id": "0f6c7364669aa3b3aa48e9332b40871db9907141",
      "new_mode": 33188,
      "new_path": "mypyc/irbuild/function.py"
    },
    {
      "type": "modify",
      "old_id": "318f94a4bf5fed36e2bd3f81dd99f6353c094a8f",
      "old_mode": 33188,
      "old_path": "mypyc/irbuild/prepare.py",
      "new_id": "301e8cfde37bafec90cb5d9bb7af1a3ced0d5198",
      "new_mode": 33188,
      "new_path": "mypyc/irbuild/prepare.py"
    },
    {
      "type": "modify",
      "old_id": "1d2343ca5917884a01c5a200c3b7918e157bcfa1",
      "old_mode": 33188,
      "old_path": "mypyc/test-data/irbuild-classes.test",
      "new_id": "43e9c2ba2ae1d017e964fe32468c61d585407a0d",
      "new_mode": 33188,
      "new_path": "mypyc/test-data/irbuild-classes.test"
    },
    {
      "type": "modify",
      "old_id": "ebeb04cf1fa598fa53fba9121781d3c98274a30e",
      "old_mode": 33188,
      "old_path": "mypyc/test-data/run-classes.test",
      "new_id": "19a18046295d361a0630c4e6088da5fb95ef752e",
      "new_mode": 33188,
      "new_path": "mypyc/test-data/run-classes.test"
    }
  ]
}
