vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / aria / utils / argparse.py
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements.  See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License.  You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """
17 Enhancements to Python's ``argparse`` module.
18 """
19
20 from __future__ import absolute_import  # so we can import standard 'argparse'
21
22 from argparse import ArgumentParser as BaseArgumentParser
23
24
25 class ArgumentParser(BaseArgumentParser):
26     """
27     Enhanced argument parser.
28
29     Applied patch to fix `this issue <https://bugs.python.org/issue22433>`__.
30     """
31
32     def add_flag_argument(self, name, help_true=None, help_false=None, default=False):
33         """
34         Adds a flag argument as two arguments: ``--my-flag`` and ``--no-my-flag``.
35         """
36
37         dest = name.replace('-', '_')
38
39         if default:
40             if help_true is not None:
41                 help_true += ' (default)'
42             else:
43                 help_true = '(default)'
44         else:
45             if help_false is not None:
46                 help_false += ' (default)'
47             else:
48                 help_false = '(default)'
49
50         group = self.add_mutually_exclusive_group()
51         group.add_argument('--%s' % name, action='store_true', help=help_true)
52         group.add_argument('--no-%s' % name, dest=dest, action='store_false', help=help_false)
53
54         self.set_defaults(**{dest: default})
55
56     def _parse_optional(self, arg_string):
57
58         if self._is_positional(arg_string):
59             return None
60
61         # if the option string is present in the parser, return the action
62         if arg_string in self._option_string_actions:
63             action = self._option_string_actions[arg_string]
64             return action, arg_string, None
65
66         # if the option string before the "=" is present, return the action
67         if '=' in arg_string:
68             option_string, explicit_arg = arg_string.split('=', 1)
69             if option_string in self._option_string_actions:
70                 action = self._option_string_actions[option_string]
71                 return action, option_string, explicit_arg
72
73         # search through all possible prefixes of the option string
74         # and all actions in the parser for possible interpretations
75         option_tuples = self._get_option_tuples(arg_string)
76
77         # if multiple actions match, the option string was ambiguous
78         if len(option_tuples) > 1:
79             options = ', '.join(
80                 [option_string for action, option_string, explicit_arg in option_tuples])
81             tup = arg_string, options
82             self.error('ambiguous option: %s could match %s' % tup)
83
84         # if exactly one action matched, this segmentation is good,
85         # so return the parsed action
86         elif len(option_tuples) == 1:
87             option_tuple = option_tuples
88             return option_tuple
89
90         # if it was not found as an option, but it looks like a negative
91         # number, it was meant to be positional
92         # unless there are negative-number-like options
93         if self._negative_number_matcher.match(arg_string):
94             if not self._has_negative_number_optionals:
95                 return None
96
97         # it was meant to be an optional but there is no such option
98         # in this parser (though it might be a valid option in a subparser)
99         return None, arg_string, None
100
101     def _is_positional(self, arg_string):
102         # if it's an empty string, it was meant to be a positional
103         if not arg_string:
104             return True
105
106         # if it doesn't start with a prefix, it was meant to be positional
107         if not arg_string[0] in self.prefix_chars:
108             return True
109
110         # if it's just a single character, it was meant to be positional
111         if len(arg_string) == 1:
112             return True
113
114         # if it contains a space, it was meant to be a positional
115         if ' ' in arg_string and arg_string[0] not in self.prefix_chars:
116             return True
117
118         return False