On Tue, 26 Nov 2013 09:30:10 -0800, Eli Bendersky <eliben@gmail.com> wrote:
Hello,
argparse does prefix matching as long as there are no conflicts. For example:
argparser = argparse.ArgumentParser() argparser.add_argument('--sync-foo', action='store_true') args = argparser.parse_args()
If I pass "--sync" to this script, it recognizes it as "--sync-foo". This behavior is quite surprising although I can see the motivation for it. At the very least it should be much more explicitly documented (AFAICS it's barely mentioned in the docs).
If there's another argument registered, say "--sync-bar" the above will fail due to a conflict.
Now comes the nasty part. When using "parse_known_args" instead of "parse_args", the above happens too - --sync is recognized for --sync-foo and captured by the parser. But this is wrong! The whole idea of parse_known_args is to parse the known args, leaving unknowns alone. This prefix matching harms more than it helps here because maybe the program we're actually acting as a front-end for (and hence using parse_known_args) knows about --sync and wants to get it.
Unless I'm missing something, this is a bug. But I'm also not sure whether we can do anything about it at this point, as existing code *may* be relying on it. The right thing to do would be to disable this prefix matching when parse_known_args is called.
Again, at the very least this should be documented (for parse_known_args not less than a warning box, IMHO).
I'm not sure whether or not it is a bug, but there are a number of bugs involving argument prefix matching in the tracker. Including one to be able to disable it, that has a patch but didn't get into 3.4 (issue 14910). This topic seems more suited to the bug tracker than python-dev. Stephen hasn't been very active lately. There is at least one non-committer who has been, but no committers have made time to review the patches and take action (they are on my list, but there is a lot of stuff ahead of them). So if you'd like to help out in that regard, that would be great :) --David