summaryrefslogtreecommitdiffstats
path: root/scripts/lib/argparse_oe.py
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2015-12-22 17:03:08 +1300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-12-28 09:25:13 +0000
commit0d8751fbab820c4f157da941b03d29f17dd62b11 (patch)
treec9ce7df77d852ee4744506dd50f2cc83069fe83b /scripts/lib/argparse_oe.py
parent1bd779347b92245ff0ac8dac5ae14dac025452b1 (diff)
downloadpoky-0d8751fbab820c4f157da941b03d29f17dd62b11.tar.gz
scripts/lib/argparse_oe: handle intermixing of optional positional arguments
Python's argparse module can't handle when several optional positional arguments (set with nargs='?') are intermixed with other options. If the positional arguments aren't optional then this isn't an issue; thus when changing positional arguments to optional (as we are doing with devtool) we need this workaround. This is a pretty horrible hack, but we don't want this flexibility of ordering to disappear simply because we made some arguments optional. Unfortunately the corresponding bug remains unresolved upstream even in Python 3, and argparse is not really designed to be subclassed so it doesn't make things like this easy. (From OE-Core rev: 98fd5de373e16fe5d69a3065f844efc8037385bc) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/lib/argparse_oe.py')
-rw-r--r--scripts/lib/argparse_oe.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/scripts/lib/argparse_oe.py b/scripts/lib/argparse_oe.py
index c2fee6de05..ec7eb8d191 100644
--- a/scripts/lib/argparse_oe.py
+++ b/scripts/lib/argparse_oe.py
@@ -9,3 +9,42 @@ class ArgumentParser(argparse.ArgumentParser):
9 self.print_help() 9 self.print_help()
10 sys.exit(2) 10 sys.exit(2)
11 11
12 def add_subparsers(self, *args, **kwargs):
13 ret = super(ArgumentParser, self).add_subparsers(*args, **kwargs)
14 ret._parser_class = ArgumentSubParser
15 return ret
16
17class ArgumentSubParser(ArgumentParser):
18 def parse_known_args(self, args=None, namespace=None):
19 # This works around argparse not handling optional positional arguments being
20 # intermixed with other options. A pretty horrible hack, but we're not left
21 # with much choice given that the bug in argparse exists and it's difficult
22 # to subclass.
23 # Borrowed from http://stackoverflow.com/questions/20165843/argparse-how-to-handle-variable-number-of-arguments-nargs
24 # with an extra workaround (in format_help() below) for the positional
25 # arguments disappearing from the --help output, as well as structural tweaks.
26 # Originally simplified from http://bugs.python.org/file30204/test_intermixed.py
27 positionals = self._get_positional_actions()
28 for action in positionals:
29 # deactivate positionals
30 action.save_nargs = action.nargs
31 action.nargs = 0
32
33 namespace, remaining_args = super(ArgumentSubParser, self).parse_known_args(args, namespace)
34 for action in positionals:
35 # remove the empty positional values from namespace
36 if hasattr(namespace, action.dest):
37 delattr(namespace, action.dest)
38 for action in positionals:
39 action.nargs = action.save_nargs
40 # parse positionals
41 namespace, extras = super(ArgumentSubParser, self).parse_known_args(remaining_args, namespace)
42 return namespace, extras
43
44 def format_help(self):
45 # Quick, restore the positionals!
46 positionals = self._get_positional_actions()
47 for action in positionals:
48 if hasattr(action, 'save_nargs'):
49 action.nargs = action.save_nargs
50 return super(ArgumentParser, self).format_help()