summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2009-10-15 15:44:46 (GMT)
committerBenjamin Peterson <benjamin@python.org>2009-10-15 15:44:46 (GMT)
commit196b0925ca55bf22ffbb97733cff3e63d4fb6e18 (patch)
treec546b34790bc5d6b122a7213886579fbad62c1b7
parent96e319e5ac93c7342ca3edd2322dad688199fac6 (diff)
downloadcpython-196b0925ca55bf22ffbb97733cff3e63d4fb6e18.zip
cpython-196b0925ca55bf22ffbb97733cff3e63d4fb6e18.tar.gz
cpython-196b0925ca55bf22ffbb97733cff3e63d4fb6e18.tar.bz2
only clear a module's __dict__ if the module is the only one with a reference to it #7140
-rw-r--r--Lib/test/test_module.py8
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/moduleobject.c5
3 files changed, 15 insertions, 1 deletions
diff --git a/Lib/test/test_module.py b/Lib/test/test_module.py
index 80d440d..638f55b 100644
--- a/Lib/test/test_module.py
+++ b/Lib/test/test_module.py
@@ -55,6 +55,14 @@ class ModuleTests(unittest.TestCase):
{"__name__": "foo", "__doc__": "foodoc", "bar": 42})
self.assertTrue(foo.__dict__ is d)
+ def test_dont_clear_dict(self):
+ # See issue 7140.
+ def f():
+ foo = ModuleType("foo")
+ foo.bar = 4
+ return foo
+ self.assertEqual(f().__dict__["bar"], 4)
+
def test_main():
run_unittest(ModuleTests)
diff --git a/Misc/NEWS b/Misc/NEWS
index 276fc56..0e85ba0 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1
Core and Builtins
-----------------
+- Issue #7140: The __dict__ of a module should not be cleared unless the module
+ is the only object holding a reference to it.
+
- Issue #1754094: Improve the stack depth calculation in the compiler.
There should be no other effect than a small decrease in memory use.
Patch by Christopher Tur Lesniewski-Laas.
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index d1aa771..c9f00e9 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -175,7 +175,10 @@ module_dealloc(PyModuleObject *m)
{
PyObject_GC_UnTrack(m);
if (m->md_dict != NULL) {
- _PyModule_Clear((PyObject *)m);
+ /* 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);
Py_DECREF(m->md_dict);
}
Py_TYPE(m)->tp_free((PyObject *)m);