Issue 9826: OrderedDict.__repr__ did not play well with self-referencing dicts.

This commit is contained in:
Raymond Hettinger 2010-09-13 22:14:36 +00:00
parent 46287f551b
commit 74f869eb94
3 changed files with 37 additions and 0 deletions

View File

@ -12,6 +12,32 @@ import sys as _sys
import heapq as _heapq
from itertools import repeat as _repeat, chain as _chain, starmap as _starmap, \
ifilter as _ifilter, imap as _imap
try:
from thread import get_ident
except AttributeError:
from dummy_thread import get_ident
def _recursive_repr(user_function):
'Decorator to make a repr function return "..." for a recursive call'
repr_running = set()
def wrapper(self):
key = id(self), get_ident()
if key in repr_running:
return '...'
repr_running.add(key)
try:
result = user_function(self)
finally:
repr_running.discard(key)
return result
# Can't use functools.wraps() here because of bootstrap issues
wrapper.__module__ = getattr(user_function, '__module__')
wrapper.__doc__ = getattr(user_function, '__doc__')
wrapper.__name__ = getattr(user_function, '__name__')
return wrapper
################################################################################
### OrderedDict
@ -142,6 +168,7 @@ class OrderedDict(dict, MutableMapping):
value = self.pop(key)
return key, value
@_recursive_repr
def __repr__(self):
'od.__repr__() <==> repr(od)'
if not self:

View File

@ -926,6 +926,13 @@ class TestOrderedDict(unittest.TestCase):
self.assertEqual(eval(repr(od)), od)
self.assertEqual(repr(OrderedDict()), "OrderedDict()")
def test_repr_recursive(self):
# See issue #9826
od = OrderedDict.fromkeys('abc')
od['x'] = od
self.assertEqual(repr(od),
"OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
def test_setdefault(self):
pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
shuffle(pairs)

View File

@ -43,6 +43,9 @@ Core and Builtins
Library
-------
- Issue #9826: OrderedDict.__repr__ can now handle self-referential
values: d['x'] = d.
- Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
(macpath module).