merge 3.2 (#3787e896dbe9)

This commit is contained in:
Benjamin Peterson 2012-03-07 18:52:52 -06:00
commit 9a6338651e
3 changed files with 27 additions and 4 deletions

View File

@ -1,8 +1,10 @@
import builtins import builtins
import gc
import sys import sys
import types import types
import math import math
import unittest import unittest
import weakref
from copy import deepcopy from copy import deepcopy
from test import support from test import support
@ -1186,7 +1188,6 @@ order (MRO) for bases """
self.assertEqual(Counted.counter, 0) self.assertEqual(Counted.counter, 0)
# Test lookup leaks [SF bug 572567] # Test lookup leaks [SF bug 572567]
import gc
if hasattr(gc, 'get_objects'): if hasattr(gc, 'get_objects'):
class G(object): class G(object):
def __eq__(self, other): def __eq__(self, other):
@ -4387,7 +4388,6 @@ order (MRO) for bases """
self.assertRaises(AttributeError, getattr, C(), "attr") self.assertRaises(AttributeError, getattr, C(), "attr")
self.assertEqual(descr.counter, 4) self.assertEqual(descr.counter, 4)
import gc
class EvilGetattribute(object): class EvilGetattribute(object):
# This used to segfault # This used to segfault
def __getattr__(self, name): def __getattr__(self, name):
@ -4484,6 +4484,21 @@ order (MRO) for bases """
ns = {'__qualname__': 1} ns = {'__qualname__': 1}
self.assertRaises(TypeError, type, 'Foo', (), ns) self.assertRaises(TypeError, type, 'Foo', (), ns)
def test_cycle_through_dict(self):
# See bug #1469629
class X(dict):
def __init__(self):
dict.__init__(self)
self.__dict__ = self
x = X()
x.attr = 42
wr = weakref.ref(x)
del x
support.gc_collect()
self.assertIsNone(wr())
for o in gc.get_objects():
self.assertIsNot(type(o), X)
class DictProxyTests(unittest.TestCase): class DictProxyTests(unittest.TestCase):
def setUp(self): def setUp(self):

View File

@ -10,6 +10,9 @@ What's New in Python 3.3.0 Alpha 2?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #1469629: Allow cycles through an object's __dict__ slot to be
collected. (For example if ``x.__dict__ is x``).
- Issue #14205: dict lookup raises a RuntimeError if the dict is modified - Issue #14205: dict lookup raises a RuntimeError if the dict is modified
during a lookup. during a lookup.

View File

@ -862,8 +862,13 @@ subtype_clear(PyObject *self)
assert(base); assert(base);
} }
/* There's no need to clear the instance dict (if any); /* Clear the instance dict (if any), to break cycles involving only
the collector will call its tp_clear handler. */ __dict__ slots (as in the case 'self.__dict__ is self'). */
if (type->tp_dictoffset != base->tp_dictoffset) {
PyObject **dictptr = _PyObject_GetDictPtr(self);
if (dictptr && *dictptr)
Py_CLEAR(*dictptr);
}
if (baseclear) if (baseclear)
return baseclear(self); return baseclear(self);