SIGN IN SIGN UP

[mypyc] Borrow final attributes more aggressively (#21702)

Final instance attributes of native classes can't be rebound after
initialization, so we can borrow them more aggressively than regular
attributes, as long as the base object is kept alive for the duration of
the borrowing. This allows skipping some incref/decref operations.

Many workloads spend a significant fraction of CPU on incref/decref, and
these operations are quite a bit more expensive on free-threaded builds,
so the potential performance impact is significant especially on
free-threaded builds.

For example, the attribute `x` can only be safely borrowed if it's
Final, since otherwise `foo` could assign to the attribute and free the
old value:
```py
def func(o: C) -> None:
    foo(o.x)
```

There are some subtleties in the implementation. Here are the main
things that required extra care:
* We don't allow borrowed values to escape from conditionally executed
code paths (e.g. conditional expressions, comprehensions).
* If a local variable can be modified with an assignment expression, we
restrict borrowing based on that variable.
* We can only borrow for a longer duration if the attribute value
doesn't depend on a subexpression with a smaller borrow scope.
* Lambda expressions generate a complete separate expression and
borrowing scope.
 
I used coding agent assist, especially for tests, but created the
implementation is short, individually reviewed increments.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
J
Jukka Lehtosalo committed
3d75cdb09f0928fa8b83e5ef03572ed878ac8d09
Parent: 24c237d
Committed by GitHub <noreply@github.com> on 7/9/2026, 6:24:21 PM