diff -r c13398566409 Lib/test/test_enumerate.py --- a/Lib/test/test_enumerate.py Wed Mar 12 12:41:44 2014 +0100 +++ b/Lib/test/test_enumerate.py Wed Mar 12 15:49:53 2014 +0200 @@ -2,6 +2,7 @@ import operator import sys import pickle +import weakref from test import support @@ -235,6 +236,27 @@ for data in 'abc', range(5), tuple(enumerate('abc')), range(1,17,5): self.check_pickle(reversed(data), list(data)[::-1]) + def test_weakref(self): + class Foo: + def __init__(self): + self.data = [1, 2, 3, 4] + + def __len__(self): + return len(self.data) + + def __getitem__(self, index): + return self.data[index] + + foo = Foo() + proxy = weakref.proxy(foo) + self.assertEqual(list(reversed(proxy)), + [4, 3, 2, 1]) + del foo + + with self.assertRaises(TypeError) as cm: + reversed(proxy) + self.assertEqual(str(cm.exception), + "argument to reversed() was dereferenced") class EnumerateStartTestCase(EnumerateTestCase): diff -r c13398566409 Objects/enumobject.c --- a/Objects/enumobject.c Wed Mar 12 12:41:44 2014 +0100 +++ b/Objects/enumobject.c Wed Mar 12 15:49:53 2014 +0200 @@ -259,9 +259,20 @@ return NULL; if (!PySequence_Check(seq)) { - PyErr_SetString(PyExc_TypeError, - "argument to reversed() must be a sequence"); - return NULL; + if (!PyWeakref_CheckProxy(seq)) { + PyErr_SetString(PyExc_TypeError, + "argument to reversed() must be a sequence"); + return NULL; + } + else { + PyTypeObject *s = (PyTypeObject *) PyWeakref_GetObject(seq); + if ((PyObject *)s == Py_None) { + PyErr_SetString(PyExc_TypeError, + "argument to reversed() was dereferenced"); + return NULL; + } else + seq = s; + } } n = PySequence_Size(seq);