Index: Lib/pprint.py =================================================================== --- Lib/pprint.py (revision 76934) +++ Lib/pprint.py (working copy) @@ -70,6 +70,38 @@ """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): + try: + if hasattr(self.obj, '__lt__'): + rv = self.obj.__lt__(other.obj) + else: + rv = self.obj.__cmp__(other.obj) < 0 + except TypeError: + rv = NotImplemented + 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 @@ -144,8 +176,7 @@ if length: context[objid] = 1 indent = indent + self._indent_per_level - items = object.items() - items.sort() + items = sorted(object.items(), key=_safe_tuple) key, ent = items[0] rep = self._repr(key, context, level) write(rep) @@ -181,7 +212,7 @@ return write('set([') endchar = '])' - object = sorted(object) + object = sorted(object, key=_safe_key) indent += 4 elif issubclass(typ, frozenset): if not length: @@ -189,7 +220,7 @@ return write('frozenset([') endchar = '])' - object = sorted(object) + object = sorted(object, key=_safe_key) indent += 10 else: write('(') @@ -274,7 +305,8 @@ append = components.append level += 1 saferepr = _safe_repr - for k, v in sorted(object.items()): + 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) append("%s: %s" % (krepr, vrepr))