Skip to content

Commit 42d9bec

Browse files
hugovkAA-Turner
andauthored
gh-118761: Improve import time of pprint (#122725)
Co-authored-by: Adam Turner <[email protected]>
1 parent f9637b4 commit 42d9bec

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

Diff for: Lib/pprint.py

+21-4
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
"""
3636

3737
import collections as _collections
38-
import dataclasses as _dataclasses
39-
import re
4038
import sys as _sys
4139
import types as _types
4240
from io import StringIO as _StringIO
@@ -54,29 +52,35 @@ def pprint(object, stream=None, indent=1, width=80, depth=None, *,
5452
underscore_numbers=underscore_numbers)
5553
printer.pprint(object)
5654

55+
5756
def pformat(object, indent=1, width=80, depth=None, *,
5857
compact=False, sort_dicts=True, underscore_numbers=False):
5958
"""Format a Python object into a pretty-printed representation."""
6059
return PrettyPrinter(indent=indent, width=width, depth=depth,
6160
compact=compact, sort_dicts=sort_dicts,
6261
underscore_numbers=underscore_numbers).pformat(object)
6362

63+
6464
def pp(object, *args, sort_dicts=False, **kwargs):
6565
"""Pretty-print a Python object"""
6666
pprint(object, *args, sort_dicts=sort_dicts, **kwargs)
6767

68+
6869
def saferepr(object):
6970
"""Version of repr() which can handle recursive data structures."""
7071
return PrettyPrinter()._safe_repr(object, {}, None, 0)[0]
7172

73+
7274
def isreadable(object):
7375
"""Determine if saferepr(object) is readable by eval()."""
7476
return PrettyPrinter()._safe_repr(object, {}, None, 0)[1]
7577

78+
7679
def isrecursive(object):
7780
"""Determine if object requires a recursive representation."""
7881
return PrettyPrinter()._safe_repr(object, {}, None, 0)[2]
7982

83+
8084
class _safe_key:
8185
"""Helper function for key functions when sorting unorderable objects.
8286
@@ -99,10 +103,12 @@ def __lt__(self, other):
99103
return ((str(type(self.obj)), id(self.obj)) < \
100104
(str(type(other.obj)), id(other.obj)))
101105

106+
102107
def _safe_tuple(t):
103108
"Helper function for comparing 2-tuples"
104109
return _safe_key(t[0]), _safe_key(t[1])
105110

111+
106112
class PrettyPrinter:
107113
def __init__(self, indent=1, width=80, depth=None, stream=None, *,
108114
compact=False, sort_dicts=True, underscore_numbers=False):
@@ -179,12 +185,15 @@ def _format(self, object, stream, indent, allowance, context, level):
179185
max_width = self._width - indent - allowance
180186
if len(rep) > max_width:
181187
p = self._dispatch.get(type(object).__repr__, None)
188+
# Lazy import to improve module import time
189+
from dataclasses import is_dataclass
190+
182191
if p is not None:
183192
context[objid] = 1
184193
p(self, object, stream, indent, allowance, context, level + 1)
185194
del context[objid]
186195
return
187-
elif (_dataclasses.is_dataclass(object) and
196+
elif (is_dataclass(object) and
188197
not isinstance(object, type) and
189198
object.__dataclass_params__.repr and
190199
# Check dataclass has generated repr method.
@@ -197,9 +206,12 @@ def _format(self, object, stream, indent, allowance, context, level):
197206
stream.write(rep)
198207

199208
def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
209+
# Lazy import to improve module import time
210+
from dataclasses import fields as dataclass_fields
211+
200212
cls_name = object.__class__.__name__
201213
indent += len(cls_name) + 1
202-
items = [(f.name, getattr(object, f.name)) for f in _dataclasses.fields(object) if f.repr]
214+
items = [(f.name, getattr(object, f.name)) for f in dataclass_fields(object) if f.repr]
203215
stream.write(cls_name + '(')
204216
self._format_namespace_items(items, stream, indent, allowance, context, level)
205217
stream.write(')')
@@ -291,6 +303,9 @@ def _pprint_str(self, object, stream, indent, allowance, context, level):
291303
if len(rep) <= max_width1:
292304
chunks.append(rep)
293305
else:
306+
# Lazy import to improve module import time
307+
import re
308+
294309
# A list of alternating (non-space, space) strings
295310
parts = re.findall(r'\S*\s*', line)
296311
assert parts
@@ -632,9 +647,11 @@ def _safe_repr(self, object, context, maxlevels, level):
632647
rep = repr(object)
633648
return rep, (rep and not rep.startswith('<')), False
634649

650+
635651
_builtin_scalars = frozenset({str, bytes, bytearray, float, complex,
636652
bool, type(None)})
637653

654+
638655
def _recursion(object):
639656
return ("<Recursion on %s with id=%s>"
640657
% (type(object).__name__, id(object)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve import time of :mod:`pprint` by around seven times. Patch by Hugo
2+
van Kemenade.

0 commit comments

Comments
 (0)