https://github.com/python/cpython/commit/42d9bec98fd846e16a3f4fa9a07e2024aae533ce
commit: 42d9bec98fd846e16a3f4fa9a07e2024aae533ce
branch: main
author: Hugo van Kemenade <[email protected]>
committer: hugovk <[email protected]>
date: 2024-08-07T22:46:54+03:00
summary:

gh-118761: Improve import time of `pprint` (#122725)

Co-authored-by: Adam Turner <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst
M Lib/pprint.py

diff --git a/Lib/pprint.py b/Lib/pprint.py
index 9314701db340c7..dc0953cec67a58 100644
--- a/Lib/pprint.py
+++ b/Lib/pprint.py
@@ -35,8 +35,6 @@
 """
 
 import collections as _collections
-import dataclasses as _dataclasses
-import re
 import sys as _sys
 import types as _types
 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)
     printer.pprint(object)
 
+
 def pformat(object, indent=1, width=80, depth=None, *,
             compact=False, sort_dicts=True, underscore_numbers=False):
     """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,
                          underscore_numbers=underscore_numbers).pformat(object)
 
+
 def pp(object, *args, sort_dicts=False, **kwargs):
     """Pretty-print a Python object"""
     pprint(object, *args, sort_dicts=sort_dicts, **kwargs)
 
+
 def saferepr(object):
     """Version of repr() which can handle recursive data structures."""
     return PrettyPrinter()._safe_repr(object, {}, None, 0)[0]
 
+
 def isreadable(object):
     """Determine if saferepr(object) is readable by eval()."""
     return PrettyPrinter()._safe_repr(object, {}, None, 0)[1]
 
+
 def isrecursive(object):
     """Determine if object requires a recursive representation."""
     return PrettyPrinter()._safe_repr(object, {}, None, 0)[2]
 
+
 class _safe_key:
     """Helper function for key functions when sorting unorderable objects.
 
@@ -99,10 +103,12 @@ def __lt__(self, other):
             return ((str(type(self.obj)), id(self.obj)) < \
                     (str(type(other.obj)), id(other.obj)))
 
+
 def _safe_tuple(t):
     "Helper function for comparing 2-tuples"
     return _safe_key(t[0]), _safe_key(t[1])
 
+
 class PrettyPrinter:
     def __init__(self, indent=1, width=80, depth=None, stream=None, *,
                  compact=False, sort_dicts=True, underscore_numbers=False):
@@ -179,12 +185,15 @@ def _format(self, object, stream, indent, allowance, 
context, level):
         max_width = self._width - indent - allowance
         if len(rep) > max_width:
             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:
                 context[objid] = 1
                 p(self, object, stream, indent, allowance, context, level + 1)
                 del context[objid]
                 return
-            elif (_dataclasses.is_dataclass(object) and
+            elif (is_dataclass(object) and
                   not isinstance(object, type) and
                   object.__dataclass_params__.repr and
                   # Check dataclass has generated repr method.
@@ -197,9 +206,12 @@ def _format(self, object, stream, indent, allowance, 
context, level):
         stream.write(rep)
 
     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__
         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 + '(')
         self._format_namespace_items(items, stream, indent, allowance, 
context, level)
         stream.write(')')
@@ -291,6 +303,9 @@ def _pprint_str(self, object, stream, indent, allowance, 
context, level):
             if len(rep) <= max_width1:
                 chunks.append(rep)
             else:
+                # Lazy import to improve module import time
+                import re
+
                 # A list of alternating (non-space, space) strings
                 parts = re.findall(r'\S*\s*', line)
                 assert parts
@@ -632,9 +647,11 @@ def _safe_repr(self, object, context, maxlevels, level):
         rep = repr(object)
         return rep, (rep and not rep.startswith('<')), False
 
+
 _builtin_scalars = frozenset({str, bytes, bytearray, float, complex,
                               bool, type(None)})
 
+
 def _recursion(object):
     return ("<Recursion on %s with id=%s>"
             % (type(object).__name__, id(object)))
diff --git 
a/Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst 
b/Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst
new file mode 100644
index 00000000000000..3f3e870b0b9565
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-08-06-10-36-55.gh-issue-118761.q_x_1A.rst
@@ -0,0 +1,2 @@
+Improve import time of :mod:`pprint` by around seven times. Patch by Hugo
+van Kemenade.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to