kopia lustrzana https://github.com/micropython/micropython-lib
argparse: Implement parse_known_args
This is convenient when components need only to parse a subset of an application's arguments, and can be implemented with minor changes to _parse_args: basically just add unknown arguments to a list instead of raising an exception.pull/261/head
rodzic
4c6e7f7107
commit
08b522abac
|
@ -144,18 +144,24 @@ class ArgumentParser:
|
||||||
print(" %-16s%s" % (', '.join(opt.names) + render_arg(opt), opt.help))
|
print(" %-16s%s" % (', '.join(opt.names) + render_arg(opt), opt.help))
|
||||||
|
|
||||||
def parse_args(self, args=None):
|
def parse_args(self, args=None):
|
||||||
|
return self._parse_args_impl(args, False)
|
||||||
|
|
||||||
|
def parse_known_args(self, args=None):
|
||||||
|
return self._parse_args_impl(args, True)
|
||||||
|
|
||||||
|
def _parse_args_impl(self, args, return_unknown):
|
||||||
if args is None:
|
if args is None:
|
||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
else:
|
else:
|
||||||
args = args[:]
|
args = args[:]
|
||||||
try:
|
try:
|
||||||
return self._parse_args(args)
|
return self._parse_args(args, return_unknown)
|
||||||
except _ArgError as e:
|
except _ArgError as e:
|
||||||
self.usage(False)
|
self.usage(False)
|
||||||
print("error:", e)
|
print("error:", e)
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
def _parse_args(self, args):
|
def _parse_args(self, args, return_unknown):
|
||||||
# add optional args with defaults
|
# add optional args with defaults
|
||||||
arg_dest = []
|
arg_dest = []
|
||||||
arg_vals = []
|
arg_vals = []
|
||||||
|
@ -163,6 +169,12 @@ class ArgumentParser:
|
||||||
arg_dest.append(opt.dest)
|
arg_dest.append(opt.dest)
|
||||||
arg_vals.append(opt.default)
|
arg_vals.append(opt.default)
|
||||||
|
|
||||||
|
# deal with unknown arguments, if needed
|
||||||
|
unknown = []
|
||||||
|
def consume_unknown():
|
||||||
|
while args and not args[0].startswith("-"):
|
||||||
|
unknown.append(args.pop(0))
|
||||||
|
|
||||||
# parse all args
|
# parse all args
|
||||||
parsed_pos = False
|
parsed_pos = False
|
||||||
while args or not parsed_pos:
|
while args or not parsed_pos:
|
||||||
|
@ -179,15 +191,26 @@ class ArgumentParser:
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
if not found:
|
if not found:
|
||||||
|
if return_unknown:
|
||||||
|
unknown.append(a)
|
||||||
|
consume_unknown()
|
||||||
|
else:
|
||||||
raise _ArgError("unknown option %s" % a)
|
raise _ArgError("unknown option %s" % a)
|
||||||
else:
|
else:
|
||||||
# positional arg
|
# positional arg
|
||||||
if parsed_pos:
|
if parsed_pos:
|
||||||
|
if return_unknown:
|
||||||
|
unknown = unknown + args
|
||||||
|
break
|
||||||
|
else:
|
||||||
raise _ArgError("extra args: %s" % " ".join(args))
|
raise _ArgError("extra args: %s" % " ".join(args))
|
||||||
for pos in self.pos:
|
for pos in self.pos:
|
||||||
arg_dest.append(pos.dest)
|
arg_dest.append(pos.dest)
|
||||||
arg_vals.append(pos.parse(pos.names[0], args))
|
arg_vals.append(pos.parse(pos.names[0], args))
|
||||||
parsed_pos = True
|
parsed_pos = True
|
||||||
|
if return_unknown:
|
||||||
|
consume_unknown()
|
||||||
|
|
||||||
# build and return named tuple with arg values
|
# build and return named tuple with arg values
|
||||||
return namedtuple("args", arg_dest)(*arg_vals)
|
values = namedtuple("args", arg_dest)(*arg_vals)
|
||||||
|
return (values, unknown) if return_unknown else values
|
||||||
|
|
|
@ -44,3 +44,25 @@ args = parser.parse_args(["a", "b"])
|
||||||
assert args.files1 == ["a", "b"] and args.files2 == []
|
assert args.files1 == ["a", "b"] and args.files2 == []
|
||||||
args = parser.parse_args(["a", "b", "c"])
|
args = parser.parse_args(["a", "b", "c"])
|
||||||
assert args.files1 == ["a", "b"] and args.files2 == ["c"]
|
assert args.files1 == ["a", "b"] and args.files2 == ["c"]
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("a", nargs=2)
|
||||||
|
parser.add_argument("-b")
|
||||||
|
args, rest = parser.parse_known_args(["a", "b", "-b", "2"])
|
||||||
|
assert args.a == ["a", "b"] and args.b == "2"
|
||||||
|
assert rest == []
|
||||||
|
args, rest = parser.parse_known_args(["-b", "2", "a", "b", "c"])
|
||||||
|
assert args.a == ["a", "b"] and args.b == "2"
|
||||||
|
assert rest == ["c"]
|
||||||
|
args, rest = parser.parse_known_args(["a", "b", "-b", "2", "c"])
|
||||||
|
assert args.a == ["a", "b"] and args.b == "2"
|
||||||
|
assert rest == ["c"]
|
||||||
|
args, rest = parser.parse_known_args(["-b", "2", "a", "b", "-", "c"])
|
||||||
|
assert args.a == ["a", "b"] and args.b == "2"
|
||||||
|
assert rest == ["-", "c"]
|
||||||
|
args, rest = parser.parse_known_args(["a", "b", "-b", "2", "-", "x", "y"])
|
||||||
|
assert args.a == ["a", "b"] and args.b == "2"
|
||||||
|
assert rest == ["-", "x", "y"]
|
||||||
|
args, rest = parser.parse_known_args(["a", "b", "c", "-b", "2", "--x", "5", "1"])
|
||||||
|
assert args.a == ["a", "b"] and args.b == "2"
|
||||||
|
assert rest == ["c", "--x", "5", "1"]
|
||||||
|
|
Ładowanie…
Reference in New Issue