a Python bug in processing __del__ method ??

Discussion in 'Python' started by Baoqiu Cui, Jan 31, 2005.

  1. Baoqiu Cui

    Baoqiu Cui Guest

    Today I was playing with a small Python program using Python 2.4
    on Cygwin (up-to-date version, on Windows XP), but ran into a
    strange error on the following small program (named bug.py):

    -------------------------------
    #!/usr/bin/python

    class Person:
    population = 0
    def __del__(self):
    Person.population -= 1

    peter = Person()
    -------------------------------

    The error returned is this:

    $ python bug.py
    Exception exceptions.AttributeError: "'NoneType' object has no
    attribute 'population'" in <bound method Person.__del__ of
    <__main__.Person instance at 0xa0c9fec>> ignored

    However, if I rename variable name 'peter' to something like 'peter1'
    or 'david', the error is gone. Looks to me the
    error only happens to variable name 'peter'.

    Does anyone know what is wrong? Is this a bug only on Cygwin?
    - Baoqiu
     
    Baoqiu Cui, Jan 31, 2005
    #1
    1. Advertising

  2. Baoqiu Cui wrote:

    > The error returned is this:
    >
    > $ python bug.py
    > Exception exceptions.AttributeError: "'NoneType' object has no
    > attribute 'population'" in <bound method Person.__del__ of
    > <__main__.Person instance at 0xa0c9fec>> ignored
    >
    > However, if I rename variable name 'peter' to something like 'peter1'
    > or 'david', the error is gone. Looks to me the
    > error only happens to variable name 'peter'.
    >
    > Does anyone know what is wrong? Is this a bug only on Cygwin?


    it is not a bug, and the documentation has the answer:

    language reference -> index -> __del__

    http://docs.python.org/ref/customization.html#l2h-175

    Warning: Due to the precarious circumstances under which __del__()
    methods are invoked, exceptions that occur during their execution are
    ignored, and a warning is printed to sys.stderr instead. Also, when
    __del__() is invoked in response to a module being deleted (e.g.,
    when execution of the program is done), other globals referenced by
    the __del__() method may already have been deleted. For this reason,
    __del__() methods should do the absolute minimum needed to
    maintain external invariants.

    if you absolutely need to have reliable access to globals, you need to make
    sure they're available as instance variables, or are bound in some other way.

    </F>
     
    Fredrik Lundh, Jan 31, 2005
    #2
    1. Advertising

  3. Baoqiu Cui wrote:
    > Today I was playing with a small Python program using Python 2.4
    > on Cygwin (up-to-date version, on Windows XP), but ran into a
    > strange error on the following small program (named bug.py):
    >
    > -------------------------------
    > #!/usr/bin/python
    >
    > class Person:
    > population = 0
    > def __del__(self):
    > Person.population -= 1
    >
    > peter = Person()
    > -------------------------------
    >
    > The error returned is this:
    >
    > $ python bug.py
    > Exception exceptions.AttributeError: "'NoneType' object has no
    > attribute 'population'" in <bound method Person.__del__ of
    > <__main__.Person instance at 0xa0c9fec>> ignored
    >
    > However, if I rename variable name 'peter' to something like 'peter1'
    > or 'david', the error is gone. Looks to me the
    > error only happens to variable name 'peter'.
    >
    > Does anyone know what is wrong? Is this a bug only on Cygwin?


    I get this error on a normal Python WinXP install too. Looks like
    Python deletes globals in order when exiting, so the Person class gets
    deleted before the Person instances:

    ---------- bug.py ----------
    class Person(object):
    population = 0
    def __del__(self):
    Person.population -= 1

    <name> = Person()
    print list(globals())
    ----------------------------

    I tried this with a few different names. Here are the results for
    'apple', 'banana' and 'cranberry'. Only when the name appears after
    'Person' in the globals do I get the error that you get.

    [D:\Steve]$ bug.py
    ['apple', '__builtins__', '__file__', 'Person', '__name__', '__doc__']

    [D:\Steve]$ bug.py
    ['__builtins__', '__file__', 'banana', 'Person', '__name__', '__doc__']

    [D:\Steve]$ bug.py
    ['__builtins__', '__file__', 'Person', 'cranberry', '__name__', '__doc__']
    Exception exceptions.AttributeError: "'NoneType' object has no attribute
    'population'" in <bound method Person.__del__ of <__main__.Person object
    at 0x009D1A50>> ignored

    I don't know whether this is a bug or a "feature". ;)

    Steve
     
    Steven Bethard, Jan 31, 2005
    #3
  4. Fredrik Lundh wrote:
    > Baoqiu Cui wrote:
    >
    >>The error returned is this:
    >>
    >>$ python bug.py
    >>Exception exceptions.AttributeError: "'NoneType' object has no
    >>attribute 'population'" in <bound method Person.__del__ of
    >><__main__.Person instance at 0xa0c9fec>> ignored
    >>
    >>However, if I rename variable name 'peter' to something like 'peter1'
    >>or 'david', the error is gone. Looks to me the
    >>error only happens to variable name 'peter'.
    >>
    >>Does anyone know what is wrong? Is this a bug only on Cygwin?

    >
    > it is not a bug, and the documentation has the answer:
    >
    > language reference -> index -> __del__
    >
    > http://docs.python.org/ref/customization.html#l2h-175
    >
    > Warning: Due to the precarious circumstances under which __del__()
    > methods are invoked, exceptions that occur during their execution are
    > ignored, and a warning is printed to sys.stderr instead. Also, when
    > __del__() is invoked in response to a module being deleted (e.g.,
    > when execution of the program is done), other globals referenced by
    > the __del__() method may already have been deleted. For this reason,
    > __del__() methods should do the absolute minimum needed to
    > maintain external invariants.
    >
    > if you absolutely need to have reliable access to globals, you need to make
    > sure they're available as instance variables, or are bound in some other way.


    Along these lines, I think changing your code to:

    class Person(object):
    population = 0
    def __del__(self):
    self.__class__.population -= 1

    peter = Person()

    solves the problem. (At least it did for me.)

    Steve
     
    Steven Bethard, Jan 31, 2005
    #4
  5. Baoqiu Cui

    Baoqiu Cui Guest

    Fredrik and Steve,

    Thank you so much for the help. Now I know more about Python. :)

    Steve's test does explain why 'peter1' is OK while 'peter' is not:
    'peter1' appears
    before 'Person' in the globals while 'peter' is after.

    The error message is just a little confusing to a Python newbie, I
    think.

    Thanks again!

    - Baoqiu
     
    Baoqiu Cui, Jan 31, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jane Austine
    Replies:
    2
    Views:
    369
    Steven Taschuk
    Jul 2, 2003
  2. Stewart Midwinter

    How do I define a __del__ method for an object?

    Stewart Midwinter, Mar 7, 2004, in forum: Python
    Replies:
    3
    Views:
    557
    Peter Otten
    Mar 7, 2004
  3. David MacQuigg

    Bug in __del__ function

    David MacQuigg, Jun 24, 2004, in forum: Python
    Replies:
    2
    Views:
    304
    David MacQuigg
    Jun 24, 2004
  4. Holger Joukl
    Replies:
    0
    Views:
    353
    Holger Joukl
    Dec 13, 2006
  5. Marco Buttu
    Replies:
    2
    Views:
    134
    Marco Buttu
    Sep 14, 2013
Loading...

Share This Page