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
Add disable_interspersed_args() to argparse.ArgumentParser #58174
Comments
If someone ports his code from optparse to argparse, there is a limit, that options and non-options can be mixed by default, and this behaviour cannot be disabled easily, an extra '--' argument is required in the command line. In some cases it is much prettier to explicitly disable this, as was available in the deprecated optparse module. I attach a patch that does this, adds disable_interspersed_args() to argparse.ArgumentParser. |
nice, thank you! |
The idea and patch seem okay to me. Needs tests though. |
I added unit test, which revealed some bugs. These are fixe now. |
The argparse changes and tests look good. The new method needs to be documented. You can see some other things (e.g. Misc/NEWS) that also need to be updated by running "make patchcheck" as described here: |
Unfortunatelly the implementation bugous as of now. I wrote additional tests. self.parser = ErrorRaisingArgumentParser()
self.parser.add_argument('-a', action='store_true')
self.parser.add_argument('-b')
self.parser.add_argument('rem', nargs=argparse.REMAINDER)
self.assertEquals(self.parser.parse_args('-b 4 -a -b 5'.split()), NS(a=True, b='5', rem=[])) This part is OK. But with the new option: This assertation also passes because it contains the actual result, which is unexpected. This is because the code doesn't handle properly the arguments that are non-options, such as '-b' in this case. I can't see a good solution for this. |
The optparse page gives a reason for disable_interspersed_args(): "Use this if you have a command processor which runs another command which has options of its own and you want to make sure these options don’t get confused. For example, each command might have a different set of options." In argparse: If you have only one positional argument, and its nargs is REMAINDER, you have effectively disabled interspersed. Argparse doesn't prohibit all interspersed positionals. You could, for example, have one or more positionals with other nargs that could be interspersed. But the REMAINDER one has to be last. In the library, profile.py uses 'optparse.disable_interspersed'. I just replaced optparse with argparse using the REMAINDER, and got the same behavior. (Actually I used argparse.PARSER which effectively requires at least one argument.) |
Oops, I was wrong about this: parser.add_argument('a')
parser.add_argument('--foo')
parser.add_argument('rest', nargs='...')
parser.parse_args('a --foo b c'.split(' ') produces: Namespace(a='a', foo=None, rest=['--foo', 'b', 'c']) That is because, 'rest' matches an empty list of arguments. With an nargs='*' or '?', the same thing happens, both 'a' and 'rest' are used up when processing the first positional argument string. nargs=argparse.PARSER (= 'A...') gives the expected
Namespace(a='a', foo='b', rest=['c']) In this case, 'rest' has to wait till the second set of positionals. Documentation warns "Note that it generally doesn’t make much sense to have more than one positional argument with nargs='*'". Maybe it should warn against combining any of the 'zero or more' positionals with other positionals. |
Looking further at test_argparse.py, I should say that the behavior of multiple positionals when there is one cluster of positional argstrings is well illustrated in the tests. It's the behavior when there are multiple clusters (interspersed positionals) that can go against some intuitions. |
http://bugs.python.org/issue14191 It does that with a new 'ArgumentParser.parse_intermixed_args()' method. |
It seems I found the solution in the attached file argparse.disable_interspersed_args.python35.diff, and it's much-much easier than I thought. I assume that this patch can cleanly applied to earlier versions (python 3.2-3.4), but I didn't check it. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: