X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/b247c6fca8c673282a0210cf90e5a0921c24fabc..ee501db1b85addbf981782924cb43bba1a78dddd:/lib/ht.py diff --git a/lib/ht.py b/lib/ht.py index ff9d6da..2613be3 100644 --- a/lib/ht.py +++ b/lib/ht.py @@ -46,7 +46,7 @@ def Parens(text): return "(%s)" % text -class _DescWrapper(object): +class _WrapperBase(object): __slots__ = [ "_fn", "_text", @@ -59,16 +59,31 @@ class _DescWrapper(object): @param fn: Wrapped function """ + assert text.strip() + self._text = text self._fn = fn def __call__(self, *args): return self._fn(*args) + +class _DescWrapper(_WrapperBase): + """Wrapper class for description text. + + """ def __str__(self): return self._text +class _CommentWrapper(_WrapperBase): + """Wrapper class for comment. + + """ + def __str__(self): + return "%s [%s]" % (self._fn, self._text) + + def WithDesc(text): """Builds wrapper class with description text. @@ -82,6 +97,19 @@ def WithDesc(text): return compat.partial(_DescWrapper, text) +def Comment(text): + """Builds wrapper for adding comment to description text. + + @type text: string + @param text: Comment text + @return: Callable class + + """ + assert not frozenset(text).intersection("[]") + + return compat.partial(_CommentWrapper, text) + + def CombinationDesc(op, args, fn): """Build description for combinating operator. @@ -294,10 +322,16 @@ TMaybeDict = TOr(TDict, TNone) TPositiveInt = \ TAnd(TInt, WithDesc("EqualGreaterZero")(lambda v: v >= 0)) +#: a maybe positive integer (positive integer or None) +TMaybePositiveInt = TOr(TPositiveInt, TNone) + #: a strictly positive integer TStrictPositiveInt = \ TAnd(TInt, WithDesc("GreaterThanZero")(lambda v: v > 0)) +#: a maybe strictly positive integer (strictly positive integer or None) +TMaybeStrictPositiveInt = TOr(TStrictPositiveInt, TNone) + #: a strictly negative integer (0 > value) TStrictNegativeInt = \ TAnd(TInt, WithDesc("LessThanZero")(compat.partial(operator.gt, 0))) @@ -307,8 +341,9 @@ TPositiveFloat = \ TAnd(TFloat, WithDesc("EqualGreaterZero")(lambda v: v >= 0.0)) #: Job ID -TJobId = TOr(TPositiveInt, - TRegex(re.compile("^%s$" % constants.JOB_ID_TEMPLATE))) +TJobId = WithDesc("JobId")(TOr(TPositiveInt, + TRegex(re.compile("^%s$" % + constants.JOB_ID_TEMPLATE)))) #: Number TNumber = TOr(TInt, TFloat) @@ -317,6 +352,14 @@ TNumber = TOr(TInt, TFloat) TRelativeJobId = WithDesc("RelativeJobId")(TStrictNegativeInt) +def TInstanceOf(my_inst): + """Checks if a given value is an instance of my_inst. + + """ + desc = WithDesc("Instance of %s" % (Parens(my_inst), )) + return desc(lambda val: isinstance(val, my_inst)) + + def TListOf(my_type): """Checks if a given value is a list with all elements of the same type. @@ -325,6 +368,9 @@ def TListOf(my_type): return desc(TAnd(TList, lambda lst: compat.all(my_type(v) for v in lst))) +TMaybeListOf = lambda item_type: TOr(TNone, TListOf(item_type)) + + def TDictOf(key_type, val_type): """Checks a dict type for the type of its key/values.