Memory leak when invoking __iadd__ via __get__ without using temporary
trying modify a decorator not to use a weakref, I stumbled across the
following behaviour:
import weakref
class descriptor(object):
def __get__(self, instance, owner):
return proxy(instance)
class proxy(object):
def __init__(self, instance):
self.instance = instance
def __iadd__(self, other):
return self
class A(object):
descr = descriptor()
def is_leaky(test_fn):
a = A()
wr = weakref.ref(a)
test_fn(a)
del a
return wr() is not None
def test1(a):
tmp = a.descr
tmp += object()
def test2(a):
a.descr += object()
print(is_leaky(test1)) # gives False
print(is_leaky(test2)) # gives True!!!
This seems very odd to me, as I'd expect both cases to behave the same.
Furthermore, from my understanding of reference counting and object
lifetime, I was convinced that in both cases the object should be freed.
I have tested it both on python2.7 and python3.3.
Is this a bug or intentional behaviour? Is there a way to get both calls
to have the expected results (free the object in question)?
I do not want to use a weakref in proxy because this destroys the correct
object lifetime semantics for bound methods:
a = A()
descr = a.descr
del a # a is kept alive since descr is a bound method to a
descr() # should execute a.descr() as expected
No comments:
Post a Comment