When first UNWRAP(x) succeeds but second UNWRAP(y) fails (dead proxy), x's new reference is leaked. Affects ~20 binary operators (+, -, *, /, |, &, ^, etc.).
import weakref, sys, gc
class C:
def __add__(self, other): return NotImplemented
def __radd__(self, other): return NotImplemented
obj = type('D', (), {})()
dead = weakref.proxy(obj)
del obj; gc.collect()
live_obj = C()
live = weakref.proxy(live_obj)
before = sys.gettotalrefcount()
for i in range(10000):
try:
live + dead
except ReferenceError:
pass
after = sys.gettotalrefcount()
print(f"Leaked {after - before} refs (~{(after-before)//10000}/call)")