mirror of https://github.com/python/cpython.git
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
93f5cd42e7
commit
582162e42b
|
@ -654,6 +654,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.support import run_unittest
|
||||
from test.support import run_unittest, gc_collect
|
||||
|
||||
import sys
|
||||
ModuleType = type(sys)
|
||||
|
@ -55,14 +55,29 @@ def test_reinit(self):
|
|||
{"__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)
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ Core and Builtins
|
|||
|
||||
- Issue #83755: Implicit set-to-frozenset conversion was not thread-safe.
|
||||
|
||||
- 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 #9416: Fix some issues with complex formatting where the
|
||||
output with no type specifier failed to match the str output:
|
||||
|
||||
|
|
|
@ -312,10 +312,7 @@ module_dealloc(PyModuleObject *m)
|
|||
if (m->md_def && m->md_def->m_free)
|
||||
m->md_def->m_free(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);
|
||||
}
|
||||
if (m->md_state != NULL)
|
||||
|
|
Loading…
Reference in New Issue