Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fca2e8a

Browse files
committed
Fix bug 9340 - argparse parse_known_args didn't work with subparsers
1 parent b68928b commit fca2e8a

2 files changed

Lines changed: 34 additions & 2 deletions

File tree

Lib/argparse.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ def _callable(obj):
102102
ONE_OR_MORE = '+'
103103
PARSER = 'A...'
104104
REMAINDER = '...'
105+
_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
105106

106107
# =============================
107108
# Utility functions and classes
@@ -1083,7 +1084,12 @@ def __call__(self, parser, namespace, values, option_string=None):
10831084
raise ArgumentError(self, msg)
10841085

10851086
# parse all the remaining options into the namespace
1086-
parser.parse_args(arg_strings, namespace)
1087+
# store any unrecognized options on the object, so that the top
1088+
# level parser can decide what to do with them
1089+
namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
1090+
if arg_strings:
1091+
vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
1092+
getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
10871093

10881094

10891095
# ==============
@@ -1699,7 +1705,11 @@ def parse_known_args(self, args=None, namespace=None):
16991705

17001706
# parse the arguments and exit if there are any errors
17011707
try:
1702-
return self._parse_known_args(args, namespace)
1708+
namespace, args = self._parse_known_args(args, namespace)
1709+
if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
1710+
args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
1711+
delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
1712+
return namespace, args
17031713
except ArgumentError:
17041714
err = _sys.exc_info()[1]
17051715
self.error(str(err))

Lib/test/test_argparse.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,28 @@ def test_parse_args(self):
17731773
NS(foo=True, bar=0.125, w=None, x='c'),
17741774
)
17751775

1776+
def test_parse_known_args(self):
1777+
self.assertEqual(
1778+
self.parser.parse_known_args('0.5 1 b -w 7'.split()),
1779+
(NS(foo=False, bar=0.5, w=7, x='b'), []),
1780+
)
1781+
self.assertEqual(
1782+
self.parser.parse_known_args('0.5 -p 1 b -w 7'.split()),
1783+
(NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
1784+
)
1785+
self.assertEqual(
1786+
self.parser.parse_known_args('0.5 1 b -w 7 -p'.split()),
1787+
(NS(foo=False, bar=0.5, w=7, x='b'), ['-p']),
1788+
)
1789+
self.assertEqual(
1790+
self.parser.parse_known_args('0.5 1 b -q -rs -w 7'.split()),
1791+
(NS(foo=False, bar=0.5, w=7, x='b'), ['-q', '-rs']),
1792+
)
1793+
self.assertEqual(
1794+
self.parser.parse_known_args('0.5 -W 1 b -X Y -w 7 Z'.split()),
1795+
(NS(foo=False, bar=0.5, w=7, x='b'), ['-W', '-X', 'Y', 'Z']),
1796+
)
1797+
17761798
def test_dest(self):
17771799
parser = ErrorRaisingArgumentParser()
17781800
parser.add_argument('--foo', action='store_true')

0 commit comments

Comments
 (0)