]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-107369: optimize textwrap.indent() (#107374)
authorInada Naoki <songofacandy@gmail.com>
Sat, 29 Jul 2023 06:37:23 +0000 (15:37 +0900)
committerGitHub <noreply@github.com>
Sat, 29 Jul 2023 06:37:23 +0000 (06:37 +0000)
Doc/whatsnew/3.13.rst
Lib/textwrap.py
Misc/NEWS.d/next/Library/2023-07-28-14-56-35.gh-issue-107369.bvTq8F.rst [new file with mode: 0644]

index 7cad5d1ec02aa785406921040730b711e3405f3e..e20832a3a4c3097c62a2e91a6466a5f49e79e9c1 100644 (file)
@@ -150,7 +150,8 @@ typing
 Optimizations
 =============
 
-
+* :func:`textwrap.indent` is now ~30% faster than before for large input.
+  (Contributed by Inada Naoki in :gh:`107369`.)
 
 
 Deprecated
index 98bedd27ea3a11995e2bf81a115df999767dc134..7ca393d1c371aad54a2d1d70fae15efa889175bb 100644 (file)
@@ -476,13 +476,19 @@ def indent(text, prefix, predicate=None):
     consist solely of whitespace characters.
     """
     if predicate is None:
-        def predicate(line):
-            return line.strip()
-
-    def prefixed_lines():
-        for line in text.splitlines(True):
-            yield (prefix + line if predicate(line) else line)
-    return ''.join(prefixed_lines())
+        # str.splitlines(True) doesn't produce empty string.
+        #  ''.splitlines(True) => []
+        #  'foo\n'.splitlines(True) => ['foo\n']
+        # So we can use just `not s.isspace()` here.
+        predicate = lambda s: not s.isspace()
+
+    prefixed_lines = []
+    for line in text.splitlines(True):
+        if predicate(line):
+            prefixed_lines.append(prefix)
+        prefixed_lines.append(line)
+
+    return ''.join(prefixed_lines)
 
 
 if __name__ == "__main__":
diff --git a/Misc/NEWS.d/next/Library/2023-07-28-14-56-35.gh-issue-107369.bvTq8F.rst b/Misc/NEWS.d/next/Library/2023-07-28-14-56-35.gh-issue-107369.bvTq8F.rst
new file mode 100644 (file)
index 0000000..76aeab6
--- /dev/null
@@ -0,0 +1,2 @@
+Optimize :func:`textwrap.indent`. It is ~30% faster for large input. Patch
+by Inada Naoki.