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: interpret termination, object deleting
Type: Stage:
Components: None Versions:
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: johnymart, loewis
Priority: normal Keywords:

Created on 2006-06-03 18:55 by johnymart, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
bugdemo.py johnymart, 2006-06-03 18:55 Make this file executable and run it. Do not use the interpretter.
Messages (2)
msg28701 - (view) Author: Jan Martinek (johnymart) Date: 2006-06-03 18:55
Hello,

I found out a strange behavior. This code

#!/usr/bin/python
class M:
  b = 0
  def __del__(self):
    M.b = 0

a1 = M()

results in exception when the program terminates.

Exception exceptions.AttributeError: "'NoneType' object
has no attribute 'b'" in <bound method M.__del__ of
<__main__.M instance at 0x2aaaaab50a28>> ignored

Note that the code must be run from an executable file
-not from the python interpretter. Otherwise the
exception is not thrown.

An interesting thing is that changing the last line to

a = M()

also prevents python from throwing the exception. Why
does it depend on variable's name?

bye
Jan Martinek
msg28702 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2006-06-04 19:56
Logged In: YES 
user_id=21627

On shutdown time, Python clears each module by replacing all
module entries with None. So at some point, it does
  a1 = None # or a1 = None
and at some other point, it does
  M = None
Depending on the order in which these happen, M might be
None (i.e. might not be class M anymore) when __del__ runs.

The order in which these happen depends on the order which
the names have in the module's dict. This, in turn, depends
on the hash values of the strings, modulo the size of the
dictionary. Apparently, "a1" gets hashed after "M", but "a"
gets hashed before "M".

This isn't really a bug, atleast not one that we plan to
fix. The order in which modules get emptied is unspecified,
and it can easily happen that things are gone when some
destructor runs. Classes should be written to be resistent
against this behaviour, e.g. by writing

  def __del__(self):
    self.__class__.b = 0 # name "M" might be gone already

Closing this as "won't fix".
History
Date User Action Args
2022-04-11 14:56:17adminsetgithub: 43450
2006-06-03 18:55:30johnymartcreate