mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
Merged revisions 85392 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r85392 | benjamin.peterson | 2010-10-12 17:57:59 -0500 (Tue, 12 Oct 2010) | 1 line prefer clearing global objects to obscure module.__dict__ bugs #10068 ........
This commit is contained in:
parent
d2f6ae63cd
commit
dc9542435b
4 changed files with 27 additions and 5 deletions
|
@ -739,6 +739,13 @@ Modules
|
|||
Special read-only attribute: :attr:`__dict__` is the module's namespace as a
|
||||
dictionary object.
|
||||
|
||||
.. impl-detail::
|
||||
|
||||
Because of the way CPython clears module dictionaries, the module
|
||||
dictionary will be cleared when the module falls out of scope even if the
|
||||
dictionary still has live references. To avoid this, copy the dictionary
|
||||
or keep the module around while using its dictionary directly.
|
||||
|
||||
.. index::
|
||||
single: __name__ (module attribute)
|
||||
single: __doc__ (module attribute)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Test the module type
|
||||
import unittest
|
||||
from test.test_support import run_unittest
|
||||
from test.test_support import run_unittest, gc_collect
|
||||
|
||||
import sys
|
||||
ModuleType = type(sys)
|
||||
|
@ -55,14 +55,29 @@ class ModuleTests(unittest.TestCase):
|
|||
{"__name__": "foo", "__doc__": "foodoc", "bar": 42})
|
||||
self.assertTrue(foo.__dict__ is d)
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_dont_clear_dict(self):
|
||||
# See issue 7140.
|
||||
def f():
|
||||
foo = ModuleType("foo")
|
||||
foo.bar = 4
|
||||
return foo
|
||||
gc_collect()
|
||||
self.assertEqual(f().__dict__["bar"], 4)
|
||||
|
||||
def test_clear_dict_in_ref_cycle(self):
|
||||
destroyed = []
|
||||
m = ModuleType("foo")
|
||||
m.destroyed = destroyed
|
||||
s = """class A:
|
||||
def __del__(self):
|
||||
destroyed.append(1)
|
||||
a = A()"""
|
||||
exec(s, m.__dict__)
|
||||
del m
|
||||
gc_collect()
|
||||
self.assertEqual(destroyed, [1])
|
||||
|
||||
def test_main():
|
||||
run_unittest(ModuleTests)
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 2.7.1?
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #10068: Global objects which have reference cycles with their module's
|
||||
dict are now cleared again. This causes issue #7140 to appear again.
|
||||
|
||||
- Issue #9869: Make long() and PyNumber_Long return something of type
|
||||
long for a class whose __long__ method returns a plain int. This
|
||||
fixes an interpreter crash when initializing an instance of a long
|
||||
|
|
|
@ -175,10 +175,7 @@ module_dealloc(PyModuleObject *m)
|
|||
{
|
||||
PyObject_GC_UnTrack(m);
|
||||
if (m->md_dict != NULL) {
|
||||
/* If we are the only ones holding a reference, we can clear
|
||||
the dictionary. */
|
||||
if (Py_REFCNT(m->md_dict) == 1)
|
||||
_PyModule_Clear((PyObject *)m);
|
||||
_PyModule_Clear((PyObject *)m);
|
||||
Py_DECREF(m->md_dict);
|
||||
}
|
||||
Py_TYPE(m)->tp_free((PyObject *)m);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue