Subclassing PrettyPrinter.format doesn't work in all cases
Open
Nobody has claimed this yet.
stdlib
type-bug
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Bug report
Bug description:
See also the earlier fixed https://github.com/python/cpython/issues/73036. This appears to have only been a partial fix, or it has regressed.
import collections
import pprint
import types
SENTINAL = object()
class _hashable:
def __hash__(self):
return 1
HASHABLE_SENTINAL = _hashable()
class CustomPrettyPrinter(pprint.PrettyPrinter):
def format(self, obj, context, maxlevels, level):
if obj is SENTINAL:
return "SENTINAL", True, False
elif obj is HASHABLE_SENTINAL:
return "HASHABLE_SENTINAL", True, False
else:
return super().format(obj, context, maxlevels, level)
if __name__ == "__main__":
printer = CustomPrettyPrinter(sort_dicts=False)
test_data = {
"item": SENTINAL,
"dict": {"a": SENTINAL},
"dict_key": {HASHABLE_SENTINAL: 1},
"OrderedDict": collections.OrderedDict({"a": SENTINAL}),
"OrderedDict_key": collections.OrderedDict({HASHABLE_SENTINAL: 1}),
"list": [SENTINAL],
"tuple": (SENTINAL,),
"set": {SENTINAL},
"frozenset": frozenset({SENTINAL}),
"mappingproxy": types.MappingProxyType({"a": SENTINAL}),
"mappingproxy_key": types.MappingProxyType({HASHABLE_SENTINAL: 1}),
"SimpleNamespace": types.SimpleNamespace(a=SENTINAL),
"defaultdict": collections.defaultdict(list, {"a": SENTINAL}),
"defaultdict_key": collections.defaultdict(list, {HASHABLE_SENTINAL: 1}),
"Counter": collections.Counter({"a": SENTINAL}),
"Counter_key": collections.Counter({HASHABLE_SENTINAL: 1}),
"deque": collections.deque([SENTINAL]),
}
printer.pprint(test_data)
This outputs:
{'item': SENTINAL,
'dict': {'a': SENTINAL},
'dict_key': {HASHABLE_SENTINAL: 1},
'OrderedDict': OrderedDict({'a': <object object at 0x1041f4660>}),
'OrderedDict_key': OrderedDict([(HASHABLE_SENTINAL, 1)]),
'list': [SENTINAL],
'tuple': (SENTINAL,),
'set': {<object object at 0x1041f4660>},
'frozenset': frozenset({<object object at 0x1041f4660>}),
'mappingproxy': mappingproxy({'a': <object object at 0x1041f4660>}),
'mappingproxy_key': mappingproxy({HASHABLE_SENTINAL: 1}),
'SimpleNamespace': namespace(a=<object object at 0x1041f4660>),
'defaultdict': defaultdict(<class 'list'>,
{'a': SENTINAL}),
'defaultdict_key': defaultdict(<class 'list'>,
{HASHABLE_SENTINAL: 1}),
'Counter': Counter({'a': <object object at 0x1041f4660>}),
'Counter_key': Counter({<__main__._hashable object at 0x1045e4d70>: 1}),
'deque': deque([<object object at 0x1041f4660>])}
Every instance of < in that output is a bug.
CPython versions tested on:
3.13
Operating systems tested on:
macOS
Linked PRs
- gh-133238
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the reproducer and inspecting pprint.PrettyPrinter.format, especially how it handles the listed container types and their contents. Compare each output with the expected custom formatting, then add regression coverage for the cases where the override is bypassed. Done means every shown or repr from the reproducer honors the subclass's format method.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100