diff --git a/Lib/pprint.py b/Lib/pprint.py index 92a2c543ac279c..e111bd59d4152c 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -235,6 +235,20 @@ def _pprint_dict(self, object, stream, indent, allowance, context, level): _dispatch[dict.__repr__] = _pprint_dict + def _pprint_frozendict(self, object, stream, indent, allowance, context, level): + write = stream.write + cls = object.__class__ + stream.write(cls.__name__ + '(') + length = len(object) + if length: + self._pprint_dict(object, stream, + indent + len(cls.__name__) + 1, + allowance + 1, + context, level) + write(')') + + _dispatch[frozendict.__repr__] = _pprint_frozendict + def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level): if not len(object): stream.write(repr(object)) @@ -623,12 +637,21 @@ def _safe_repr(self, object, context, maxlevels, level): else: return repr(object), True, False - if issubclass(typ, dict) and r is dict.__repr__: + if ((issubclass(typ, dict) and r is dict.__repr__) + or (issubclass(typ, frozendict) and r is frozendict.__repr__)): + is_frozendict = issubclass(typ, frozendict) if not object: - return "{}", True, False + if is_frozendict: + rep = f"{object.__class__.__name__}()" + else: + rep = "{}" + return rep, True, False objid = id(object) if maxlevels and level >= maxlevels: - return "{...}", False, objid in context + rep = "{...}" + if is_frozendict: + rep = f"{object.__class__.__name__}({rep})" + return rep, False, objid in context if objid in context: return _recursion(object), False, True context[objid] = 1 @@ -651,7 +674,10 @@ def _safe_repr(self, object, context, maxlevels, level): if krecur or vrecur: recursive = True del context[objid] - return "{%s}" % ", ".join(components), readable, recursive + rep = "{%s}" % ", ".join(components) + if is_frozendict: + rep = f"{object.__class__.__name__}({rep})" + return rep, readable, recursive if (issubclass(typ, list) and r is list.__repr__) or \ (issubclass(typ, tuple) and r is tuple.__repr__): diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index 41c337ade7eca1..f3860a5d511989 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -67,6 +67,13 @@ class dict3(dict): def __repr__(self): return dict.__repr__(self) +class frozendict2(frozendict): + pass + +class frozendict3(frozendict): + def __repr__(self): + return frozendict.__repr__(self) + class dict_custom_repr(dict): def __repr__(self): return '*'*len(dict.__repr__(self)) @@ -254,18 +261,22 @@ def test_same_as_repr(self): set(), set2(), set3(), frozenset(), frozenset2(), frozenset3(), {}, dict2(), dict3(), + frozendict(), frozendict2(), frozendict3(), {}.keys(), {}.values(), {}.items(), MappingView({}), KeysView({}), ItemsView({}), ValuesView({}), self.assertTrue, pprint, -6, -6, -6-6j, -1.5, "x", b"x", bytearray(b"x"), (3,), [3], {3: 6}, - (1,2), [3,4], {5: 6}, + (1,2), [3,4], tuple2((1,2)), tuple3((1,2)), tuple3(range(100)), [3,4], list2([3,4]), list3([3,4]), list3(range(100)), set({7}), set2({7}), set3({7}), frozenset({8}), frozenset2({8}), frozenset3({8}), - dict2({5: 6}), dict3({5: 6}), + {5: 6}, dict2({5: 6}), dict3({5: 6}), + frozendict({5: 6}), frozendict2({5: 6}), frozendict3({5: 6}), {5: 6}.keys(), {5: 6}.values(), {5: 6}.items(), + frozendict({5: 6}).keys(), frozendict({5: 6}).values(), + frozendict({5: 6}).items(), MappingView({5: 6}), KeysView({5: 6}), ItemsView({5: 6}), ValuesView({5: 6}), range(10, -11, -1), @@ -330,20 +341,45 @@ def test_basic_line_wrap(self): for type in [dict, dict2]: self.assertEqual(pprint.pformat(type(o)), exp) + exp = """\ +frozendict({'RPM_cal': 0, + 'RPM_cal2': 48059, + 'Speed_cal': 0, + 'controldesk_runtime_us': 0, + 'main_code_runtime_us': 0, + 'read_io_runtime_us': 0, + 'write_io_runtime_us': 43690})""" + self.assertEqual(pprint.pformat(frozendict(o)), exp) + exp = """\ +frozendict2({'RPM_cal': 0, + 'RPM_cal2': 48059, + 'Speed_cal': 0, + 'controldesk_runtime_us': 0, + 'main_code_runtime_us': 0, + 'read_io_runtime_us': 0, + 'write_io_runtime_us': 43690})""" + self.assertEqual(pprint.pformat(frozendict2(o)), exp) + o = range(100) exp = 'dict_keys([%s])' % ',\n '.join(map(str, o)) keys = dict.fromkeys(o).keys() self.assertEqual(pprint.pformat(keys), exp) + keys = frozendict.fromkeys(o).keys() + self.assertEqual(pprint.pformat(keys), exp) o = range(100) exp = 'dict_values([%s])' % ',\n '.join(map(str, o)) values = {v: v for v in o}.values() self.assertEqual(pprint.pformat(values), exp) + values = frozendict({v: v for v in o}).values() + self.assertEqual(pprint.pformat(values), exp) o = range(100) exp = 'dict_items([%s])' % ',\n '.join("(%s, %s)" % (i, i) for i in o) items = {v: v for v in o}.items() self.assertEqual(pprint.pformat(items), exp) + items = frozendict({v: v for v in o}).items() + self.assertEqual(pprint.pformat(items), exp) o = range(100) exp = 'odict_keys([%s])' % ',\n '.join(map(str, o))