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.

Author ncoghlan
Recipients BreamoreBoy, Stefan.Friesel, andrea.corbellini, arigo, asvetlov, belopolsky, brett.cannon, cburroughs, christian.heimes, eric.snow, flox, glchapman, gregory.p.smith, loewis, nascheme, ncoghlan, pitrou
Date 2013-01-05.01:33:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1357349588.52.0.458780361296.issue812369@psf.upfronthosting.co.za>
In-reply-to
Content
In addition to the problem Neil noted with references in extension modules keeping module objects themselves alive, Antoine recently noted that the other major challenge is the reference cycles between module global dictionaries and their contents. As soon as a module global has both a __del__ method and a reference back to the module globals, the entire cycle becomes uncollectable. I suspect one of the reasons PyPy can cope without the explicit reference breaking step is that their GC is better able to cope with __del__ methods than ours.

I wonder if a useful interim step might be to make the current explicit reference breaking hack a bit smarter by looking at the reference counts. (Note: some aspects of this idea could be made simpler if modules supported weak references)

1. Call importlib.invalidate_caches()
2. Delete the first module from sys.modules that has a reference count of exactly one
3. Repeat 2 until sys.modules is empty or every remaining module has a reference count greater than 1 (meaning another module has a reference to it one way or another)
4. Pick the module in sys.modules with the lowest number of references to it, delete it from sys.modules and delete the reference from the module object to its dictionary
5. Repeat 4 until sys.modules is empty

Throughout the process, keep an eye on gc.garbage - if we see a module dict show up there, hit it with the "set all globals to None" hammer. (The new callback functionality in 3.3 makes that easier - for example, you could put a sentinel object in the globals of the module being cleared and watching for a dict containing that sentinel object showing up in 'uncollectable' during the stop phase)
History
Date User Action Args
2013-01-05 01:33:08ncoghlansetrecipients: + ncoghlan, loewis, brett.cannon, arigo, nascheme, glchapman, gregory.p.smith, belopolsky, pitrou, christian.heimes, andrea.corbellini, asvetlov, flox, cburroughs, BreamoreBoy, eric.snow, Stefan.Friesel
2013-01-05 01:33:08ncoghlansetmessageid: <1357349588.52.0.458780361296.issue812369@psf.upfronthosting.co.za>
2013-01-05 01:33:08ncoghlanlinkissue812369 messages
2013-01-05 01:33:06ncoghlancreate