Show More
@@ -2,25 +2,17 b'' | |||||
2 |
|
2 | |||
3 | # Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>. |
|
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 |
|
5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may not | |
6 | # modification, are permitted provided that the following conditions are met: |
|
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 | # http://www.apache.org/licenses/LICENSE-2.0 | |
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. |
|
|||
13 | # |
|
10 | # | |
14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
11 | # Unless required by applicable law or agreed to in writing, software | |
15 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
16 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
17 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
|
14 | # License for the specific language governing permissions and limitations | |
18 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|
15 | # under the License. | |
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. |
|
|||
24 |
|
16 | |||
25 | """Command-line parsing library |
|
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 | still considered an implementation detail.) |
|
75 | still considered an implementation detail.) | |
84 | """ |
|
76 | """ | |
85 |
|
77 | |||
86 |
__version__ = '1. |
|
78 | __version__ = '1.1a1' | |
87 | __all__ = [ |
|
79 | __all__ = [ | |
88 | 'ArgumentParser', |
|
80 | 'ArgumentParser', | |
89 | 'ArgumentError', |
|
81 | 'ArgumentError', | |
@@ -92,7 +84,7 b' __all__ = [' | |||||
92 | 'FileType', |
|
84 | 'FileType', | |
93 | 'HelpFormatter', |
|
85 | 'HelpFormatter', | |
94 | 'RawDescriptionHelpFormatter', |
|
86 | 'RawDescriptionHelpFormatter', | |
95 | 'RawTextHelpFormatter' |
|
87 | 'RawTextHelpFormatter', | |
96 | 'ArgumentDefaultsHelpFormatter', |
|
88 | 'ArgumentDefaultsHelpFormatter', | |
97 | ] |
|
89 | ] | |
98 |
|
90 | |||
@@ -126,6 +118,10 b' except NameError:' | |||||
126 | result.reverse() |
|
118 | result.reverse() | |
127 | return result |
|
119 | return result | |
128 |
|
120 | |||
|
121 | ||||
|
122 | def _callable(obj): | |||
|
123 | return hasattr(obj, '__call__') or hasattr(obj, '__bases__') | |||
|
124 | ||||
129 | # silence Python 2.6 buggy warnings about Exception.message |
|
125 | # silence Python 2.6 buggy warnings about Exception.message | |
130 | if _sys.version_info[:2] == (2, 6): |
|
126 | if _sys.version_info[:2] == (2, 6): | |
131 | import warnings |
|
127 | import warnings | |
@@ -141,7 +137,8 b" SUPPRESS = '==SUPPRESS=='" | |||||
141 | OPTIONAL = '?' |
|
137 | OPTIONAL = '?' | |
142 | ZERO_OR_MORE = '*' |
|
138 | ZERO_OR_MORE = '*' | |
143 | ONE_OR_MORE = '+' |
|
139 | ONE_OR_MORE = '+' | |
144 |
PARSER = ' |
|
140 | PARSER = 'A...' | |
|
141 | REMAINDER = '...' | |||
145 |
|
142 | |||
146 | # ============================= |
|
143 | # ============================= | |
147 | # Utility functions and classes |
|
144 | # Utility functions and classes | |
@@ -508,6 +505,8 b' class HelpFormatter(object):' | |||||
508 | return text |
|
505 | return text | |
509 |
|
506 | |||
510 | def _format_text(self, text): |
|
507 | def _format_text(self, text): | |
|
508 | if '%(prog)' in text: | |||
|
509 | text = text % dict(prog=self._prog) | |||
511 | text_width = self._width - self._current_indent |
|
510 | text_width = self._width - self._current_indent | |
512 | indent = ' ' * self._current_indent |
|
511 | indent = ' ' * self._current_indent | |
513 | return self._fill_text(text, text_width, indent) + '\n\n' |
|
512 | return self._fill_text(text, text_width, indent) + '\n\n' | |
@@ -608,7 +607,9 b' class HelpFormatter(object):' | |||||
608 | result = '[%s [%s ...]]' % get_metavar(2) |
|
607 | result = '[%s [%s ...]]' % get_metavar(2) | |
609 | elif action.nargs == ONE_OR_MORE: |
|
608 | elif action.nargs == ONE_OR_MORE: | |
610 | result = '%s [%s ...]' % get_metavar(2) |
|
609 | result = '%s [%s ...]' % get_metavar(2) | |
611 |
elif action.nargs |
|
610 | elif action.nargs == REMAINDER: | |
|
611 | result = '...' | |||
|
612 | elif action.nargs == PARSER: | |||
612 | result = '%s ...' % get_metavar(1) |
|
613 | result = '%s ...' % get_metavar(1) | |
613 | else: |
|
614 | else: | |
614 | formats = ['%s' for _ in range(action.nargs)] |
|
615 | formats = ['%s' for _ in range(action.nargs)] | |
@@ -724,6 +725,12 b' class ArgumentError(Exception):' | |||||
724 | return format % dict(message=self.message, |
|
725 | return format % dict(message=self.message, | |
725 | argument_name=self.argument_name) |
|
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 | # Action classes |
|
735 | # Action classes | |
729 | # ============== |
|
736 | # ============== | |
@@ -1018,6 +1025,7 b' class _VersionAction(Action):' | |||||
1018 |
|
1025 | |||
1019 | def __init__(self, |
|
1026 | def __init__(self, | |
1020 | option_strings, |
|
1027 | option_strings, | |
|
1028 | version=None, | |||
1021 | dest=SUPPRESS, |
|
1029 | dest=SUPPRESS, | |
1022 | default=SUPPRESS, |
|
1030 | default=SUPPRESS, | |
1023 | help=None): |
|
1031 | help=None): | |
@@ -1027,10 +1035,15 b' class _VersionAction(Action):' | |||||
1027 | default=default, |
|
1035 | default=default, | |
1028 | nargs=0, |
|
1036 | nargs=0, | |
1029 | help=help) |
|
1037 | help=help) | |
|
1038 | self.version = version | |||
1030 |
|
1039 | |||
1031 | def __call__(self, parser, namespace, values, option_string=None): |
|
1040 | def __call__(self, parser, namespace, values, option_string=None): | |
1032 | parser.print_version() |
|
1041 | version = self.version | |
1033 | parser.exit() |
|
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 | class _SubParsersAction(Action): |
|
1049 | class _SubParsersAction(Action): | |
@@ -1211,7 +1224,7 b' class _ActionsContainer(object):' | |||||
1211 | self._defaults = {} |
|
1224 | self._defaults = {} | |
1212 |
|
1225 | |||
1213 | # determines whether an "option" looks like a negative number |
|
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 | # whether or not there are any optionals that look like negative |
|
1229 | # whether or not there are any optionals that look like negative | |
1217 | # numbers -- uses a list so it can be shared and edited |
|
1230 | # numbers -- uses a list so it can be shared and edited | |
@@ -1228,7 +1241,7 b' class _ActionsContainer(object):' | |||||
1228 | return self._registries[registry_name].get(value, default) |
|
1241 | return self._registries[registry_name].get(value, default) | |
1229 |
|
1242 | |||
1230 | # ================================== |
|
1243 | # ================================== | |
1231 |
# Namespace default |
|
1244 | # Namespace default accessor methods | |
1232 | # ================================== |
|
1245 | # ================================== | |
1233 | def set_defaults(self, **kwargs): |
|
1246 | def set_defaults(self, **kwargs): | |
1234 | self._defaults.update(kwargs) |
|
1247 | self._defaults.update(kwargs) | |
@@ -1239,6 +1252,13 b' class _ActionsContainer(object):' | |||||
1239 | if action.dest in kwargs: |
|
1252 | if action.dest in kwargs: | |
1240 | action.default = kwargs[action.dest] |
|
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 | # Adding argument actions |
|
1263 | # Adding argument actions | |
1244 | # ======================= |
|
1264 | # ======================= | |
@@ -1253,6 +1273,8 b' class _ActionsContainer(object):' | |||||
1253 | # argument |
|
1273 | # argument | |
1254 | chars = self.prefix_chars |
|
1274 | chars = self.prefix_chars | |
1255 | if not args or len(args) == 1 and args[0][0] not in chars: |
|
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 | kwargs = self._get_positional_kwargs(*args, **kwargs) |
|
1278 | kwargs = self._get_positional_kwargs(*args, **kwargs) | |
1257 |
|
1279 | |||
1258 | # otherwise, we're adding an optional argument |
|
1280 | # otherwise, we're adding an optional argument | |
@@ -1269,6 +1291,8 b' class _ActionsContainer(object):' | |||||
1269 |
|
1291 | |||
1270 | # create the action object, and add it to the parser |
|
1292 | # create the action object, and add it to the parser | |
1271 | action_class = self._pop_action_class(kwargs) |
|
1293 | action_class = self._pop_action_class(kwargs) | |
|
1294 | if not _callable(action_class): | |||
|
1295 | raise ValueError('unknown action "%s"' % action_class) | |||
1272 | action = action_class(**kwargs) |
|
1296 | action = action_class(**kwargs) | |
1273 | return self._add_action(action) |
|
1297 | return self._add_action(action) | |
1274 |
|
1298 | |||
@@ -1578,6 +1602,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
1578 | if self.version: |
|
1602 | if self.version: | |
1579 | self.add_argument( |
|
1603 | self.add_argument( | |
1580 | '-v', '--version', action='version', default=SUPPRESS, |
|
1604 | '-v', '--version', action='version', default=SUPPRESS, | |
|
1605 | version=self.version, | |||
1581 | help=_("show program's version number and exit")) |
|
1606 | help=_("show program's version number and exit")) | |
1582 |
|
1607 | |||
1583 | # add parent arguments and defaults |
|
1608 | # add parent arguments and defaults | |
@@ -2011,6 +2036,13 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
2011 | action = self._option_string_actions[arg_string] |
|
2036 | action = self._option_string_actions[arg_string] | |
2012 | return action, arg_string, None |
|
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 | # search through all possible prefixes of the option string |
|
2046 | # search through all possible prefixes of the option string | |
2015 | # and all actions in the parser for possible interpretations |
|
2047 | # and all actions in the parser for possible interpretations | |
2016 | option_tuples = self._get_option_tuples(arg_string) |
|
2048 | option_tuples = self._get_option_tuples(arg_string) | |
@@ -2108,8 +2140,12 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
2108 | elif nargs == ONE_OR_MORE: |
|
2140 | elif nargs == ONE_OR_MORE: | |
2109 | nargs_pattern = '(-*A[A-]*)' |
|
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 | # allow one argument followed by any number of options or arguments |
|
2147 | # allow one argument followed by any number of options or arguments | |
2112 |
elif nargs |
|
2148 | elif nargs == PARSER: | |
2113 | nargs_pattern = '(-*A[-AO]*)' |
|
2149 | nargs_pattern = '(-*A[-AO]*)' | |
2114 |
|
2150 | |||
2115 | # all others should be integers |
|
2151 | # all others should be integers | |
@@ -2129,7 +2165,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
2129 | # ======================== |
|
2165 | # ======================== | |
2130 | def _get_values(self, action, arg_strings): |
|
2166 | def _get_values(self, action, arg_strings): | |
2131 | # for everything but PARSER args, strip out '--' |
|
2167 | # for everything but PARSER args, strip out '--' | |
2132 |
if action.nargs |
|
2168 | if action.nargs not in [PARSER, REMAINDER]: | |
2133 | arg_strings = [s for s in arg_strings if s != '--'] |
|
2169 | arg_strings = [s for s in arg_strings if s != '--'] | |
2134 |
|
2170 | |||
2135 | # optional argument produces a default when not present |
|
2171 | # optional argument produces a default when not present | |
@@ -2158,8 +2194,12 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
2158 | value = self._get_value(action, arg_string) |
|
2194 | value = self._get_value(action, arg_string) | |
2159 | self._check_value(action, value) |
|
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 | # PARSER arguments convert all values, but check only the first |
|
2201 | # PARSER arguments convert all values, but check only the first | |
2162 |
elif action.nargs |
|
2202 | elif action.nargs == PARSER: | |
2163 | value = [self._get_value(action, v) for v in arg_strings] |
|
2203 | value = [self._get_value(action, v) for v in arg_strings] | |
2164 | self._check_value(action, value[0]) |
|
2204 | self._check_value(action, value[0]) | |
2165 |
|
2205 | |||
@@ -2174,16 +2214,21 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
2174 |
|
2214 | |||
2175 | def _get_value(self, action, arg_string): |
|
2215 | def _get_value(self, action, arg_string): | |
2176 | type_func = self._registry_get('type', action.type, action.type) |
|
2216 | type_func = self._registry_get('type', action.type, action.type) | |
2177 |
if not |
|
2217 | if not _callable(type_func): | |
2178 | if not hasattr(type_func, '__bases__'): # classic classes |
|
2218 | msg = _('%r is not callable') | |
2179 | msg = _('%r is not callable') |
|
2219 | raise ArgumentError(action, msg % type_func) | |
2180 | raise ArgumentError(action, msg % type_func) |
|
|||
2181 |
|
2220 | |||
2182 | # convert the value to the appropriate type |
|
2221 | # convert the value to the appropriate type | |
2183 | try: |
|
2222 | try: | |
2184 | result = type_func(arg_string) |
|
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 | except (TypeError, ValueError): |
|
2232 | except (TypeError, ValueError): | |
2188 | name = getattr(action.type, '__name__', repr(action.type)) |
|
2233 | name = getattr(action.type, '__name__', repr(action.type)) | |
2189 | msg = _('invalid %s value: %r') |
|
2234 | msg = _('invalid %s value: %r') | |
@@ -2262,7 +2307,7 b' class ArgumentParser(_AttributeHolder, _ActionsContainer):' | |||||
2262 | # =============== |
|
2307 | # =============== | |
2263 | def exit(self, status=0, message=None): |
|
2308 | def exit(self, status=0, message=None): | |
2264 | if message: |
|
2309 | if message: | |
2265 | _sys.stderr.write(message) |
|
2310 | self._print_message(message, _sys.stderr) | |
2266 | _sys.exit(status) |
|
2311 | _sys.exit(status) | |
2267 |
|
2312 | |||
2268 | def error(self, message): |
|
2313 | def error(self, message): |
General Comments 0
You need to be logged in to leave comments.
Login now