Show More
@@ -7,7 +7,9 b'' | |||
|
7 | 7 | |
|
8 | 8 | from __future__ import absolute_import |
|
9 | 9 | |
|
10 | import abc | |
|
10 | 11 | import functools |
|
12 | import types | |
|
11 | 13 | |
|
12 | 14 | from .i18n import _ |
|
13 | 15 | from . import ( |
@@ -201,6 +203,64 b' def earlygetopt(args, shortlist, namelis' | |||
|
201 | 203 | parsedargs.extend(args[pos:]) |
|
202 | 204 | return parsedopts, parsedargs |
|
203 | 205 | |
|
206 | class customopt(object): | |
|
207 | """Manage defaults and mutations for any type of opt.""" | |
|
208 | ||
|
209 | __metaclass__ = abc.ABCMeta | |
|
210 | ||
|
211 | def __init__(self, defaultvalue): | |
|
212 | self.defaultvalue = defaultvalue | |
|
213 | ||
|
214 | def _isboolopt(self): | |
|
215 | return False | |
|
216 | ||
|
217 | @abc.abstractmethod | |
|
218 | def newstate(self, oldstate, newparam, abort): | |
|
219 | """Adds newparam to oldstate and returns the new state. | |
|
220 | ||
|
221 | On failure, abort can be called with a string error message.""" | |
|
222 | ||
|
223 | class _simpleopt(customopt): | |
|
224 | def _isboolopt(self): | |
|
225 | return isinstance(self.defaultvalue, (bool, types.NoneType)) | |
|
226 | ||
|
227 | def newstate(self, oldstate, newparam, abort): | |
|
228 | return newparam | |
|
229 | ||
|
230 | class _callableopt(customopt): | |
|
231 | def __init__(self, callablefn): | |
|
232 | self.callablefn = callablefn | |
|
233 | super(_callableopt, self).__init__(None) | |
|
234 | ||
|
235 | def newstate(self, oldstate, newparam, abort): | |
|
236 | return self.callablefn(newparam) | |
|
237 | ||
|
238 | class _listopt(customopt): | |
|
239 | def newstate(self, oldstate, newparam, abort): | |
|
240 | oldstate.append(newparam) | |
|
241 | return oldstate | |
|
242 | ||
|
243 | class _intopt(customopt): | |
|
244 | def newstate(self, oldstate, newparam, abort): | |
|
245 | try: | |
|
246 | return int(newparam) | |
|
247 | except ValueError: | |
|
248 | abort(_('expected int')) | |
|
249 | ||
|
250 | def _defaultopt(default): | |
|
251 | """Returns a default opt implementation, given a default value.""" | |
|
252 | ||
|
253 | if isinstance(default, customopt): | |
|
254 | return default | |
|
255 | elif callable(default): | |
|
256 | return _callableopt(default) | |
|
257 | elif isinstance(default, list): | |
|
258 | return _listopt(default[:]) | |
|
259 | elif type(default) is type(1): | |
|
260 | return _intopt(default) | |
|
261 | else: | |
|
262 | return _simpleopt(default) | |
|
263 | ||
|
204 | 264 | def fancyopts(args, options, state, gnu=False, early=False, optaliases=None): |
|
205 | 265 | """ |
|
206 | 266 | read args, parse options, and store options in state |
@@ -220,6 +280,7 b' def fancyopts(args, options, state, gnu=' | |||
|
220 | 280 | list - parameter string is added to a list |
|
221 | 281 | integer - parameter strings is stored as int |
|
222 | 282 | function - call function with parameter |
|
283 | customopt - subclass of 'customopt' | |
|
223 | 284 | |
|
224 | 285 | optaliases is a mapping from a canonical option name to a list of |
|
225 | 286 | additional long options. This exists for preserving backward compatibility |
@@ -250,18 +311,13 b' def fancyopts(args, options, state, gnu=' | |||
|
250 | 311 | argmap['-' + short] = name |
|
251 | 312 | for n in onames: |
|
252 | 313 | argmap['--' + n] = name |
|
253 | defmap[name] = default | |
|
314 | defmap[name] = _defaultopt(default) | |
|
254 | 315 | |
|
255 | 316 | # copy defaults to state |
|
256 | if isinstance(default, list): | |
|
257 | state[name] = default[:] | |
|
258 | elif callable(default): | |
|
259 | state[name] = None | |
|
260 | else: | |
|
261 | state[name] = default | |
|
317 | state[name] = defmap[name].defaultvalue | |
|
262 | 318 | |
|
263 | 319 | # does it take a parameter? |
|
264 | if not (default is None or default is True or default is False): | |
|
320 | if not defmap[name]._isboolopt(): | |
|
265 | 321 | if short: |
|
266 | 322 | short += ':' |
|
267 | 323 | onames = [n + '=' for n in onames] |
@@ -301,21 +357,13 b' def fancyopts(args, options, state, gnu=' | |||
|
301 | 357 | boolval = False |
|
302 | 358 | name = argmap[opt] |
|
303 | 359 | obj = defmap[name] |
|
304 | t = type(obj) | |
|
305 | if callable(obj): | |
|
306 | state[name] = defmap[name](val) | |
|
307 | elif t is type(1): | |
|
308 | try: | |
|
309 | state[name] = int(val) | |
|
310 | except ValueError: | |
|
311 | raise error.Abort(_('invalid value %r for option %s, ' | |
|
312 | 'expected int') % (val, opt)) | |
|
313 | elif t is type(''): | |
|
314 | state[name] = val | |
|
315 | elif t is type([]): | |
|
316 | state[name].append(val) | |
|
317 | elif t is type(None) or t is type(False): | |
|
360 | if obj._isboolopt(): | |
|
318 | 361 | state[name] = boolval |
|
362 | else: | |
|
363 | def abort(s): | |
|
364 | raise error.Abort( | |
|
365 | _('invalid value %r for option %s, %s') % (val, opt, s)) | |
|
366 | state[name] = defmap[name].newstate(state[name], val, abort) | |
|
319 | 367 | |
|
320 | 368 | # return unparsed args |
|
321 | 369 | return args |
General Comments 0
You need to be logged in to leave comments.
Login now