Show More
@@ -2,25 +2,17 b'' | |||
|
2 | 2 | |
|
3 | 3 | # Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>. |
|
4 | 4 | # |
|
5 | # Redistribution and use in source and binary forms, with or without | |
|
6 | # modification, are permitted provided that the following conditions are met: | |
|
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not | |
|
6 | # use this file except in compliance with the License. You may obtain a copy | |
|
7 | # of the License at | |
|
7 | 8 | # |
|
8 | # * Redistributions of source code must retain the above copyright notice, this | |
|
9 | # list of conditions and the following disclaimer. | |
|
10 | # * Redistributions in binary form must reproduce the above copyright notice, | |
|
11 | # this list of conditions and the following disclaimer in the documentation | |
|
12 | # and/or other materials provided with the distribution. | |
|
9 | # http://www.apache.org/licenses/LICENSE-2.0 | |
|
13 | 10 | # |
|
14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
|
15 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
|
16 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
|
17 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
|
18 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
|
19 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
|
20 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
|
21 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
|
22 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
|
23 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
|
11 | # Unless required by applicable law or agreed to in writing, software | |
|
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
|
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
|
14 | # License for the specific language governing permissions and limitations | |
|
15 | # under the License. | |
|
24 | 16 | |
|
25 | 17 | """Command-line parsing library |
|
26 | 18 | |
@@ -83,7 +75,7 b' considered public as object names -- the API of the formatter objects is' | |||
|
83 | 75 | still considered an implementation detail.) |
|
84 | 76 | """ |
|
85 | 77 | |
|
86 |
__version__ = '1. |
|
|
78 | __version__ = '1.1a1' | |
|
87 | 79 | __all__ = [ |
|
88 | 80 | 'ArgumentParser', |
|
89 | 81 | 'ArgumentError', |
@@ -92,7 +84,7 b' __all__ = [' | |||
|
92 | 84 | 'FileType', |
|
93 | 85 | 'HelpFormatter', |
|
94 | 86 | 'RawDescriptionHelpFormatter', |
|
95 | 'RawTextHelpFormatter' | |
|
87 | 'RawTextHelpFormatter', | |
|
96 | 88 | 'ArgumentDefaultsHelpFormatter', |
|
97 | 89 | ] |
|
98 | 90 | |
@@ -126,6 +118,10 b' except NameError:' | |||
|
126 | 118 | result.reverse() |
|
127 | 119 | return result |
|
128 | 120 | |
|
121 | ||
|
122 | def _callable(obj): | |
|
123 | return hasattr(obj, '__call__') or hasattr(obj, '__bases__') | |
|
124 | ||
|
129 | 125 | # silence Python 2.6 buggy warnings about Exception.message |
|
130 | 126 | if _sys.version_info[:2] == (2, 6): |
|
131 | 127 | import warnings |
@@ -141,7 +137,8 b" SUPPRESS = '==SUPPRESS=='" | |||
|
141 | 137 | OPTIONAL = '?' |
|
142 | 138 | ZERO_OR_MORE = '*' |
|
143 | 139 | ONE_OR_MORE = '+' |
|
144 |
PARSER = ' |
|
|
140 | PARSER = 'A...' | |
|
141 | REMAINDER = '...' | |
|
145 | 142 | |
|
146 | 143 | # ============================= |
|
147 | 144 | # Utility functions and classes |
@@ -508,6 +505,8 b' class HelpFormatter(object):' | |||
|
508 | 505 | return text |
|
509 | 506 | |
|
510 | 507 | def _format_text(self, text): |
|
508 | if '%(prog)' in text: | |
|
509 | text = text % dict(prog=self._prog) | |
|
511 | 510 | text_width = self._width - self._current_indent |
|
512 | 511 | indent = ' ' * self._current_indent |
|
513 | 512 | return self._fill_text(text, text_width, indent) + '\n\n' |
@@ -608,7 +607,9 b' class HelpFormatter(object):' | |||
|
608 | 607 | result = '[%s [%s ...]]' % get_metavar(2) |
|
609 | 608 | elif action.nargs == ONE_OR_MORE: |
|
610 | 609 | result = '%s [%s ...]' % get_metavar(2) |
|
611 |
elif action.nargs |
|
|
610 | elif action.nargs == REMAINDER: | |
|
611 | result = '...' | |
|
612 | elif action.nargs == PARSER: | |
|
612 | 613 | result = '%s ...' % get_metavar(1) |
|
613 | 614 | else: |
|
614 | 615 | formats = ['%s' for _ in range(action.nargs)] |
@@ -724,6 +725,12 b' class ArgumentError(Exception):' | |||
|
724 | 725 | return format % dict(message=self.message, |
|
725 | 726 | argument_name=self.argument_name) |
|
726 | 727 | |
|
728 | ||
|
729 | class ArgumentTypeError(Exception): | |
|
730 | """An error from trying to convert a command line string to a type.""" | |
|
731 | pass | |
|
732 | ||
|
733 | ||
|
727 | 734 | # ============== |
|
728 | 735 | # Action classes |
|
729 | 736 | # ============== |
@@ -1018,6 +1025,7 b' class _VersionAction(Action):' | |||
|
1018 | 1025 | |
|
1019 | 1026 | def __init__(self, |
|
1020 | 1027 | option_strings, |
|
1028 | version=None, | |
|
1021 | 1029 | dest=SUPPRESS, |
|
1022 | 1030 | default=SUPPRESS, |
|
1023 | 1031 | help=None): |
@@ -1027,10 +1035,15 b' class _VersionAction(Action):' | |||
|
1027 | 1035 | default=default, |
|
1028 | 1036 | nargs=0, |
|
1029 | 1037 | help=help) |
|
1038 | self.version = version | |
|
1030 | 1039 | |
|
1031 | 1040 | def __call__(self, parser, namespace, values, option_string=None): |
|
1032 | parser.print_version() | |
|
1033 | parser.exit() | |
|
1041 | version = self.version | |
|
1042 | if version is None: | |
|
1043 | version = parser.version | |
|
1044 | formatter = parser._get_formatter() | |
|
1045 | formatter.add_text(version) | |
|
1046 | parser.exit(message=formatter.format_help()) | |
|
1034 | 1047 | |
|
1035 | 1048 | |
|
1036 | 1049 | class _SubParsersAction(Action): |
@@ -1211,7 +1224,7 b' class _ActionsContainer(object):' | |||
|
1211 | 1224 | self._defaults = {} |
|
1212 | 1225 | |
|
1213 | 1226 | # determines whether an "option" looks like a negative number |
|
1214 | self._negative_number_matcher = _re.compile(r'^-\d+|-\d*.\d+$') | |
|
1227 | self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$') | |
|
1215 | 1228 | |
|
1216 | 1229 | # whether or not there are any optionals that look like negative |
|
1217 | 1230 | # numbers -- uses a list so it can be shared and edited |
@@ -1228,7 +1241,7 b' class _ActionsContainer(object):' | |||
|
1228 | 1241 | return self._registries[registry_name].get(value, default) |
|
1229 | 1242 | |
|
1230 | 1243 | # ================================== |
|
1231 |
# Namespace default |
|
|
1244 | # Namespace default accessor methods | |
|
1232 | 1245 | # ================================== |
|
1233 | 1246 | def set_defaults(self, **kwargs): |
|
1234 | 1247 | self._defaults.update(kwargs) |
@@ -1239,6 +1252,13 b' class _ActionsContainer(object):' | |||
|
1239 | 1252 | if action.dest in kwargs: |
|
1240 | 1253 | action.default = kwargs[action.dest] |
|
1241 | 1254 | |
|
1255 | def get_default(self, dest): | |
|
1256 | for action in self._actions: | |
|
1257 | if action.dest == dest and action.default is not None: | |
|
1258 | return action.default | |
|
1259 | return self._defaults.get(dest, None) | |
|
1260 | ||
|
1261 | ||
|
1242 | 1262 | # ======================= |
|
1243 | 1263 | # Adding argument actions |
|
1244 | 1264 | # ======================= |
@@ -1253,6 +1273,8 b' class _ActionsContainer(object):' | |||
|
1253 | 1273 | # argument |
|
1254 | 1274 | chars = self.prefix_chars |
|
1255 | 1275 | if not args or len(args) == 1 and args[0][0] not in chars: |
|
1276 | if args and 'dest' in kwargs: | |
|
1277 | raise ValueError('dest supplied twice for positional argument') | |
|
1256 | 1278 | kwargs = self._get_positional_kwargs(*args, **kwargs) |
|
1257 | 1279 | |
|
1258 | 1280 | # otherwise, we're adding an optional argument |
@@ -1269,6 +1291,8 b' class _ActionsContainer(object):' | |||
|
1269 | 1291 | |
|
1270 | 1292 | # create the action object, and add it to the parser |
|
1271 | 1293 | action_class = self._pop_action_class(kwargs) |
|
1294 | if not _callable(action_class): | |
|
1295 | raise ValueError('unknown action "%s"' % action_class) | |
|
1272 | 1296 | action = action_class(**kwargs) |
|
1273 | 1297 | return self._add_action(action) |
|
1274 | 1298 | |
@@ -1578,6 +1602,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
1578 | 1602 | if self.version: |
|
1579 | 1603 | self.add_argument( |
|
1580 | 1604 | '-v', '--version', action='version', default=SUPPRESS, |
|
1605 | version=self.version, | |
|
1581 | 1606 | help=_("show program's version number and exit")) |
|
1582 | 1607 | |
|
1583 | 1608 | # add parent arguments and defaults |
@@ -2011,6 +2036,13 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
2011 | 2036 | action = self._option_string_actions[arg_string] |
|
2012 | 2037 | return action, arg_string, None |
|
2013 | 2038 | |
|
2039 | # if the option string before the "=" is present, return the action | |
|
2040 | if '=' in arg_string: | |
|
2041 | option_string, explicit_arg = arg_string.split('=', 1) | |
|
2042 | if option_string in self._option_string_actions: | |
|
2043 | action = self._option_string_actions[option_string] | |
|
2044 | return action, option_string, explicit_arg | |
|
2045 | ||
|
2014 | 2046 | # search through all possible prefixes of the option string |
|
2015 | 2047 | # and all actions in the parser for possible interpretations |
|
2016 | 2048 | option_tuples = self._get_option_tuples(arg_string) |
@@ -2108,8 +2140,12 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
2108 | 2140 | elif nargs == ONE_OR_MORE: |
|
2109 | 2141 | nargs_pattern = '(-*A[A-]*)' |
|
2110 | 2142 | |
|
2143 | # allow any number of options or arguments | |
|
2144 | elif nargs == REMAINDER: | |
|
2145 | nargs_pattern = '([-AO]*)' | |
|
2146 | ||
|
2111 | 2147 | # allow one argument followed by any number of options or arguments |
|
2112 |
elif nargs |
|
|
2148 | elif nargs == PARSER: | |
|
2113 | 2149 | nargs_pattern = '(-*A[-AO]*)' |
|
2114 | 2150 | |
|
2115 | 2151 | # all others should be integers |
@@ -2129,7 +2165,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
2129 | 2165 | # ======================== |
|
2130 | 2166 | def _get_values(self, action, arg_strings): |
|
2131 | 2167 | # for everything but PARSER args, strip out '--' |
|
2132 |
if action.nargs |
|
|
2168 | if action.nargs not in [PARSER, REMAINDER]: | |
|
2133 | 2169 | arg_strings = [s for s in arg_strings if s != '--'] |
|
2134 | 2170 | |
|
2135 | 2171 | # optional argument produces a default when not present |
@@ -2158,8 +2194,12 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
2158 | 2194 | value = self._get_value(action, arg_string) |
|
2159 | 2195 | self._check_value(action, value) |
|
2160 | 2196 | |
|
2197 | # REMAINDER arguments convert all values, checking none | |
|
2198 | elif action.nargs == REMAINDER: | |
|
2199 | value = [self._get_value(action, v) for v in arg_strings] | |
|
2200 | ||
|
2161 | 2201 | # PARSER arguments convert all values, but check only the first |
|
2162 |
elif action.nargs |
|
|
2202 | elif action.nargs == PARSER: | |
|
2163 | 2203 | value = [self._get_value(action, v) for v in arg_strings] |
|
2164 | 2204 | self._check_value(action, value[0]) |
|
2165 | 2205 | |
@@ -2174,16 +2214,21 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
2174 | 2214 | |
|
2175 | 2215 | def _get_value(self, action, arg_string): |
|
2176 | 2216 | type_func = self._registry_get('type', action.type, action.type) |
|
2177 |
if not |
|
|
2178 | if not hasattr(type_func, '__bases__'): # classic classes | |
|
2179 | msg = _('%r is not callable') | |
|
2180 | raise ArgumentError(action, msg % type_func) | |
|
2217 | if not _callable(type_func): | |
|
2218 | msg = _('%r is not callable') | |
|
2219 | raise ArgumentError(action, msg % type_func) | |
|
2181 | 2220 | |
|
2182 | 2221 | # convert the value to the appropriate type |
|
2183 | 2222 | try: |
|
2184 | 2223 | result = type_func(arg_string) |
|
2185 | 2224 | |
|
2186 |
# Typ |
|
|
2225 | # ArgumentTypeErrors indicate errors | |
|
2226 | except ArgumentTypeError: | |
|
2227 | name = getattr(action.type, '__name__', repr(action.type)) | |
|
2228 | msg = str(_sys.exc_info()[1]) | |
|
2229 | raise ArgumentError(action, msg) | |
|
2230 | ||
|
2231 | # TypeErrors or ValueErrors also indicate errors | |
|
2187 | 2232 | except (TypeError, ValueError): |
|
2188 | 2233 | name = getattr(action.type, '__name__', repr(action.type)) |
|
2189 | 2234 | msg = _('invalid %s value: %r') |
@@ -2262,7 +2307,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||
|
2262 | 2307 | # =============== |
|
2263 | 2308 | def exit(self, status=0, message=None): |
|
2264 | 2309 | if message: |
|
2265 | _sys.stderr.write(message) | |
|
2310 | self._print_message(message, _sys.stderr) | |
|
2266 | 2311 | _sys.exit(status) |
|
2267 | 2312 | |
|
2268 | 2313 | def error(self, message): |
General Comments 0
You need to be logged in to leave comments.
Login now