Skip to content

Commit af26c15

Browse files
committed
#9351: set_defaults on subparser is no longer ignored if set on parent.
Before, if a default was set on the parent parser, any default for that variable set via set_defaults on a subparser would be ignored. Now the subparser set_defaults is honored. Patch by Jyrki Pullianinen.
1 parent 10229a4 commit af26c15

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

Lib/argparse.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,14 @@ def __call__(self, parser, namespace, values, option_string=None):
10891089
# parse all the remaining options into the namespace
10901090
# store any unrecognized options on the object, so that the top
10911091
# level parser can decide what to do with them
1092-
namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
1092+
1093+
# In case this subparser defines new defaults, we parse them
1094+
# in a new namespace object and then update the original
1095+
# namespace for the relevant parts.
1096+
subnamespace, arg_strings = parser.parse_known_args(arg_strings, None)
1097+
for key, value in vars(subnamespace).items():
1098+
setattr(namespace, key, value)
1099+
10931100
if arg_strings:
10941101
vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
10951102
getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)

Lib/test/test_argparse.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2726,6 +2726,13 @@ def test_set_defaults_parents(self):
27262726
parser = ErrorRaisingArgumentParser(parents=[parent])
27272727
self.assertEqual(NS(x='foo'), parser.parse_args([]))
27282728

2729+
def test_set_defaults_on_parent_and_subparser(self):
2730+
parser = argparse.ArgumentParser()
2731+
xparser = parser.add_subparsers().add_parser('X')
2732+
parser.set_defaults(foo=1)
2733+
xparser.set_defaults(foo=2)
2734+
self.assertEqual(NS(foo=2), parser.parse_args(['X']))
2735+
27292736
def test_set_defaults_same_as_add_argument(self):
27302737
parser = ErrorRaisingArgumentParser()
27312738
parser.set_defaults(w='W', x='X', y='Y', z='Z')

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Core and Builtins
3737
Library
3838
-------
3939

40+
- Issue #9351: Defaults set with set_defaults on an argparse subparser
41+
are no longer ignored when also set on the parent parser.
42+
4043
- Issue #20421: Add a .version() method to SSL sockets exposing the actual
4144
protocol version in use.
4245

0 commit comments

Comments
 (0)