]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-154638: Use lazy imports in argparse (#154639)
authorSavannah Ostrowski <savannah@python.org>
Fri, 24 Jul 2026 20:33:26 +0000 (13:33 -0700)
committerGitHub <noreply@github.com>
Fri, 24 Jul 2026 20:33:26 +0000 (20:33 +0000)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Lib/argparse.py
Lib/test/test_argparse.py
Misc/NEWS.d/next/Library/2026-07-24-17-02-46.gh-issue-154638.7YnFHH.rst [new file with mode: 0644]

index 42891516b3bb2a09505b202478fd0195242f7479..f8739d031e01c58e2f54b0befb154ec861456b08 100644 (file)
@@ -87,12 +87,17 @@ __all__ = [
 
 
 import os as _os
-import re as _re
 import sys as _sys
-from gettext import gettext as _
-from gettext import ngettext
 
 lazy import _colorize
+lazy import copy
+lazy import difflib
+lazy import re as _re
+lazy import shutil
+lazy import textwrap
+lazy import warnings
+lazy from gettext import gettext as _
+lazy from gettext import ngettext
 
 SUPPRESS = '==SUPPRESS=='
 
@@ -143,10 +148,8 @@ def _copy_items(items):
         return []
     # The copy module is used only in the 'append' and 'append_const'
     # actions, and it is needed only when the default value isn't a list.
-    # Delay its import for speeding up the common case.
     if type(items) is list:
         return items[:]
-    import copy
     return copy.copy(items)
 
 
@@ -186,7 +189,6 @@ class HelpFormatter(object):
     ):
         # default setting for width
         if width is None:
-            import shutil
             width = shutil.get_terminal_size().columns
             width -= 2
 
@@ -773,9 +775,6 @@ class HelpFormatter(object):
 
     def _split_lines(self, text, width):
         text = self._whitespace_matcher.sub(' ', text).strip()
-        # The textwrap module is used only for formatting help.
-        # Delay its import for speeding up the common usage of argparse.
-        import textwrap
         decolored = self._decolor(text)
         if decolored == text:
             return textwrap.wrap(text, width)
@@ -808,7 +807,6 @@ class HelpFormatter(object):
 
     def _fill_text(self, text, width, indent):
         text = self._whitespace_matcher.sub(' ', text).strip()
-        import textwrap
         return textwrap.fill(text, width,
                              initial_indent=indent,
                              subsequent_indent=indent)
@@ -1486,7 +1484,6 @@ class FileType(object):
     """
 
     def __init__(self, mode='r', bufsize=-1, encoding=None, errors=None):
-        import warnings
         warnings.warn(
             "FileType is deprecated. Simply open files after parsing arguments.",
             category=PendingDeprecationWarning,
@@ -1893,7 +1890,6 @@ class _ArgumentGroup(_ActionsContainer):
 
     def __init__(self, container, title=None, description=None, **kwargs):
         if 'prefix_chars' in kwargs:
-            import warnings
             depr_msg = (
                 "The use of the undocumented 'prefix_chars' parameter in "
                 "ArgumentParser.add_argument_group() is deprecated."
@@ -2824,7 +2820,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
 
             if self.suggest_on_error and isinstance(value, str):
                 if all(isinstance(choice, str) for choice in action.choices):
-                    import difflib
                     suggestions = difflib.get_close_matches(value, action.choices, 1)
                     if suggestions:
                         args['closest'] = suggestions[0]
@@ -2964,8 +2959,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
 
 def __getattr__(name):
     if name == "__version__":
-        from warnings import _deprecated
-
-        _deprecated("__version__", remove=(3, 20))
+        warnings._deprecated("__version__", remove=(3, 20))
         return "1.1"  # Do not change
     raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
index fbeb933841129e31bca4a093e80c38263733fc61..442cbb1aaadfe3f85e870f84302b213e691ee69e 100644 (file)
@@ -3,7 +3,6 @@
 import _colorize
 import contextlib
 import functools
-import inspect
 import io
 import operator
 import os
@@ -12,6 +11,7 @@ import stat
 import sys
 import textwrap
 import tempfile
+import types
 import unittest
 import argparse
 import warnings
@@ -85,6 +85,8 @@ class TestLazyImports(unittest.TestCase):
         "_colorize",
         "copy",
         "difflib",
+        "gettext",
+        "re",
         "shutil",
         "textwrap",
         "warnings",
@@ -99,7 +101,7 @@ class TestLazyImports(unittest.TestCase):
         # Test imports are still unused after
         # creating a parser
         create_parser = "argparse.ArgumentParser()"
-        imported_modules = {"shutil"}
+        imported_modules = {"gettext", "re", "shutil"}
 
         import_helper.ensure_lazy_imports(
             "argparse",
@@ -114,7 +116,7 @@ class TestLazyImports(unittest.TestCase):
             parser.add_subparsers(dest='command', required=False)
             """
         )
-        imported_modules = {"shutil"}
+        imported_modules = {"gettext", "re", "shutil"}
 
         import_helper.ensure_lazy_imports(
             "argparse",
@@ -132,7 +134,7 @@ class TestLazyImports(unittest.TestCase):
             parser.parse_args(['BAR', '--foo', 'FOO'])
             """
         )
-        imported_modules = {"shutil"}
+        imported_modules = {"gettext", "re", "shutil"}
         import_helper.ensure_lazy_imports(
             "argparse",
             self.LAZY_IMPORTS - imported_modules,
@@ -7098,7 +7100,10 @@ class TestImportStar(TestCase):
             name
             for name, value in vars(argparse).items()
             if not (name.startswith("_") or name == 'ngettext')
-            if not inspect.ismodule(value)
+            if not isinstance(
+                value,
+                (types.ModuleType, types.LazyImportType),
+            )
         ]
         self.assertEqual(sorted(items), sorted(argparse.__all__))
 
diff --git a/Misc/NEWS.d/next/Library/2026-07-24-17-02-46.gh-issue-154638.7YnFHH.rst b/Misc/NEWS.d/next/Library/2026-07-24-17-02-46.gh-issue-154638.7YnFHH.rst
new file mode 100644 (file)
index 0000000..91c2264
--- /dev/null
@@ -0,0 +1 @@
+Improve import time of :mod:`argparse` by lazily importing several dependencies.