Ejemplo n.º 1
0
def FloatCompare(a, b):
    a = float(a or 0)
    b = float(b or 0)
    
    # NaN seems to always equal everything else, so we'll do it ourselves
    # the IEEE definition of NaN makes it the largest possible number
    if number.isnan(a):
        if number.isnan(b):
            return 0
        else:
            return -1
    elif number.isnan(b):
        return 1

    return cmp(a, b)
Ejemplo n.º 2
0
 def f(a, b):
     if number.isnan(b):
         return b
     elif a > b:
         return a
     else:
         return b
Ejemplo n.º 3
0
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''
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
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))
Ejemplo n.º 7
0
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))
Ejemplo n.º 8
0
def _strFloat(float):
    if number.finite(float):
        if float == round(float):
            return unicode(str(long(float)))
        else:
            # 12 digits is how many Python uses for str()
            return u'%0.12g' % float
    elif number.isnan(float):
        return u'NaN'
    elif float < 0:
        return u'-Infinity'
    else:
        return u'Infinity'
Ejemplo n.º 9
0
def _strFloat(float):
    if number.finite(float):
        if float == round(float):
            return unicode(str(long(float)))
        else:
            # 12 digits is how many Python uses for str()
            return u'%0.12g' % float
    elif number.isnan(float):
        return u'NaN'
    elif float < 0:
        return u'-Infinity'
    else:
        return u'Infinity'
Ejemplo n.º 10
0
def Sqrt(context, num):
    """
    The math:sqrt function returns the square root of a number.
    """
    # The platform C library determines what math.sqrt() returns.
    # On some platforms, especially prior to Python 2.4,
    # nan may be returned for a negative or nan argument.
    # On other platforms, and especially since Python 2.4,
    # a ValueError is raised.
    #
    # EXSLT requires that we return zero for negative arg.
    # The result for a nan arg is undefined, but we'll return nan.
    n = Conversions.NumberValue(num)
    if number.isnan(n):
        return number.nan
    if n < 0.0:
        return 0.0
    try:
        return math.sqrt(Conversions.NumberValue(num))
    except ValueError:
        return 0.0
Ejemplo n.º 11
0
def Sqrt(context, num):
    """
    The math:sqrt function returns the square root of a number.
    """
    # The platform C library determines what math.sqrt() returns.
    # On some platforms, especially prior to Python 2.4,
    # nan may be returned for a negative or nan argument.
    # On other platforms, and especially since Python 2.4,
    # a ValueError is raised.
    #
    # EXSLT requires that we return zero for negative arg.
    # The result for a nan arg is undefined, but we'll return nan.
    n = Conversions.NumberValue(num)
    if number.isnan(n):
        return number.nan
    if n < 0.0:
        return 0.0
    try:
        return math.sqrt(Conversions.NumberValue(num))
    except ValueError:
        return 0.0
Ejemplo n.º 12
0
def Lowest(context, nodeset):
    """
    The math:lowest function returns the nodes in the node set whose value is
    the minimum value for the node set. The minimum value for the node set is
    the same as the value as calculated by math:min. A node has this minimum
    value if the result of converting its string value to a number as if by the
    number function is equal to the minimum value, where the equality
    comparison is defined as a numerical comparison using the = operator.
    """
    if type(nodeset) != type([]):
        raise XsltRuntimeException(Error.WRONG_ARGUMENT_TYPE,
                                   context.currentInstruction)

    numbers = map(Conversions.NumberValue, nodeset)
    min = _min(numbers[:])
    if number.isnan(min):
        return []
    result = []
    for i in xrange(len(nodeset)):
        if numbers[i] == min:
            result.append(nodeset[i])
    return result
Ejemplo n.º 13
0
def Lowest(context, nodeset):
    """
    The math:lowest function returns the nodes in the node set whose value is
    the minimum value for the node set. The minimum value for the node set is
    the same as the value as calculated by math:min. A node has this minimum
    value if the result of converting its string value to a number as if by the
    number function is equal to the minimum value, where the equality
    comparison is defined as a numerical comparison using the = operator.
    """
    if type(nodeset) != type([]):
        raise XsltRuntimeException(Error.WRONG_ARGUMENT_TYPE,
                                   context.currentInstruction)

    numbers = map(Conversions.NumberValue, nodeset)
    min = _min(numbers[:])
    if number.isnan(min):
        return []
    result = []
    for i in xrange(len(nodeset)):
        if numbers[i] == min:
            result.append(nodeset[i])
    return result
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
 def filter(self, nodeList, context, reverse):
     if self._length:
         state = context.copy()
         for pred in self._predicates:
             size = len(nodeList)
             ctr = 0
             current = nodeList
             nodeList = []
             for node in current:
                 position = (reverse and size - ctr) or (ctr + 1)
                 context.node, context.position, context.size = \
                               node, position, size
                 res = pred.evaluate(context)
                 if type(res) in NumberTypes:
                     # This must be separate to prevent falling into
                     # the boolean check.
                     if not number.isnan(res) and res == position:
                         nodeList.append(node)
                 elif Conversions.BooleanValue(res):
                     nodeList.append(node)
                 ctr += 1
         context.set(state)
     return nodeList
Ejemplo n.º 17
0
    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
Ejemplo n.º 18
0
    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