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 00:16:54 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 00:16:54 2013 +0100 @@ -3256,13 +3256,22 @@ { PyObject *seq; PyObject *result; + 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; + if (seq == NULL) { + result = NULL; + goto Done; + } result = PyUnicode_FromFormat("%s(%R)", Py_TYPE(dv)->tp_name, seq); Py_DECREF(seq); +Done: + Py_ReprLeave((PyObject *)dv); return result; }