from argparse import * import re as _re from gettext import gettext as _, ngettext import sys as _sys # class ArgumentParser(_AttributeHolder, _ActionsContainer): class ArgumentParserOpt(ArgumentParser): def _match_argument(self, action, arg_strings_pattern): # match the pattern for this action to the arg strings nargs_pattern = self._get_nargs_pattern(action) match = _re.match(nargs_pattern, arg_strings_pattern) # if no match, see if we can emulate optparse and return the # required number of arguments regardless of their values # if match is None: import numbers nargs = action.nargs if action.nargs is not None else 1 if isinstance(nargs, numbers.Number) and len(arg_strings_pattern) >= nargs: return nargs # raise an exception if we weren't able to find a match if match is None: nargs_errors = { None: _('expected one argument'), OPTIONAL: _('expected at most one argument'), ONE_OR_MORE: _('expected at least one argument'), } default = ngettext('expected %s argument', 'expected %s arguments', action.nargs) % action.nargs msg = nargs_errors.get(action.nargs, default) raise ArgumentError(action, msg) # return the number of arguments matched return len(match.group(1)) def test(argv): try: args = parser.parse_args(argv) print(args) print() except SystemExit: print() if __name__ == '__main__': if True: ParserClass = ArgumentParserOpt else: ParserClass = ArgumentParser # https://bugs.python.org/issue9334 example parser = ParserClass(prog='a2x') parser.set_defaults(prog=parser.prog) parser.add_argument('--asciidoc-opts', action='store', dest='asciidoc_opts', default='', metavar='ASCIIDOC_OPTS', help='asciidoc options') parser.add_argument('--safe', action='store_true') test(['--asciidoc-opts', '--safe']) test(['--asciidoc-opts', '--safe', '--safe']) test(['--asciidoc-opts', '-1']) # works in default test(['--asciidoc-opts', '-one']) test(['--asciidoc-opts=-one']) # works in default test(['--safe', '--asciidoc-opts']) # should return error, but doesnt parser = ParserClass(prog='nargs2') parser.set_defaults(prog=parser.prog) parser.add_argument('-a', nargs=2) test(['-a', '-first', '-second']) test(['-a', '-first']) parser = ParserClass(prog='karzes') parser.set_defaults(prog=parser.prog) parser.add_argument('--myopt') test(['--myopt', '-1,2'])