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]
