From 9cbb64cf8a850dafebf68abb16a9cb9b12db247c Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 25 May 2024 07:25:27 -0700 Subject: [PATCH 1/2] gh-117865: Defer import of re in ast This is used only by ast.get_source_segment(), so it seems sensible to avoid importing it. --- Lib/ast.py | 8 ++++++-- .../2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst diff --git a/Lib/ast.py b/Lib/ast.py index 031bab43df7579..8ac1860a5448c6 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -25,7 +25,6 @@ :license: Python License. """ import sys -import re from _ast import * from contextlib import contextmanager, nullcontext from enum import IntEnum, auto, _simple_enum @@ -325,12 +324,17 @@ def get_docstring(node, clean=True): return text -_line_pattern = re.compile(r"(.*?(?:\r\n|\n|\r|$))") +_line_pattern = None def _splitlines_no_ff(source, maxlines=None): """Split a string into lines ignoring form feed and other chars. This mimics how the Python parser splits source code. """ + global _line_pattern + if _line_pattern is None: + import re + _line_pattern = re.compile(r"(.*?(?:\r\n|\n|\r|$))") + lines = [] for lineno, match in enumerate(_line_pattern.finditer(source), 1): if maxlines is not None and lineno > maxlines: diff --git a/Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst b/Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst new file mode 100644 index 00000000000000..48cd390d1bb128 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-05-25-07-25-07.gh-issue-117865.1A0Xpi.rst @@ -0,0 +1,2 @@ +Improve the import time of the :mod:`ast` module by deferring the import of +:mod:`re`. Patch by Jelle Zijlstra. From 967f7d921322c0bca270517673e711de32b8fdc3 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 26 May 2024 10:28:48 -0700 Subject: [PATCH 2/2] Update Lib/ast.py Co-authored-by: Alex Waygood --- Lib/ast.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/ast.py b/Lib/ast.py index 8ac1860a5448c6..ce92cf79739312 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -332,6 +332,7 @@ def _splitlines_no_ff(source, maxlines=None): """ global _line_pattern if _line_pattern is None: + # lazily computed to speedup import time of `ast` import re _line_pattern = re.compile(r"(.*?(?:\r\n|\n|\r|$))")