https://github.com/python/cpython/commit/95be16eb7b89c9775cfffbf6e5a5da1d3df71225
commit: 95be16eb7b89c9775cfffbf6e5a5da1d3df71225
branch: 3.14
author: Miss Islington (bot) <[email protected]>
committer: savannahostrowski <[email protected]>
date: 2026-02-17T02:53:51Z
summary:

[3.14] gh-144782: Make sure that ArgumentParser instances are pickleable 
(GH-144783) (#144895)

gh-144782: Make sure that ArgumentParser instances are pickleable (GH-144783)
(cherry picked from commit 2f7634c0291c92cf1e040fc81c4210f0883e6036)

Co-authored-by: Mauricio Villegas <[email protected]>
Co-authored-by: Bartosz SÅ‚awecki <[email protected]>
Co-authored-by: AN Long <[email protected]>
Co-authored-by: Savannah Ostrowski <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Lib/argparse.py b/Lib/argparse.py
index 1d7d34f9924326..8cf856943002de 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -149,6 +149,10 @@ def _copy_items(items):
     return copy.copy(items)
 
 
+def _identity(value):
+    return value
+
+
 # ===============
 # Formatting Help
 # ===============
@@ -200,7 +204,7 @@ def _set_color(self, color):
             self._decolor = decolor
         else:
             self._theme = get_theme(force_no_color=True).argparse
-            self._decolor = lambda text: text
+            self._decolor = _identity
 
     # ===============================
     # Section and indentation methods
@@ -1903,9 +1907,7 @@ def __init__(self,
         self._subparsers = None
 
         # register types
-        def identity(string):
-            return string
-        self.register('type', None, identity)
+        self.register('type', None, _identity)
 
         # add help argument if necessary
         # (using explicit default to override global argument_default)
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index f48fb765bb31d1..8331d021813424 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -81,6 +81,27 @@ def test_skip_invalid_stdout(self):
                 self.assertRegex(mocked_stderr.getvalue(), r'usage:')
 
 
+class TestArgumentParserPickleable(unittest.TestCase):
+
+    @force_not_colorized
+    def test_pickle_roundtrip(self):
+        import pickle
+        parser = argparse.ArgumentParser(exit_on_error=False)
+        parser.add_argument('--foo', type=int, default=42)
+        parser.add_argument('bar', nargs='?', default='baz')
+        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+            with self.subTest(protocol=proto):
+                # Try to pickle and unpickle the parser
+                parser2 = pickle.loads(pickle.dumps(parser, protocol=proto))
+                # Check that the round-tripped parser still works
+                ns = parser2.parse_args(['--foo', '123', 'quux'])
+                self.assertEqual(ns.foo, 123)
+                self.assertEqual(ns.bar, 'quux')
+                ns2 = parser2.parse_args([])
+                self.assertEqual(ns2.foo, 42)
+                self.assertEqual(ns2.bar, 'baz')
+
+
 class TestCase(unittest.TestCase):
 
     def setUp(self):
diff --git 
a/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst 
b/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst
new file mode 100644
index 00000000000000..871005fd7d986c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-02-13-14-20-10.gh-issue-144782.0Y8TKj.rst
@@ -0,0 +1 @@
+Fix :class:`argparse.ArgumentParser` to be :mod:`pickleable <pickle>`.

_______________________________________________
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