python / python/cpython

Subclassing PrettyPrinter.format doesn't work in all cases

Abierto
#132,855 5 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

stdlib type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza ejecutando el reproducer e inspeccionando pprint.PrettyPrinter.format, especialmente cómo gestiona los tipos de contenedor indicados y su contenido. Compara cada salida con el formato personalizado esperado y, después, añade cobertura de regresión para los casos en los que se omite el override. La tarea estará terminada cuando cada o repr mostrado por el reproducer respete el método format de la subclase.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
tooling
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bien especificado
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.