diff options
-rw-r--r-- | .gitignore | 5 | ||||
-rw-r--r-- | LICENSE | 15 | ||||
-rw-r--r-- | Makefile | 26 | ||||
-rw-r--r-- | README | 42 | ||||
-rw-r--r-- | arg.py | 307 | ||||
-rwxr-xr-x | test.py | 536 |
6 files changed, 931 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8a0b878 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*~ +*\#* +__pycache__/ +*.pyc +*.pyo @@ -0,0 +1,15 @@ +ISC License + +© 2017 Mattias Andrée <maandree@kth.se> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..50ede37 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +.POSIX: + +PREFIX = /usr/local + +PYTHON_MAJOR = $$(python --version 2>&1 | cut -d . -f 1 | cut -d ' ' -f 2) +PYTHON_MINOR = $$(python$(PYTHON_MAJOR) --version 2>&1 | cut -d . -f 2) + +all: + @true + +check: + python$(PYTHON_MAJOR) ./test.py + +install: + mkdir -p -- "$(DESTDIR)$(PREFIX)/lib/python$(PYTHON_MAJOR).$(PYTHON_MINOR)/site-packages" + cp -- arg.py "$(DESTDIR)$(PREFIX)/lib/python$(PYTHON_MAJOR).$(PYTHON_MINOR)/site-packages/" + +uninstall: + -rm -f -- "$(DESTDIR)$(PREFIX)/lib/python$(PYTHON_MAJOR).$(PYTHON_MINOR)/site-packages/arg.py" + +clean: + -rm -rf -- *.pyc *.pyo __pycache__ + +.SUFFIXES: + +.PHONY: all check install uninstall clean @@ -0,0 +1,42 @@ +A simple argument parser for Python + +Example usage: + import sys + import arg + + def usage(): + print('usage: %s [-v value] [-xy]' % sys.argv[0], file = sys.stderr) + sys.exit(1) + + xflag = False + yflag = False + vflag = None + + parser = arg.Parser(usage = usage) + for c in parser.flags: + if c == 'x': + xflag = True + elif c == 'y': + yflag = True + elif c == 'v': + vflag = parser.arg + else: + usage() + +Supports: + Short flags without arguments + Short flags with optionally attached arguments + Joined short flags + Long flags with optional arguments + Long flags with mandatory arguments + Long flags with mandatory attached arguments + Long flags with mandatory detached arguments + Long flags with without arguments + Long flags with only one dash + Flags not starting with a dash + Numeral flags + Stop parsing flags at -- + Mixing flags and arguments + Stop parsing flags at first argument + Returning -- as an argument + Not returning -- as an argument @@ -0,0 +1,307 @@ +# See LICENSE file for copyright and license details. +# -*- coding: utf-8 -*- + +from __future__ import print_function +import sys as _sys +import os as _os +import errno as _errno + +MAY_HAVE_ATTACHED_ARGUMENT = 0 +NEED_ARGUMENT = 1 +NEED_ATTACHED_ARGUMENT = 2 +NEED_DETACHED_ARGUMENT = 3 +NEED_NO_ARGUMENT = 4 + +class UsageError(Exception): + pass + +class Parser(object): + ''' + Command line parser + + Example usage: + import sys + import arg + + def usage(): + print('usage: %s [-v value] [-xy]' % sys.argv[0], file = sys.stderr) + sys.exit(1) + + xflag = False + yflag = False + vflag = None + + parser = arg.Parser(usage = usage) + for c in parser.flags: + if c == 'x': + xflag = True + elif c == 'y': + yflag = True + elif c == 'v': + vflag = parser.arg + else: + usage() + ''' + + def __init__(self, argv = None, symbols = '-', keep_dashdash = False, store_nonflags = False, usage = None): + ''' + @param argv A list with the arguments to parse, if `None`, `sys.argv[1:]` is used + @param symbols A string or list contain the characters that will cause an argument + to be parsed as being a flag, multicharacter strings will be ignored + @param keep_dashdash If `True`, `--` will be returned in `self.argv` + @param keep_nonflags During parsing, non-flag arguments are ignored, and after the last + flag has been parsed, `self.argv` will have the ignored arguments at + the beginning + @param usage Function (without arguments) that is to be called if parsing fails + due to usage error, if `None`, `UsageError` will be raised instead + on usage error + ''' + if argv is None: + argv = _sys.argv[1:] + self._argv = list(argv) + self._usage_func = usage + self._symbols = symbols + self._keep_ddash = keep_dashdash + self._stored = [] if store_nonflags else None + + def _usage(self): + if self._usage_func is None: + raise UsageError() + else: + self._usage_func() + + @property + def flags(self): + ''' + Return a generator that returns the flags in the command line + + Properties and functions in `self` can be used to after each + time a flag is returned + + Each returned value is a single character + ''' + self._brk = False + self._accept_none_arg = False + while len(self._argv): + if len(self._argv[0]) < 2: + if self._stored is not None: + self._stored.append(self._argv[0]) + self._argv = self._argv[1:] + continue + break + self._symbol = self._argv[0][0] + self._lflag = self._argv[0] + if self._symbol not in self._symbols: + if self._stored is not None: + self._stored.append(self._argv[0]) + self._argv = self._argv[1:] + continue + break + if self._argv[0] == 2 * self._symbol: + if self._symbol == '-': + if not self._keep_ddash: + self._argv = self._argv[1:] + elif self._stored is not None: + self._stored.append(self._argv[0]) + self._argv = self._argv[1:] + continue + break + self._i = 1 + n = len(self._argv[0]) + while self._i < n: + self._flag = self._argv[0][self._i] + if self._flag == self._symbol and self._i != 1: + self._usage() + if self._i + 1 < n: + self._arg = self._argv[0][self._i + 1:] + elif len(self._argv) > 1: + self._arg = self._argv[1] + else: + self._arg = None + yield self._flag + self._lflag = None + self._accept_none_arg = False + if self._brk: + if len(self._argv) > 1 and self._arg is self._argv[1]: + self._argv = self._argv[1:] + self._brk = False + break + self._i += 1 + self._argv = self._argv[1:] + if self._stored: + self._argv = self._stored + self._argv + self._stored = None + + @property + def flag(self): + ''' + Return the current short flag, for example '-a', + this string is always two characters long + ''' + return self._symbol + self._flag + + @property + def symbol(self): + ''' + Get the first character in the flag, normally '-' + ''' + return self._symbol + + @property + def lflag(self): + ''' + Get the entire current argument, for example + '--mode=755', `None` not at the beginning + ''' + return self._lflag + + @property + def argv(self): + ''' + Return a list of all remaining arguments + ''' + return self._argv + + @property + def argc(self): + ''' + Return the number of remaining arguments + ''' + return len(self._argv) + + @property + def arg(self): + ''' + Get the argument specified for the flag, can only be + `None` (no argument) if `self.testlong` has returned + `True` with `MAY_HAVE_ATTACHED_ARGUMENT` as the second + argument for the currnet flag + + Reading this property will cause the parser to assume + that the flag should have an argument, if these is + no argument UsageError will be raised (or the specified + usage function will be called) unless `self.testlong` + has returned `True` with `MAY_HAVE_ATTACHED_ARGUMENT` + as the second argument for the currnet flag + ''' + if self._arg is None and not self._accept_none_arg: + self._usage() + self._brk = True + return self._arg + + @property + def arghere(self): + ''' + Return the current argument with an offset such that the + first character is the character associated with the + current flag, for example, if the current argument is + '-123' and the current flag is '1', '123' is returned + + Reading this property will cause the parser to continue + with the next argument when getting the next flag + ''' + self._brk = True + self._arg = None + return self._argv[0][self._i:] + + @property + def isargnum(self): + ''' + Check whether the value returned by `arghere` will be a number + + Calling this function does not affect the parser + ''' + return self._argv[0][self._i:].isdigit() + + @property + def argnum(self): + ''' + Identical to `arghere`, except the returned value will + be converted to an integer + + If the value returned by `self.arghere` is not a + number, UsageError will be raised (or the specified + usage function will be called) + ''' + if not self.isargnum: + self._usage() + return int(self.arghere) + + def consume(self): + ''' + Cause the parser to skip the rest of current argument + and continue with the next argument + + If `self.arg` has been read and returned the next argument, + the parser will still read that argument + ''' + self._arg = None + self._brk = True + + def testlong(self, flag, argument = 0): + ''' + Check whether the current flag is specific long flag + + It is important to use this function, because it will + set the parser's state appropriately whe it finds a match + + If the flag is the specified long flag, but its argument + status does not match `argument`, UsageError will be raised + (or the specified usage function will be called) + + @param flag The long flag, should start with its symbol prefix (usually '--') + @param argument arg.MAY_HAVE_ATTACHED_ARGUMENT (default): + The flag may have an argument attached to the flag + separated by a '=', for example '--value=2', but + it is not necessary, so just '--value' is also accepted, + but the next argument may not be parsed as a value + associated with the flag + arg.NEED_ARGUMENT: + The flag must have an attached argument or a detached + argument, for example '--value=2' is accepted, but + '--value' is only accepted if it is not the last argument, + if the current argument does not contain a '=' + arg.NEED_ATTACHED_ARGUMENT: + The flag must have an attached argument, for example + '--value=2' is accepted but '--value' is not + arg.NEED_DETACHED_ARGUMENT: + The flag must have a detached argument, for example + '--value' is accepted, but only if it is not the last + argument, but '--value=2' is not accepted + arg.NEED_NO_ARGUMENT: + The flag must not have an argument, for example + '--value' is accepted but '--value=2' is not + ''' + if self._lflag is None: + return False + attached = self._lflag.startswith(flag + '=') + if attached: + arg = self._lflag[self._lflag.index('=') + 1:] + lflag = self._lflag[:self._lflag.index('=')] + else: + arg = self._argv[1] if len(self._argv) > 1 else None + lflag = self._lflag + if lflag != flag: + return False + elif argument == MAY_HAVE_ATTACHED_ARGUMENT: + if not attached: + arg = None + self._accept_none_arg = True + elif argument == NEED_ARGUMENT: + if arg is None: + self._usage() + elif argument == NEED_ATTACHED_ARGUMENT: + if not attached: + self._usage() + elif argument == NEED_DETACHED_ARGUMENT: + if attached or arg is None: + self._usage() + elif argument == NEED_NO_ARGUMENT: + arg = None + if attached: + self._usage() + else: + raise OSError(_os.strerror(_errno.EINVAL), _errno.EINVAL) + self._arg = arg + self._brk = True + return True @@ -0,0 +1,536 @@ +#!/usr/bin/env python +# See LICENSE file for copyright and license details. +# -*- coding: utf-8 -*- + +import sys +import arg + + +parser = arg.Parser() +assert parser.argv == sys.argv[1:] + + +parser = arg.Parser(argv = ['-a', '-aa', '-aaa']) +n = 0 +for c in parser.flags: + assert c == 'a' + n += 1 +assert n == 6 +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +parser = arg.Parser(argv = ['-abc', '-xyz']) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +assert parser.symbol == '-' +assert next(flags) == 'b' +assert parser.flag == '-b' +assert next(flags) == 'c' +assert parser.flag == '-c' +assert next(flags) == 'x' +assert parser.flag == '-x' +assert parser.lflag == '-xyz' +assert next(flags) == 'y' +assert parser.flag == '-y' +assert parser.lflag is None +assert next(flags) == 'z' +assert parser.flag == '-z' +assert parser.symbol == '-' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +for mid in ('', '-', 'x'): + parser = arg.Parser(argv = ['-abc', mid, '-xyz']) + flags = parser.flags + assert next(flags) == 'a' + assert parser.flag == '-a' + assert parser.symbol == '-' + assert next(flags) == 'b' + assert parser.flag == '-b' + assert next(flags) == 'c' + assert parser.flag == '-c' + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 2 + assert type(parser.argc) is int + assert parser.argc == 2 + assert parser.argv == [mid, '-xyz'] + + +parser = arg.Parser(argv = ['-abc', '--', '-xyz']) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +assert parser.symbol == '-' +assert next(flags) == 'b' +assert parser.flag == '-b' +assert next(flags) == 'c' +assert parser.flag == '-c' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 1 +assert type(parser.argc) is int +assert parser.argc == 1 +assert parser.argv == ['-xyz'] + + +parser = arg.Parser(argv = ['-abc', '--', '-xyz'], keep_dashdash = True) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +assert parser.symbol == '-' +assert next(flags) == 'b' +assert parser.flag == '-b' +assert next(flags) == 'c' +assert parser.flag == '-c' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 2 +assert type(parser.argc) is int +assert parser.argc == 2 +assert parser.argv == ['--', '-xyz'] + + +parser = arg.Parser(argv = ['a', '--', 'b'], keep_dashdash = True, store_nonflags = True) +flags = parser.flags +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 3 +assert type(parser.argc) is int +assert parser.argc == 3 +assert parser.argv == ['a', '--', 'b'] + + +parser = arg.Parser(argv = ['a', '--', 'b'], keep_dashdash = False, store_nonflags = True) +flags = parser.flags +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 2 +assert type(parser.argc) is int +assert parser.argc == 2 +assert parser.argv == ['a', 'b'] + + +parser = arg.Parser(argv = ['-a-b']) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +try: + next(flags) + assert False +except arg.UsageError: + pass + + +parser = arg.Parser(argv = ['-123', '-xyz']) +flags = parser.flags +assert next(flags) == '1' +assert parser.flag == '-1' +assert next(flags) == '2' +assert parser.flag == '-2' +assert next(flags) == '3' +assert parser.flag == '-3' +assert next(flags) == 'x' +assert parser.flag == '-x' +assert next(flags) == 'y' +assert parser.flag == '-y' +assert next(flags) == 'z' +assert parser.flag == '-z' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +parser = arg.Parser(argv = ['-123', '-xyz']) +flags = parser.flags +assert next(flags) == '1' +assert parser.flag == '-1' +assert parser.arghere == '123' +assert parser.isargnum +assert parser.argnum == 123 +assert next(flags) == 'x' +assert parser.flag == '-x' +assert next(flags) == 'y' +assert parser.flag == '-y' +assert next(flags) == 'z' +assert parser.flag == '-z' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +parser = arg.Parser(argv = ['-1', '-xyz']) +flags = parser.flags +assert next(flags) == '1' +assert parser.flag == '-1' +assert parser.arghere == '1' +assert parser.isargnum +assert parser.argnum == 1 +assert next(flags) == 'x' +assert parser.flag == '-x' +assert next(flags) == 'y' +assert parser.flag == '-y' +assert next(flags) == 'z' +assert parser.flag == '-z' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +parser = arg.Parser(argv = ['-ab', '--', '-xyz'], store_nonflags = True) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +assert next(flags) == 'b' +assert parser.flag == '-b' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 1 +assert type(parser.argc) is int +assert parser.argc == 1 +assert parser.argv == ['-xyz'] + + +parser = arg.Parser(argv = ['-ab', '--', '-xyz'], keep_dashdash = True, store_nonflags = True) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +assert next(flags) == 'b' +assert parser.flag == '-b' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 2 +assert type(parser.argc) is int +assert parser.argc == 2 +assert parser.argv == ['--', '-xyz'] + + +for mid in ('o', 'oo'): + parser = arg.Parser(argv = ['-ab', mid, '-xyz'], store_nonflags = True) + flags = parser.flags + assert next(flags) == 'a' + assert parser.flag == '-a' + assert next(flags) == 'b' + assert parser.flag == '-b' + assert next(flags) == 'x' + assert parser.flag == '-x' + assert next(flags) == 'y' + assert parser.flag == '-y' + assert next(flags) == 'z' + assert parser.flag == '-z' + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 1 + assert type(parser.argc) is int + assert parser.argc == 1 + assert parser.argv == [mid] + + +parser = arg.Parser(argv = ['-abc'], symbols = '+') +flags = parser.flags +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 1 +assert type(parser.argc) is int +assert parser.argc == 1 +assert parser.argv == ['-abc'] + + +parser = arg.Parser(argv = ['+xyz', '-abc'], symbols = '+') +flags = parser.flags +assert next(flags) == 'x' +assert parser.flag == '+x' +assert parser.symbol == '+' +assert next(flags) == 'y' +assert parser.flag == '+y' +assert next(flags) == 'z' +assert parser.flag == '+z' +assert parser.symbol == '+' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 1 +assert type(parser.argc) is int +assert parser.argc == 1 +assert parser.argv == ['-abc'] + + +parser = arg.Parser(argv = ['+xyz', '-abc'], symbols = '-+') +flags = parser.flags +assert next(flags) == 'x' +assert parser.flag == '+x' +assert parser.symbol == '+' +assert next(flags) == 'y' +assert parser.flag == '+y' +assert next(flags) == 'z' +assert parser.flag == '+z' +assert parser.symbol == '+' +assert next(flags) == 'a' +assert parser.flag == '-a' +assert parser.symbol == '-' +assert next(flags) == 'b' +assert parser.flag == '-b' +assert next(flags) == 'c' +assert parser.flag == '-c' +assert parser.symbol == '-' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +parser = arg.Parser(argv = ['+xyz', '++', '-abc'], symbols = '-+') +flags = parser.flags +assert next(flags) == 'x' +assert parser.flag == '+x' +assert parser.symbol == '+' +assert next(flags) == 'y' +assert parser.flag == '+y' +assert next(flags) == 'z' +assert parser.flag == '+z' +assert parser.symbol == '+' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 2 +assert type(parser.argc) is int +assert parser.argc == 2 +assert parser.argv == ['++', '-abc'] + + +parser = arg.Parser(argv = ['-123', '-xyz']) +flags = parser.flags +assert next(flags) == '1' +assert parser.arg == '23' +assert next(flags) == 'x' +assert parser.flag == '-x' +assert parser.arg == 'yz' +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +for a in ('', '-x'): + parser = arg.Parser(argv = ['-1', a]) + flags = parser.flags + assert next(flags) == '1' + assert parser.arg == a + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 0 + assert type(parser.argc) is int + assert parser.argc == 0 + + +parser = arg.Parser(argv = ['-123', '-xyz']) +flags = parser.flags +assert next(flags) == '1' +parser.consume() +assert next(flags) == 'x' +parser.consume() +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 0 +assert type(parser.argc) is int +assert parser.argc == 0 + + +parser = arg.Parser(argv = ['--123', 'x']) +flags = parser.flags +assert next(flags) == '-' +assert not parser.testlong('--abc') +assert parser.testlong('--123', arg.NEED_NO_ARGUMENT) +try: + next(flags) + assert False +except StopIteration: + pass +assert type(parser.argv) is list +assert len(parser.argv) == 1 +assert type(parser.argc) is int +assert parser.argc == 1 +assert parser.argv == ['x'] + + +for check_arg in (True, False): + for arg_need in (arg.NEED_ARGUMENT, arg.NEED_DETACHED_ARGUMENT): + parser = arg.Parser(argv = ['--123', 'x']) + flags = parser.flags + assert next(flags) == '-' + assert not parser.testlong('--abc') + assert parser.testlong('--123', arg_need) + if check_arg: + assert parser.arg == 'x' + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 0 + assert type(parser.argc) is int + assert parser.argc == 0 + + +for check_arg in (True, False): + parser = arg.Parser(argv = ['--123=x']) + flags = parser.flags + assert next(flags) == '-' + assert not parser.testlong('--abc') + assert parser.testlong('--123', arg.NEED_ATTACHED_ARGUMENT) + if check_arg: + assert parser.arg == 'x' + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 0 + assert type(parser.argc) is int + assert parser.argc == 0 + + +parser = arg.Parser(argv = ['--123', 'x']) +flags = parser.flags +assert next(flags) == '-' +assert not parser.testlong('--abc') +try: + parser.testlong('--123', arg.NEED_ATTACHED_ARGUMENT) + assert False +except arg.UsageError: + pass + + +for a in ('x', ''): + parser = arg.Parser(argv = ['--123=' + a]) + flags = parser.flags + assert next(flags) == '-' + assert not parser.testlong('--abc') + assert parser.testlong('--123', arg.MAY_HAVE_ATTACHED_ARGUMENT) + assert parser.arg == a + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 0 + assert type(parser.argc) is int + assert parser.argc == 0 + + parser = arg.Parser(argv = ['--123', a]) + flags = parser.flags + assert next(flags) == '-' + assert not parser.testlong('--abc') + assert parser.testlong('--123', arg.MAY_HAVE_ATTACHED_ARGUMENT) + assert parser.arg == None + try: + next(flags) + assert False + except StopIteration: + pass + assert type(parser.argv) is list + assert len(parser.argv) == 1 + assert type(parser.argc) is int + assert parser.argc == 1 + assert parser.argv == [a] + + +parser = arg.Parser(argv = ['-a-'], usage = lambda : sys.exit(0)) +flags = parser.flags +assert next(flags) == 'a' +assert parser.flag == '-a' +next(flags) +assert False |