diff -r 042ff9325c5e Lib/test/test_dictviews.py --- a/Lib/test/test_dictviews.py Mon Jul 22 22:08:09 2013 -0700 +++ b/Lib/test/test_dictviews.py Wed Jul 24 07:31:35 2013 +0100 @@ -1,4 +1,5 @@ import unittest +import sys from test import support class DictSetTest(unittest.TestCase): @@ -182,6 +183,18 @@ def test_recursive_repr(self): d = {} d[42] = d.values() + r = repr(d) + self.assertIsInstance(r, str) + self.assertEqual(r, '{42: dict_values([...])}') + d[42] = d.items() + r = repr(d) + self.assertIsInstance(r, str) + self.assertEqual(r, '{42: dict_items([(42, ...)])}') + + def test_deeply_nested_repr(self): + d = {} + for i in range(sys.getrecursionlimit() + 100): + d = {42: d.values()} self.assertRaises(RuntimeError, repr, d) diff -r 042ff9325c5e Objects/dictobject.c --- a/Objects/dictobject.c Mon Jul 22 22:08:09 2013 -0700 +++ b/Objects/dictobject.c Wed Jul 24 07:31:35 2013 +0100 @@ -3255,14 +3255,21 @@ dictview_repr(dictviewobject *dv) { PyObject *seq; - PyObject *result; + PyObject *result = NULL; + Py_ssize_t rc; + + rc = Py_ReprEnter((PyObject *)dv); + if (rc != 0) + return rc > 0 ? PyUnicode_FromString("...") : NULL; seq = PySequence_List((PyObject *)dv); if (seq == NULL) - return NULL; + goto Done; result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq); Py_DECREF(seq); +Done: + Py_ReprLeave((PyObject *)dv); return result; }