bpo-29298: Fix crash with required subparsers without dest (GH-3680) … · python/cpython@c589992 (original) (raw)

3 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -727,6 +727,8 @@ def _get_action_name(argument):
727 727 return argument.metavar
728 728 elif argument.dest not in (None, SUPPRESS):
729 729 return argument.dest
730 +elif argument.choices:
731 +return '{' + ','.join(argument.choices) + '}'
730 732 else:
731 733 return None
732 734
Original file line number Diff line number Diff line change
@@ -2060,6 +2060,30 @@ def test_required_subparsers_default(self):
2060 2060 ret = parser.parse_args(())
2061 2061 self.assertIsNone(ret.command)
2062 2062
2063 +def test_required_subparsers_no_destination_error(self):
2064 +parser = ErrorRaisingArgumentParser()
2065 +subparsers = parser.add_subparsers(required=True)
2066 +subparsers.add_parser('foo')
2067 +subparsers.add_parser('bar')
2068 +with self.assertRaises(ArgumentParserError) as excinfo:
2069 +parser.parse_args(())
2070 +self.assertRegex(
2071 +excinfo.exception.stderr,
2072 +'error: the following arguments are required: {foo,bar}\n$'
2073 + )
2074 +
2075 +def test_wrong_argument_subparsers_no_destination_error(self):
2076 +parser = ErrorRaisingArgumentParser()
2077 +subparsers = parser.add_subparsers(required=True)
2078 +subparsers.add_parser('foo')
2079 +subparsers.add_parser('bar')
2080 +with self.assertRaises(ArgumentParserError) as excinfo:
2081 +parser.parse_args(('baz',))
2082 +self.assertRegex(
2083 +excinfo.exception.stderr,
2084 +r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 'foo', 'bar'\)\n$"
2085 + )
2086 +
2063 2087 def test_optional_subparsers(self):
2064 2088 parser = ErrorRaisingArgumentParser()
2065 2089 subparsers = parser.add_subparsers(dest='command', required=False)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1 +Fix ``TypeError`` when required subparsers without ``dest`` do not receive
2 +arguments. Patch by Anthony Sottile.