Mercurial > cpython-lru_cache-weakref
diff Lib/pprint.py @ 57341:b8a0b333e469
Issue 3976: fix pprint for sets, frozensets, and dicts containing unorderable types.
| author | Raymond Hettinger <python@rcn.com> |
|---|---|
| date | Thu, 19 Nov 2009 01:07:05 +0000 |
| parents | 58a0d5524f9a |
| children | 9659e8c40079 |
line wrap: on
line diff
--- a/Lib/pprint.py Wed Nov 18 20:32:09 2009 +0000 +++ b/Lib/pprint.py Thu Nov 19 01:07:05 2009 +0000 @@ -70,6 +70,32 @@ """Determine if object requires a recursive representation.""" return _safe_repr(object, {}, None, 0)[2] +class _safe_key: + """Helper function for key functions when sorting unorderable objects. + + The wrapped-object will fallback to an Py2.x style comparison for + unorderable types (sorting first comparing the type name and then by + the obj ids). Does not work recursively, so dict.items() must have + _safe_key applied to both the key and the value. + + """ + + __slots__ = ['obj'] + + def __init__(self, obj): + self.obj = obj + + def __lt__(self, other): + rv = self.obj.__lt__(other.obj) + if rv is NotImplemented: + rv = (str(type(self.obj)), id(self.obj)) < \ + (str(type(other.obj)), id(other.obj)) + return rv + +def _safe_tuple(t): + "Helper function for comparing 2-tuples" + return _safe_key(t[0]), _safe_key(t[1]) + class PrettyPrinter: def __init__(self, indent=1, width=80, depth=None, stream=None): """Handle pretty printing operations onto a stream using a set of @@ -145,7 +171,7 @@ if length: context[objid] = 1 indent = indent + self._indent_per_level - items = sorted(object.items()) + items = sorted(object.items(), key=_safe_tuple) key, ent = items[0] rep = self._repr(key, context, level) write(rep) @@ -178,14 +204,14 @@ return write('{') endchar = '}' - object = sorted(object) + object = sorted(object, key=_safe_key) elif issubclass(typ, frozenset): if not length: write('frozenset()') return write('frozenset({') endchar = '})' - object = sorted(object) + object = sorted(object, key=_safe_key) indent += 10 else: write('(') @@ -267,14 +293,7 @@ append = components.append level += 1 saferepr = _safe_repr - items = object.items() - try: - items = sorted(items) - except TypeError: - def sortkey(item): - key, value = item - return str(type(key)), key, value - items = sorted(items, key=sortkey) + items = sorted(object.items(), key=_safe_tuple) for k, v in items: krepr, kreadable, krecur = saferepr(k, context, maxlevels, level) vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
