This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Class instance apparently not destructed when expected
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 2.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: ajaksu2, mwh, nnorwitz, peterdonis
Priority: normal Keywords:

Created on 2006-09-07 03:26 by peterdonis, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
deltest.py peterdonis, 2006-09-07 03:27 Python Test Script (deltest.py)
del-ref.py nnorwitz, 2006-09-07 07:34 refleak test
deltest2.py peterdonis, 2006-09-08 03:05
Messages (6)
msg29785 - (view) Author: Peter Donis (peterdonis) Date: 2006-09-07 03:26
When an instance variable of a class with the same 
name as a class variable in a base class is assigned 
a value (making the class variable of the base class 
invisible), the class instance does not appear to be 
destructed when it should.

Here is the simplest test script I've been able to 
come up with that reproduces the error, along with 
its output when run from a shell prompt. I've 
included the dir() commands to make sure that the 
variable referencing the class instance is in fact 
deleted in both cases. As you can see, the instance 
of the base class gets destructed as expected, but 
the instance of the derived class does not.

--- Test script ---

#!/usr/bin/env python
# Test script to see when objects are freed

class Test(object):
    
    testfield = None
    
    def __init__(self):
        print "Initializing test object."
    
    def __del__(self):
        print "Freeing test object."

class Test2(Test):
    
    def __init__(self):
        # This masks Test.testfield
        self.testfield = self.meth
        Test.__init__(self)
    
    def meth(self):
        pass

print dir()
t = Test()
print dir()
del t
print dir()
t2 = Test2()
print dir()
del t2
print dir()

--- Output ---

$ python deltest.py
['Test', 'Test2', '__builtins__', '__doc__', '__file__', '__name__', 'func']
Initializing test object.
['Test', 'Test2', '__builtins__', '__doc__', '__file__', '__name__', 'func', 't']
Freeing test object.
['Test', 'Test2', '__builtins__', '__doc__', '__file__', '__name__', 'func']
Initializing test object.
['Test', 'Test2', '__builtins__', '__doc__', '__file__', '__name__', 'func', 't2']
['Test', 'Test2', '__builtins__', '__doc__', '__file__', '__name__', 'func']
msg29786 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-09-07 07:19
Logged In: YES 
user_id=33168

The attached variant puts this into a function and shows ref
leaks.  It requires a debug build.
msg29787 - (view) Author: Michael Hudson (mwh) (Python committer) Date: 2006-09-07 14:06
Logged In: YES 
user_id=6656

It's a reference cycle featuring an object with a __del__ --> it ends up in 
gc.garbage.

More coffee for Neal?
msg29788 - (view) Author: Peter Donis (peterdonis) Date: 2006-09-08 03:05
Logged In: YES 
user_id=1592444

mwh's comment is correct. See attached script deltest2.py, 
showing the contents of gc.garbage and how the reference 
cycle can be cleared (script output shown below). Note that 
I eliminated the base class and the masking of its class 
field; that was a red herring. My only other question is 
whether it might be worthwhile to add a sentence or two to 
the description of bound method objects in the 
documentation to make it clearer that you're creating a 
reference to the class instance.

--- script output ---

$ python deltest2.py
['Test', '__builtins__', '__doc__', '__file__', '__name__', 
'gc']
Initializing test object.
['Test', '__builtins__', '__doc__', '__file__', '__name__', 
'gc', 't']
['Test', '__builtins__', '__doc__', '__file__', '__name__', 
'gc']
[]
gc: uncollectable <Test 0xb7c3f34c>
gc: uncollectable <dict 0xb7c4c1c4>
gc: uncollectable <instancemethod 0xb7cb86bc>
3
[<__main__.Test object at 0xb7c3f34c>, {'testfield': <bound 
method Test.meth of <__main__.Test object at 0xb7c3f34c>>}, 
<bound method Test.meth of <__main__.Test object at 
0xb7c3f34c>>]
[]
0
['Test', '__builtins__', '__doc__', '__file__', '__name__', 
'g', 'gc']
Freeing test object.
msg29789 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-09-08 03:09
Logged In: YES 
user_id=33168

Michael: coffee, no, sleep, yes. :-)
msg84481 - (view) Author: Daniel Diniz (ajaksu2) * (Python triager) Date: 2009-03-30 03:23
Closing as invalid. If someone wants to salvage the doc RFE, please reopen.
History
Date User Action Args
2022-04-11 14:56:20adminsetgithub: 43953
2009-03-30 03:23:38ajaksu2setstatus: open -> closed

type: behavior

nosy: + ajaksu2
messages: + msg84481
resolution: not a bug
stage: resolved
2006-09-07 03:26:02peterdoniscreate