mirror of
https://github.com/python/cpython.git
synced 2025-08-02 16:13:13 +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
|
Special read-only attribute: :attr:`__dict__` is the module's namespace as a
|
||||||
dictionary object.
|
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::
|
.. index::
|
||||||
single: __name__ (module attribute)
|
single: __name__ (module attribute)
|
||||||
single: __doc__ (module attribute)
|
single: __doc__ (module attribute)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Test the module type
|
# Test the module type
|
||||||
import unittest
|
import unittest
|
||||||
from test.test_support import run_unittest
|
from test.test_support import run_unittest, gc_collect
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
ModuleType = type(sys)
|
ModuleType = type(sys)
|
||||||
|
@ -55,14 +55,29 @@ class ModuleTests(unittest.TestCase):
|
||||||
{"__name__": "foo", "__doc__": "foodoc", "bar": 42})
|
{"__name__": "foo", "__doc__": "foodoc", "bar": 42})
|
||||||
self.assertTrue(foo.__dict__ is d)
|
self.assertTrue(foo.__dict__ is d)
|
||||||
|
|
||||||
|
@unittest.expectedFailure
|
||||||
def test_dont_clear_dict(self):
|
def test_dont_clear_dict(self):
|
||||||
# See issue 7140.
|
# See issue 7140.
|
||||||
def f():
|
def f():
|
||||||
foo = ModuleType("foo")
|
foo = ModuleType("foo")
|
||||||
foo.bar = 4
|
foo.bar = 4
|
||||||
return foo
|
return foo
|
||||||
|
gc_collect()
|
||||||
self.assertEqual(f().__dict__["bar"], 4)
|
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():
|
def test_main():
|
||||||
run_unittest(ModuleTests)
|
run_unittest(ModuleTests)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ What's New in Python 2.7.1?
|
||||||
Core and Builtins
|
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
|
- Issue #9869: Make long() and PyNumber_Long return something of type
|
||||||
long for a class whose __long__ method returns a plain int. This
|
long for a class whose __long__ method returns a plain int. This
|
||||||
fixes an interpreter crash when initializing an instance of a long
|
fixes an interpreter crash when initializing an instance of a long
|
||||||
|
|
|
@ -175,10 +175,7 @@ module_dealloc(PyModuleObject *m)
|
||||||
{
|
{
|
||||||
PyObject_GC_UnTrack(m);
|
PyObject_GC_UnTrack(m);
|
||||||
if (m->md_dict != NULL) {
|
if (m->md_dict != NULL) {
|
||||||
/* If we are the only ones holding a reference, we can clear
|
_PyModule_Clear((PyObject *)m);
|
||||||
the dictionary. */
|
|
||||||
if (Py_REFCNT(m->md_dict) == 1)
|
|
||||||
_PyModule_Clear((PyObject *)m);
|
|
||||||
Py_DECREF(m->md_dict);
|
Py_DECREF(m->md_dict);
|
||||||
}
|
}
|
||||||
Py_TYPE(m)->tp_free((PyObject *)m);
|
Py_TYPE(m)->tp_free((PyObject *)m);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue