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: Unexpected module garbage collection
Type: behavior Stage:
Components: None Versions: Python 3.1, Python 2.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, j_pok, pitrou
Priority: normal Keywords:

Created on 2009-07-02 13:56 by j_pok, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
broken_module.py j_pok, 2009-07-02 13:56
Messages (3)
msg90011 - (view) Author: (j_pok) Date: 2009-07-02 13:56
This code does not behave as I expected. Removing module from 
sys.modules and from local variable causes garbage collection (?) of 
module in spite of there is an instance of a class from this module. 
Instance method test() from TestClass returns global variable contained 
in module.

import sys

module = __import__("broken_module")
instance = module.TestClass()
print("a: "+str(instance.test()))
del sys.modules["broken_module"]
print("b: "+str(instance.test()))
del module
print("c: "+str(instance.test()))

Output:

a: test
b: test
c: None
msg90013 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2009-07-02 14:30
The class doesn't hold any references to the module, so naturally it
will be collected if you don't.
msg90014 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2009-07-02 14:32
This is a quirk of module finalization semantics. You've got to consider
the following facts:
- a class doesn't hold a reference to the module it is defined it,
because it doesn't need to (the __module__ attribute is a string)
- a function (and a method) holds a reference to the dictionary of
global variables of its defining namespace, that is, to the __dict__ of
the module, but not to the module itself
- therefore, if you remove all explicit references to the module, the
module will get garbage collected (but not its __dict__)
- when a module gets garbage collected, its attributes (members of its
__dict__) are first set to None, in an attempt to minimize circular
references issues

That's why, when you remove all explicit references to your module,
values of its __dict__ (including the "global_variable") get set to None.
(it is also why you shouldn't remove stuff from sys.modules unless you
really know what you are doing :-))
History
Date User Action Args
2022-04-11 14:56:50adminsetgithub: 50650
2009-07-02 14:32:03pitrousetnosy: + pitrou
messages: + msg90014
2009-07-02 14:30:51benjamin.petersonsetstatus: open -> closed

nosy: + benjamin.peterson
messages: + msg90013

resolution: not a bug
2009-07-02 13:56:23j_pokcreate