mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-118761: Improve import time of pprint
(#122725)
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
This commit is contained in:
parent
f9637b4ba3
commit
42d9bec98f
2 changed files with 23 additions and 4 deletions
|
@ -35,8 +35,6 @@ saferepr()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import collections as _collections
|
import collections as _collections
|
||||||
import dataclasses as _dataclasses
|
|
||||||
import re
|
|
||||||
import sys as _sys
|
import sys as _sys
|
||||||
import types as _types
|
import types as _types
|
||||||
from io import StringIO as _StringIO
|
from io import StringIO as _StringIO
|
||||||
|
@ -54,6 +52,7 @@ def pprint(object, stream=None, indent=1, width=80, depth=None, *,
|
||||||
underscore_numbers=underscore_numbers)
|
underscore_numbers=underscore_numbers)
|
||||||
printer.pprint(object)
|
printer.pprint(object)
|
||||||
|
|
||||||
|
|
||||||
def pformat(object, indent=1, width=80, depth=None, *,
|
def pformat(object, indent=1, width=80, depth=None, *,
|
||||||
compact=False, sort_dicts=True, underscore_numbers=False):
|
compact=False, sort_dicts=True, underscore_numbers=False):
|
||||||
"""Format a Python object into a pretty-printed representation."""
|
"""Format a Python object into a pretty-printed representation."""
|
||||||
|
@ -61,22 +60,27 @@ def pformat(object, indent=1, width=80, depth=None, *,
|
||||||
compact=compact, sort_dicts=sort_dicts,
|
compact=compact, sort_dicts=sort_dicts,
|
||||||
underscore_numbers=underscore_numbers).pformat(object)
|
underscore_numbers=underscore_numbers).pformat(object)
|
||||||
|
|
||||||
|
|
||||||
def pp(object, *args, sort_dicts=False, **kwargs):
|
def pp(object, *args, sort_dicts=False, **kwargs):
|
||||||
"""Pretty-print a Python object"""
|
"""Pretty-print a Python object"""
|
||||||
pprint(object, *args, sort_dicts=sort_dicts, **kwargs)
|
pprint(object, *args, sort_dicts=sort_dicts, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def saferepr(object):
|
def saferepr(object):
|
||||||
"""Version of repr() which can handle recursive data structures."""
|
"""Version of repr() which can handle recursive data structures."""
|
||||||
return PrettyPrinter()._safe_repr(object, {}, None, 0)[0]
|
return PrettyPrinter()._safe_repr(object, {}, None, 0)[0]
|
||||||
|
|
||||||
|
|
||||||
def isreadable(object):
|
def isreadable(object):
|
||||||
"""Determine if saferepr(object) is readable by eval()."""
|
"""Determine if saferepr(object) is readable by eval()."""
|
||||||
return PrettyPrinter()._safe_repr(object, {}, None, 0)[1]
|
return PrettyPrinter()._safe_repr(object, {}, None, 0)[1]
|
||||||
|
|
||||||
|
|
||||||
def isrecursive(object):
|
def isrecursive(object):
|
||||||
"""Determine if object requires a recursive representation."""
|
"""Determine if object requires a recursive representation."""
|
||||||
return PrettyPrinter()._safe_repr(object, {}, None, 0)[2]
|
return PrettyPrinter()._safe_repr(object, {}, None, 0)[2]
|
||||||
|
|
||||||
|
|
||||||
class _safe_key:
|
class _safe_key:
|
||||||
"""Helper function for key functions when sorting unorderable objects.
|
"""Helper function for key functions when sorting unorderable objects.
|
||||||
|
|
||||||
|
@ -99,10 +103,12 @@ class _safe_key:
|
||||||
return ((str(type(self.obj)), id(self.obj)) < \
|
return ((str(type(self.obj)), id(self.obj)) < \
|
||||||
(str(type(other.obj)), id(other.obj)))
|
(str(type(other.obj)), id(other.obj)))
|
||||||
|
|
||||||
|
|
||||||
def _safe_tuple(t):
|
def _safe_tuple(t):
|
||||||
"Helper function for comparing 2-tuples"
|
"Helper function for comparing 2-tuples"
|
||||||
return _safe_key(t[0]), _safe_key(t[1])
|
return _safe_key(t[0]), _safe_key(t[1])
|
||||||
|
|
||||||
|
|
||||||
class PrettyPrinter:
|
class PrettyPrinter:
|
||||||
def __init__(self, indent=1, width=80, depth=None, stream=None, *,
|
def __init__(self, indent=1, width=80, depth=None, stream=None, *,
|
||||||
compact=False, sort_dicts=True, underscore_numbers=False):
|
compact=False, sort_dicts=True, underscore_numbers=False):
|
||||||
|
@ -179,12 +185,15 @@ class PrettyPrinter:
|
||||||
max_width = self._width - indent - allowance
|
max_width = self._width - indent - allowance
|
||||||
if len(rep) > max_width:
|
if len(rep) > max_width:
|
||||||
p = self._dispatch.get(type(object).__repr__, None)
|
p = self._dispatch.get(type(object).__repr__, None)
|
||||||
|
# Lazy import to improve module import time
|
||||||
|
from dataclasses import is_dataclass
|
||||||
|
|
||||||
if p is not None:
|
if p is not None:
|
||||||
context[objid] = 1
|
context[objid] = 1
|
||||||
p(self, object, stream, indent, allowance, context, level + 1)
|
p(self, object, stream, indent, allowance, context, level + 1)
|
||||||
del context[objid]
|
del context[objid]
|
||||||
return
|
return
|
||||||
elif (_dataclasses.is_dataclass(object) and
|
elif (is_dataclass(object) and
|
||||||
not isinstance(object, type) and
|
not isinstance(object, type) and
|
||||||
object.__dataclass_params__.repr and
|
object.__dataclass_params__.repr and
|
||||||
# Check dataclass has generated repr method.
|
# Check dataclass has generated repr method.
|
||||||
|
@ -197,9 +206,12 @@ class PrettyPrinter:
|
||||||
stream.write(rep)
|
stream.write(rep)
|
||||||
|
|
||||||
def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
|
def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
|
||||||
|
# Lazy import to improve module import time
|
||||||
|
from dataclasses import fields as dataclass_fields
|
||||||
|
|
||||||
cls_name = object.__class__.__name__
|
cls_name = object.__class__.__name__
|
||||||
indent += len(cls_name) + 1
|
indent += len(cls_name) + 1
|
||||||
items = [(f.name, getattr(object, f.name)) for f in _dataclasses.fields(object) if f.repr]
|
items = [(f.name, getattr(object, f.name)) for f in dataclass_fields(object) if f.repr]
|
||||||
stream.write(cls_name + '(')
|
stream.write(cls_name + '(')
|
||||||
self._format_namespace_items(items, stream, indent, allowance, context, level)
|
self._format_namespace_items(items, stream, indent, allowance, context, level)
|
||||||
stream.write(')')
|
stream.write(')')
|
||||||
|
@ -291,6 +303,9 @@ class PrettyPrinter:
|
||||||
if len(rep) <= max_width1:
|
if len(rep) <= max_width1:
|
||||||
chunks.append(rep)
|
chunks.append(rep)
|
||||||
else:
|
else:
|
||||||
|
# Lazy import to improve module import time
|
||||||
|
import re
|
||||||
|
|
||||||
# A list of alternating (non-space, space) strings
|
# A list of alternating (non-space, space) strings
|
||||||
parts = re.findall(r'\S*\s*', line)
|
parts = re.findall(r'\S*\s*', line)
|
||||||
assert parts
|
assert parts
|
||||||
|
@ -632,9 +647,11 @@ class PrettyPrinter:
|
||||||
rep = repr(object)
|
rep = repr(object)
|
||||||
return rep, (rep and not rep.startswith('<')), False
|
return rep, (rep and not rep.startswith('<')), False
|
||||||
|
|
||||||
|
|
||||||
_builtin_scalars = frozenset({str, bytes, bytearray, float, complex,
|
_builtin_scalars = frozenset({str, bytes, bytearray, float, complex,
|
||||||
bool, type(None)})
|
bool, type(None)})
|
||||||
|
|
||||||
|
|
||||||
def _recursion(object):
|
def _recursion(object):
|
||||||
return ("<Recursion on %s with id=%s>"
|
return ("<Recursion on %s with id=%s>"
|
||||||
% (type(object).__name__, id(object)))
|
% (type(object).__name__, id(object)))
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Improve import time of :mod:`pprint` by around seven times. Patch by Hugo
|
||||||
|
van Kemenade.
|
Loading…
Add table
Add a link
Reference in a new issue