classification
Title: global objects created in some module are not destroyed when last reference to that module is released
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.1, Python 3.2, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Valery.Lesin, amaury.forgeotdarc, benjamin.peterson, haypo, pitrou
Priority: normal Keywords:

Created on 2010-10-12 10:09 by Valery.Lesin, last changed 2010-10-13 01:05 by benjamin.peterson. This issue is now closed.

Messages (9)
msg118408 - (view) Author: Valery Lesin (Valery.Lesin) Date: 2010-10-12 10:09
Interpreter: Python 3.1.2

Sample:

===== first.py =====
import sys
import second 

if 'second' in sys.modules:
  print ('in sys modules')
  del sys.modules['second']

del second

===== second.py =====
class A:
 def __init__(self):
   print('created')

 def __del__(self):
   print('destroyed')

a = A()
---------------------------------------------

Result: 'destroyed' isn't printed
With Python 2.6.5 it worked fine
msg118412 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2010-10-12 11:24
This also reproduces in 2.7.
2.6 and 2.7 have a different behaviour.
msg118418 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-10-12 12:19
Probably issue7140, which will disable clearing of the module dict if it's caught in a reference cycle (which it is here, since A.__init__ and A.__del__ will reference it as their globals dict).
msg118474 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-10-12 21:16
Tricky. I think the only way to do this properly is to call _PyModule_Clear when the dict is destroyed. However, there's no good way to flag a dictionary as a "module" dict. Therefore, I propose we remove the Py_REFCNT == 1 guard in module_dealloc, and simply leave as an open bug that modules will clear their dictionaries on deallocation. Thoughts?
msg118475 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-10-12 21:19
> Therefore, I propose we remove the Py_REFCNT == 1 guard in
> module_dealloc, and simply leave as an open bug that modules will clear 
> their dictionaries on deallocation.

Yes, I think it's the best solution. People can easily copy the dict if they want to keep it around after the module gets destroyed.
msg118481 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-10-12 22:58
r85392.
msg118494 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2010-10-13 00:36
r85393 introduced a regression in test_runpy of Python 2.7.
msg118495 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2010-10-13 00:55
test_runpy fails also on Python 3.2.
msg118496 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-10-13 01:05
r85398
History
Date User Action Args
2010-10-13 01:05:25benjamin.petersonsetstatus: open -> closed
resolution: fixed
messages: + msg118496
2010-10-13 00:55:20hayposetmessages: + msg118495
2010-10-13 00:36:54hayposetstatus: closed -> open

nosy: + haypo
messages: + msg118494

resolution: fixed -> (no value)
2010-10-12 22:58:28benjamin.petersonsetstatus: open -> closed
resolution: fixed
messages: + msg118481
2010-10-12 21:19:37pitrousetmessages: + msg118475
2010-10-12 21:16:41benjamin.petersonsetmessages: + msg118474
2010-10-12 12:19:03pitrousetnosy: + pitrou, benjamin.peterson
messages: + msg118418
2010-10-12 11:24:42amaury.forgeotdarcsetnosy: + amaury.forgeotdarc

messages: + msg118412
versions: + Python 2.7
2010-10-12 10:09:26Valery.Lesincreate