Skip to content

Commit 95be16e

Browse files
miss-islingtonmauvilsajohnslavikaisksavannahostrowski
authored
[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 2f7634c) Co-authored-by: Mauricio Villegas <5780272+mauvilsa@users.noreply.github.com> Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com> Co-authored-by: AN Long <aisk@users.noreply.github.com> Co-authored-by: Savannah Ostrowski <savannah@python.org>
1 parent 907958c commit 95be16e

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

Lib/argparse.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ def _copy_items(items):
149149
return copy.copy(items)
150150

151151

152+
def _identity(value):
153+
return value
154+
155+
152156
# ===============
153157
# Formatting Help
154158
# ===============
@@ -200,7 +204,7 @@ def _set_color(self, color):
200204
self._decolor = decolor
201205
else:
202206
self._theme = get_theme(force_no_color=True).argparse
203-
self._decolor = lambda text: text
207+
self._decolor = _identity
204208

205209
# ===============================
206210
# Section and indentation methods
@@ -1903,9 +1907,7 @@ def __init__(self,
19031907
self._subparsers = None
19041908

19051909
# register types
1906-
def identity(string):
1907-
return string
1908-
self.register('type', None, identity)
1910+
self.register('type', None, _identity)
19091911

19101912
# add help argument if necessary
19111913
# (using explicit default to override global argument_default)

Lib/test/test_argparse.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,27 @@ def test_skip_invalid_stdout(self):
8181
self.assertRegex(mocked_stderr.getvalue(), r'usage:')
8282

8383

84+
class TestArgumentParserPickleable(unittest.TestCase):
85+
86+
@force_not_colorized
87+
def test_pickle_roundtrip(self):
88+
import pickle
89+
parser = argparse.ArgumentParser(exit_on_error=False)
90+
parser.add_argument('--foo', type=int, default=42)
91+
parser.add_argument('bar', nargs='?', default='baz')
92+
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
93+
with self.subTest(protocol=proto):
94+
# Try to pickle and unpickle the parser
95+
parser2 = pickle.loads(pickle.dumps(parser, protocol=proto))
96+
# Check that the round-tripped parser still works
97+
ns = parser2.parse_args(['--foo', '123', 'quux'])
98+
self.assertEqual(ns.foo, 123)
99+
self.assertEqual(ns.bar, 'quux')
100+
ns2 = parser2.parse_args([])
101+
self.assertEqual(ns2.foo, 42)
102+
self.assertEqual(ns2.bar, 'baz')
103+
104+
84105
class TestCase(unittest.TestCase):
85106

86107
def setUp(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix :class:`argparse.ArgumentParser` to be :mod:`pickleable <pickle>`.

0 commit comments

Comments
 (0)