Bug in __del__ function

From: David MacQuigg (dmq_at_gain.com)
Date: 06/24/04


Date: Wed, 23 Jun 2004 18:07:50 -0700

I'm __del__() to decrement a count of instances of a class whenever an
instance is deleted, and I'm getting very erratic behavior. This is
in CPython, which I am told has no problem with reference counts
getting out-of-sync with the deletion of instances. The behavior of
__del__() seems to be very sensitive to the exact sequence of
commands.

The example below is a repeatable test case. It might be possible to
simplify this further, but at this point, I haven't a clue as to why
it works with some sequences of commands, but not others.

I'm also not able to repeat the problem by putting the commands in the
file, and just running the file. Adding the necessary 'print'
keywords makes the problem go away. This could be just a problem in
IDLE, but unless I'm sure of that, I don't want to be using __del__ in
my programs.

Is this a bug, or have I misunderstood the use of __del__?

-- Dave

### test__del__.py

class Animal(object):
    _count = 0
    def __init__(self):
        print "Creating instance:", self
        self.__class__._count += 1
    def __del__(self):
        print "Deleting instance:", self
        self.__class__._count -= 1
        print countem()

class Mammal(Animal):
    _count = 0

class Cat(Mammal):
    _count = 0

def countem():
    str = ''
    for cls in Cat.__mro__[:-1]:
        str += '%9s:%s' % (cls.__name__, cls._count)
    return str

import sys
def rc(obj):
    print "sys.getrefcount(obj):", sys.getrefcount(obj)

### Run the above file in IDLE:

Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)]
on win32
...
IDLE 1.0.3
...
>>> ================================ RESTART ===================
>>>
>>> cat1 = Cat()
Creating instance: <__main__.Cat object at 0x00A11F70>
>>> cat2 = cat1
>>> countem()
' Cat:1 Mammal:0 Animal:0'
>>> rc(cat1)
sys.getrefcount(obj): 5
>>> rc(cat2)
sys.getrefcount(obj): 5
>>> del cat1
>>> cat2
<__main__.Cat object at 0x00A11F70>
>>> rc(cat2)
sys.getrefcount(obj): 5 ### Should be one less.
>>> del cat2 ### Should delete instance.
>>> countem()
Deleting instance: <__main__.Cat object at 0x00A11F70>
      Cat:0 Mammal:0 Animal:0
' Cat:1 Mammal:0 Animal:0' ### Count is wrong.
>>> countem()
' Cat:0 Mammal:0 Animal:0' ### Count is right.

### END ###



Relevant Pages

  • Re: looking for design patterns of interacting state machine
    ... do_x, do_y, do_z to an extern equipment, waits for the answer and ... B sends commands to the external board via RS232. ... Maybe you suggest that the sends command action be moved in the IDLE ... let it execute the desired actions. ...
    (comp.object)
  • Re: Python/IDLE - text in different colours
    ... The output (in blue, using IDLE) was: ... > programs from the input prompt, the commands, and the shell feedback. ... > Setting the colour of the text is fairly easy using ANSI terminal escape ... > Printing the output of external programs in dark red, ...
    (comp.lang.python)
  • Re: Quick help
    ... in directories in the unix v6 shell. ... Which also doesn't cause "erratic behavior" - it's just a security ... commands in their directory. ...
    (comp.unix.questions)
  • Re: libata passthru: support PIO multi commands
    ... At that point you know the bus is idle, all other commands ... have finished executing, and dev->multi_count is fresh not stale. ...
    (Linux-Kernel)
  • Re: killed users shell, but finger says theyre still logged in
    ... certain period of idle time... ... you need some extra program to run and log them ... So if a user is running a long, cpu bound job with no ... the programs that use the output of commands ...
    (comp.unix.aix)