def Substring(context, st, start, length=None): """Function: <string> substring(<string>, <number>, <number>?)""" if not isinstance(st, XPathStringType): st = Conversions.StringValue(st) if not isinstance(start, NumberType): start = Conversions.NumberValue(start) # start == NaN: spec doesn't say; assume no substring to return # start == +Inf or -Inf: no substring to return if number.isnan(start) or number.isinf(start): return u'' # start is finite, safe for int() and round(). start = int(round(start)) # convert to 0-based index for python string slice if start < 1: startidx = 0 else: startidx = start - 1 # length undefined: return chars startidx to end if length is None: return st[startidx:] elif not isinstance(length, NumberType): length = Conversions.NumberValue(length) # length == NaN: spec doesn't say; assume no substring to return if number.isnan(length): return u'' # length == +Inf: return chars startidx to end # length == -Inf: no substring to return elif number.isinf(length): if length > 0: return st[startidx:] else: return u'' # length is finite, safe for int() and round(). length = int(round(length)) # return value must end before position (start+length) # which is (start+length-1) in 0-based index endidx = start + length - 1 if endidx > startidx: return st[startidx:endidx] else: return u''
def Round(context, object_): """Function: <number> round(<number>)""" num = Conversions.NumberValue(object_) if number.isnan(num) or number.isinf(num): return num elif num < 0 and num % 1.0 == 0.5: return round(num, 0) + 1 else: return round(num, 0)
def __repr__(self): if number.isnan(self._literal): return 'NaN' elif number.isinf(self._literal): if self._literal < 0: return '-Infinity' else: return 'Infinity' else: return str(self._nliteral)
def Ceiling(context, object_): """Function: <number> ceiling(<number>)""" num = Conversions.NumberValue(object_) if number.isnan(num) or number.isinf(num): return num elif int(num) == num: return num elif num > 0: return float(int(num) + 1) else: return float(int(num))
def Floor(context, object_): """Function: <number> floor(<number>)""" num = Conversions.NumberValue(object_) if number.isnan(num) or number.isinf(num): return num elif int(num) == num: return num elif num < 0: return float(int(num) - 1) else: return float(int(num))
def Range(context, lo, hi): """ Returns a node-set consisting of text nodes encapsulating integers in the numeric range bounded by the given low and high values. """ # contributed by Lars Marius Garshol; # originally using namespace URI 'http://garshol.priv.no/symbolic/' doc = context.node.rootNode # sanity check for n in (lo, hi): if number.isinf(n) or number.isnan(n): raise ValueError("Arguments to ft:range must be neither infinite nor NaN.") #xrange wants int, not float lo = int(round(Conversions.NumberValue(lo))) hi = int(round(Conversions.NumberValue(hi))) nodeset = [] for num in xrange(lo, hi): nodeset.append(doc.createTextNode(str(num))) return nodeset
def compare(self, expected, actual, msg=None, func=cmp, diff=0, stackLevel=1, funcArgs={}): """ Uses func to compare the expected result with actual result of a regression test. diff is ignored. msg is an optional custom message to print if the comparison tests positive (i.e. the results differ). func is the comparison function to use, and must be a function that returns the same as the built-in cmp(). stackLevel affects exception reporting. funcArgs is an optional dictionary of keyword arguments that will be passed to the comparison function, if the dictionary is not empty. """ self.totalComparisons += 1 # Normalize float values if type(expected) == type(actual) == float: if number.finite(expected): expected = float(str(expected)) elif number.isnan(expected): expected = 'NaN' elif number.isinf(expected) > 0: expected = 'Inf' else: expected = '-Inf' if number.finite(actual): actual = float(str(actual)) elif number.isnan(actual): actual = 'NaN' elif number.isinf(actual) > 0: actual = 'Inf' else: actual = '-Inf' # Make sure there was a message for this comparison if not msg: if self.test: self.test.comparisons += 1 msg = 'Test %d' % (self.test.comparisons) else: msg = 'Test %d of all tests' % self.totalComparisons start = time.time() try: if funcArgs: res = func(expected, actual, **funcArgs) else: res = func(expected, actual) if res: # failure self.message(msg) if diff and self.verbose >= VERBOSE_DEBUG: self._diff(expected, actual) error = '%sExpected:%s %s\n' % (self.GREEN, self.NORMAL, repr(expected)) error += '%sCompared:%s %s' % (self.RED, self.NORMAL, repr(actual)) self.error(error, stackLevel=(stackLevel+1)) return 0 finally: end = time.time() if self.test: self.test.compareTime += (end - start) # success return 1
def compare(self, expected, actual, msg=None, func=cmp, diff=0, stackLevel=1, funcArgs={}): """ Uses func to compare the expected result with actual result of a regression test. diff is ignored. msg is an optional custom message to print if the comparison tests positive (i.e. the results differ). func is the comparison function to use, and must be a function that returns the same as the built-in cmp(). stackLevel affects exception reporting. funcArgs is an optional dictionary of keyword arguments that will be passed to the comparison function, if the dictionary is not empty. """ self.totalComparisons += 1 # Normalize float values if type(expected) == type(actual) == float: if number.finite(expected): expected = float(str(expected)) elif number.isnan(expected): expected = 'NaN' elif number.isinf(expected) > 0: expected = 'Inf' else: expected = '-Inf' if number.finite(actual): actual = float(str(actual)) elif number.isnan(actual): actual = 'NaN' elif number.isinf(actual) > 0: actual = 'Inf' else: actual = '-Inf' # Make sure there was a message for this comparison if not msg: if self.test: self.test.comparisons += 1 msg = 'Test %d' % (self.test.comparisons) else: msg = 'Test %d of all tests' % self.totalComparisons start = time.time() try: if funcArgs: res = func(expected, actual, **funcArgs) else: res = func(expected, actual) if res: # failure self.message(msg) if diff and self.verbose >= VERBOSE_DEBUG: self._diff(expected, actual) error = '%sExpected:%s %s\n' % (self.GREEN, self.NORMAL, repr(expected)) error += '%sCompared:%s %s' % (self.RED, self.NORMAL, repr(actual)) self.error(error, stackLevel=(stackLevel + 1)) return 0 finally: end = time.time() if self.test: self.test.compareTime += (end - start) # success return 1