python / python/cpython

Subclassing PrettyPrinter.format doesn't work in all cases

未關閉
#132,855 5 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

stdlib type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

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

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

先執行 reproducer 並檢查 pprint.PrettyPrinter.format,尤其是它如何處理列出的容器類型及其內容。將每個輸出與預期的自訂格式進行比較,然後為 override 被繞過的情況新增回歸覆蓋。完成的標準是 reproducer 中顯示的每個 或 repr 都遵循子類別的 format 方法。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
tooling
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
描述清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。