-
-
Notifications
You must be signed in to change notification settings - Fork 32k
bpo-29298: Fix crash with required subparsers without dest #3680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d8bb0bd
fd1a8c0
6a09976
36e8f80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2060,6 +2060,30 @@ def test_required_subparsers_default(self): | |
ret = parser.parse_args(()) | ||
self.assertIsNone(ret.command) | ||
|
||
def test_required_subparsers_no_destination_error(self): | ||
parser = ErrorRaisingArgumentParser() | ||
subparsers = parser.add_subparsers(required=True) | ||
subparsers.add_parser('foo') | ||
subparsers.add_parser('bar') | ||
with self.assertRaises(ArgumentParserError) as excinfo: | ||
parser.parse_args(()) | ||
self.assertRegex( | ||
excinfo.exception.stderr, | ||
'error: the following arguments are required: {foo,bar}\n$' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a space after comma. Why braces are used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is a notation for alternatives: it means one of foo or bar is required. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is consistent with the rendering of import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', choices=('baz', 'womp'))
parser.parse_args()
|
||
) | ||
|
||
def test_wrong_argument_subparsers_no_destination_error(self): | ||
parser = ErrorRaisingArgumentParser() | ||
subparsers = parser.add_subparsers(required=True) | ||
subparsers.add_parser('foo') | ||
subparsers.add_parser('bar') | ||
with self.assertRaises(ArgumentParserError) as excinfo: | ||
parser.parse_args(('baz',)) | ||
self.assertRegex( | ||
excinfo.exception.stderr, | ||
r"error: argument {foo,bar}: invalid choice: 'baz' \(choose from 'foo', 'bar'\)\n$" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "foo, bar" is duplicated. And this error message looks confusing to me. What it means? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah I didn't really know what to do for this, it's essentially an anonymous positional choices argument. Personally I'd love a default Then this would read something like |
||
) | ||
|
||
def test_optional_subparsers(self): | ||
parser = ErrorRaisingArgumentParser() | ||
subparsers = parser.add_subparsers(dest='command', required=False) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Fix ``TypeError`` when required subparsers without ``dest`` do not receive | ||
arguments. Patch by Anthony Sottile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test doesn’t really help me understand what this change does (i.e. what a human would see in an error case).
I’m also not sure if some of the changes in the various patches for bpo-9253 (especially in tests) could be useful here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check those out. I had a difficult time demonstrating (by assertion) the actual output (didn't find any examples) -- I'll bang against that and hopefully I'll make something more expressive :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@merwok looks like they had the same idea I had (but a different implementation) -- I took inspiration from one of their tests for additional coverage and updated the tests to hopefully be more expressive (and have a better failure mode)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code for this is already in
_metavar_formatter
:The metavar formatter can be called, if the parser is known (as
self
), using:Perhaps
_get_action_name
should be made into a method, or take the parser as an optional argument?