##// END OF EJS Templates
fancyopts: add support for custom multi-arg opts in fancyopts.py...
Daniel Ploch -
r36373:cc9d0763 default
parent child Browse files
Show More
@@ -7,7 +7,9 b''
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import abc
10 import functools
11 import functools
12 import types
11
13
12 from .i18n import _
14 from .i18n import _
13 from . import (
15 from . import (
@@ -201,6 +203,64 b' def earlygetopt(args, shortlist, namelis'
201 parsedargs.extend(args[pos:])
203 parsedargs.extend(args[pos:])
202 return parsedopts, parsedargs
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 def fancyopts(args, options, state, gnu=False, early=False, optaliases=None):
264 def fancyopts(args, options, state, gnu=False, early=False, optaliases=None):
205 """
265 """
206 read args, parse options, and store options in state
266 read args, parse options, and store options in state
@@ -220,6 +280,7 b' def fancyopts(args, options, state, gnu='
220 list - parameter string is added to a list
280 list - parameter string is added to a list
221 integer - parameter strings is stored as int
281 integer - parameter strings is stored as int
222 function - call function with parameter
282 function - call function with parameter
283 customopt - subclass of 'customopt'
223
284
224 optaliases is a mapping from a canonical option name to a list of
285 optaliases is a mapping from a canonical option name to a list of
225 additional long options. This exists for preserving backward compatibility
286 additional long options. This exists for preserving backward compatibility
@@ -250,18 +311,13 b' def fancyopts(args, options, state, gnu='
250 argmap['-' + short] = name
311 argmap['-' + short] = name
251 for n in onames:
312 for n in onames:
252 argmap['--' + n] = name
313 argmap['--' + n] = name
253 defmap[name] = default
314 defmap[name] = _defaultopt(default)
254
315
255 # copy defaults to state
316 # copy defaults to state
256 if isinstance(default, list):
317 state[name] = defmap[name].defaultvalue
257 state[name] = default[:]
258 elif callable(default):
259 state[name] = None
260 else:
261 state[name] = default
262
318
263 # does it take a parameter?
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 if short:
321 if short:
266 short += ':'
322 short += ':'
267 onames = [n + '=' for n in onames]
323 onames = [n + '=' for n in onames]
@@ -301,21 +357,13 b' def fancyopts(args, options, state, gnu='
301 boolval = False
357 boolval = False
302 name = argmap[opt]
358 name = argmap[opt]
303 obj = defmap[name]
359 obj = defmap[name]
304 t = type(obj)
360 if obj._isboolopt():
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):
318 state[name] = boolval
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 # return unparsed args
368 # return unparsed args
321 return args
369 return args
General Comments 0
You need to be logged in to leave comments. Login now