mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
bpo-43080: pprint for dataclass instances (GH-24389)
* Added pprint support for dataclass instances which don't have a custom __repr__.
This commit is contained in:
parent
695d47b51e
commit
11159d2c9d
5 changed files with 133 additions and 14 deletions
|
@ -35,6 +35,7 @@ saferepr()
|
|||
"""
|
||||
|
||||
import collections as _collections
|
||||
import dataclasses as _dataclasses
|
||||
import re
|
||||
import sys as _sys
|
||||
import types as _types
|
||||
|
@ -178,8 +179,26 @@ class PrettyPrinter:
|
|||
p(self, object, stream, indent, allowance, context, level + 1)
|
||||
del context[objid]
|
||||
return
|
||||
elif (_dataclasses.is_dataclass(object) and
|
||||
not isinstance(object, type) and
|
||||
object.__dataclass_params__.repr and
|
||||
# Check dataclass has generated repr method.
|
||||
hasattr(object.__repr__, "__wrapped__") and
|
||||
"__create_fn__" in object.__repr__.__wrapped__.__qualname__):
|
||||
context[objid] = 1
|
||||
self._pprint_dataclass(object, stream, indent, allowance, context, level + 1)
|
||||
del context[objid]
|
||||
return
|
||||
stream.write(rep)
|
||||
|
||||
def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
|
||||
cls_name = object.__class__.__name__
|
||||
indent += len(cls_name) + 1
|
||||
items = [(f.name, getattr(object, f.name)) for f in _dataclasses.fields(object) if f.repr]
|
||||
stream.write(cls_name + '(')
|
||||
self._format_namespace_items(items, stream, indent, allowance, context, level)
|
||||
stream.write(')')
|
||||
|
||||
_dispatch = {}
|
||||
|
||||
def _pprint_dict(self, object, stream, indent, allowance, context, level):
|
||||
|
@ -346,21 +365,9 @@ class PrettyPrinter:
|
|||
else:
|
||||
cls_name = object.__class__.__name__
|
||||
indent += len(cls_name) + 1
|
||||
delimnl = ',\n' + ' ' * indent
|
||||
items = object.__dict__.items()
|
||||
last_index = len(items) - 1
|
||||
|
||||
stream.write(cls_name + '(')
|
||||
for i, (key, ent) in enumerate(items):
|
||||
stream.write(key)
|
||||
stream.write('=')
|
||||
|
||||
last = i == last_index
|
||||
self._format(ent, stream, indent + len(key) + 1,
|
||||
allowance if last else 1,
|
||||
context, level)
|
||||
if not last:
|
||||
stream.write(delimnl)
|
||||
self._format_namespace_items(items, stream, indent, allowance, context, level)
|
||||
stream.write(')')
|
||||
|
||||
_dispatch[_types.SimpleNamespace.__repr__] = _pprint_simplenamespace
|
||||
|
@ -382,6 +389,25 @@ class PrettyPrinter:
|
|||
if not last:
|
||||
write(delimnl)
|
||||
|
||||
def _format_namespace_items(self, items, stream, indent, allowance, context, level):
|
||||
write = stream.write
|
||||
delimnl = ',\n' + ' ' * indent
|
||||
last_index = len(items) - 1
|
||||
for i, (key, ent) in enumerate(items):
|
||||
last = i == last_index
|
||||
write(key)
|
||||
write('=')
|
||||
if id(ent) in context:
|
||||
# Special-case representation of recursion to match standard
|
||||
# recursive dataclass repr.
|
||||
write("...")
|
||||
else:
|
||||
self._format(ent, stream, indent + len(key) + 1,
|
||||
allowance if last else 1,
|
||||
context, level)
|
||||
if not last:
|
||||
write(delimnl)
|
||||
|
||||
def _format_items(self, items, stream, indent, allowance, context, level):
|
||||
write = stream.write
|
||||
indent += self._indent_per_level
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue