Example #1
0
def test_string_to_float_nan():
    nan = float('nan')
    pinf = float('inf')
    for s in ['nan', '+nan', '-nan', 'NAN', '+nAn']:
        assert math.isnan(string_to_float(s))
    for s in ['inf', '+inf', '-inf', '-infinity', '   -infiNITy  ']:
        assert math.isinf(string_to_float(s))
Example #2
0
    def descr__new__(space, w_complextype, w_real, w_imag=None):
        # if w_real is already a complex number and there is no second
        # argument, return it.  Note that we cannot return w_real if
        # it is an instance of a *subclass* of complex, or if w_complextype
        # is itself a subclass of complex.
        noarg2 = w_imag is None
        if (noarg2 and space.is_w(w_complextype, space.w_complex)
                and space.is_w(space.type(w_real), space.w_complex)):
            return w_real

        if space.isinstance_w(w_real, space.w_text):
            # a string argument
            if not noarg2:
                raise oefmt(
                    space.w_TypeError, "complex() can't take second"
                    " arg if first is a string")
            unistr = unicode_to_decimal_w(space, w_real)
            try:
                unistr = _remove_underscores(unistr)
            except ValueError:
                raise oefmt(space.w_ValueError,
                            "complex() arg is a malformed string")
            try:
                realstr, imagstr = _split_complex(unistr)
            except ValueError:
                raise oefmt(space.w_ValueError,
                            "complex() arg is a malformed string")
            try:
                realval = string_to_float(realstr)
                imagval = string_to_float(imagstr)
            except ParseStringError:
                raise oefmt(space.w_ValueError,
                            "complex() arg is a malformed string")

        else:
            # non-string arguments
            realval, imagval = unpackcomplex(space, w_real)

            # now take w_imag into account
            if not noarg2:
                # complex(x, y) == x+y*j, even if 'y' is already a complex.
                realval2, imagval2 = unpackcomplex(space,
                                                   w_imag,
                                                   firstarg=False)

                # try to preserve the signs of zeroes of realval and realval2
                if imagval2 != 0.0:
                    realval -= imagval2

                if imagval != 0.0:
                    imagval += realval2
                else:
                    imagval = realval2
        # done
        w_obj = space.allocate_instance(W_ComplexObject, w_complextype)
        W_ComplexObject.__init__(w_obj, realval, imagval)
        return w_obj
Example #3
0
def descr__new__(space, w_complextype, w_real, w_imag=None):
    from pypy.objspace.std.complexobject import W_ComplexObject

    # if w_real is already a complex number and there is no second
    # argument, return it.  Note that we cannot return w_real if
    # it is an instance of a *subclass* of complex, or if w_complextype
    # is itself a subclass of complex.
    noarg2 = w_imag is None
    if (noarg2 and space.is_w(w_complextype, space.w_complex)
            and space.is_w(space.type(w_real), space.w_complex)):
        return w_real

    if space.isinstance_w(w_real, space.w_str) or \
            space.isinstance_w(w_real, space.w_unicode):
        # a string argument
        if not noarg2:
            raise OperationError(
                space.w_TypeError,
                space.wrap("complex() can't take second arg"
                           " if first is a string"))
        try:
            realstr, imagstr = _split_complex(space.str_w(w_real))
        except ValueError:
            raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED))
        try:
            realval = string_to_float(realstr)
            imagval = string_to_float(imagstr)
        except ParseStringError:
            raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED))

    else:
        # non-string arguments
        realval, imagval = unpackcomplex(space, w_real, strict_typing=False)

        # now take w_imag into account
        if not noarg2:
            # complex(x, y) == x+y*j, even if 'y' is already a complex.
            realval2, imagval2 = unpackcomplex(space,
                                               w_imag,
                                               strict_typing=False)

            # try to preserve the signs of zeroes of realval and realval2
            if imagval2 != 0.0:
                realval -= imagval2

            if imagval != 0.0:
                imagval += realval2
            else:
                imagval = realval2
    # done
    w_obj = space.allocate_instance(W_ComplexObject, w_complextype)
    W_ComplexObject.__init__(w_obj, realval, imagval)
    return w_obj
Example #4
0
    def descr__new__(space, w_complextype, w_real, w_imag=None):
        # if w_real is already a complex number and there is no second
        # argument, return it.  Note that we cannot return w_real if
        # it is an instance of a *subclass* of complex, or if w_complextype
        # is itself a subclass of complex.
        noarg2 = w_imag is None
        if (noarg2 and space.is_w(w_complextype, space.w_complex)
            and space.is_w(space.type(w_real), space.w_complex)):
            return w_real

        if space.isinstance_w(w_real, space.w_str) or \
                space.isinstance_w(w_real, space.w_unicode):
            # a string argument
            if not noarg2:
                raise oefmt(space.w_TypeError, "complex() can't take second"
                                               " arg if first is a string")
            try:
                realstr, imagstr = _split_complex(space.str_w(w_real))
            except ValueError:
                raise oefmt(space.w_ValueError,
                            "complex() arg is a malformed string")
            try:
                realval = string_to_float(realstr)
                imagval = string_to_float(imagstr)
            except ParseStringError:
                raise oefmt(space.w_ValueError,
                            "complex() arg is a malformed string")

        else:
            # non-string arguments
            realval, imagval = unpackcomplex(space, w_real,
                                             strict_typing=False)

            # now take w_imag into account
            if not noarg2:
                # complex(x, y) == x+y*j, even if 'y' is already a complex.
                realval2, imagval2 = unpackcomplex(space, w_imag,
                                                   strict_typing=False)

                # try to preserve the signs of zeroes of realval and realval2
                if imagval2 != 0.0:
                    realval -= imagval2

                if imagval != 0.0:
                    imagval += realval2
                else:
                    imagval = realval2
        # done
        w_obj = space.allocate_instance(W_ComplexObject, w_complextype)
        W_ComplexObject.__init__(w_obj, realval, imagval)
        return w_obj
Example #5
0
 def _string_to_float(space, w_source, string):
     try:
         string = _remove_underscores(string)
     except ValueError:
         pass
     else:
         try:
             return rfloat.string_to_float(string)
         except ParseStringError as e:
             pass
     raise oefmt(space.w_ValueError,
                 "could not convert string to float: %R", w_source)
Example #6
0
 def save_field(self, field_builder):
     field = field_builder.build()
     if self.numeric_field:
         from rpython.rlib.rstring import ParseStringError
         from rpython.rlib.rfloat import string_to_float
         self.numeric_field = False
         try:
             ff = string_to_float(field)
         except ParseStringError, e:
             raise OperationError(self.space.w_ValueError,
                                  self.space.wrap(e.msg))
         w_obj = self.space.wrap(ff)
Example #7
0
def str2num(w_s):
    from rpython.rlib import rarithmetic, rfloat, rbigint
    from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError

    s = w_s.as_str_utf8()
    try:
        if "." in s:
            return values.W_Flonum(rfloat.string_to_float(s))
        else:
            try:
                return values.W_Fixnum(rarithmetic.string_to_int(s, base=10))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s))
    except ParseStringError as e:
        return values.w_false
Example #8
0
File: string.py Project: 8l/pycket
def str2num(w_s):
    from rpython.rlib import rarithmetic, rfloat, rbigint
    from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError

    try:
        s = w_s.as_str_utf8()
        if "." in s:
            return values.W_Flonum(rfloat.string_to_float(s))
        else:
            try:
                return values.W_Fixnum(rarithmetic.string_to_int(s, base=0))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s))
    except ParseStringError as e:
        return values.w_false
Example #9
0
 def save_field(self, field_builder):
     space = self.space
     field = field_builder.build()
     if self.numeric_field:
         from rpython.rlib.rstring import ParseStringError
         from rpython.rlib.rfloat import string_to_float
         self.numeric_field = False
         try:
             ff = string_to_float(field)
         except ParseStringError as e:
             raise wrap_parsestringerror(space, e, space.wrap(field))
         w_obj = space.wrap(ff)
     else:
         w_obj = space.wrap(field)
     self.fields_w.append(w_obj)
Example #10
0
 def save_field(self, field_builder):
     space = self.space
     field = field_builder.build()
     if self.numeric_field:
         from rpython.rlib.rstring import ParseStringError
         from rpython.rlib.rfloat import string_to_float
         self.numeric_field = False
         try:
             ff = string_to_float(field)
         except ParseStringError as e:
             raise wrap_parsestringerror(space, e, space.wrap(field))
         w_obj = space.wrap(ff)
     else:
         w_obj = space.wrap(field)
     self.fields_w.append(w_obj)
Example #11
0
def descr__new__(space, w_floattype, w_x):
    from pypy.objspace.std.floatobject import W_FloatObject
    w_value = w_x     # 'x' is the keyword argument name in CPython
    w_special = space.lookup(w_value, "__float__")
    if w_special is not None:
        w_obj = space.get_and_call_function(w_special, w_value)
        if not space.isinstance_w(w_obj, space.w_float):
            raise OperationError(space.w_TypeError,
                                 space.wrap("__float__ returned non-float"))
        if space.is_w(w_floattype, space.w_float):
            return w_obj
        value = space.float_w(w_obj)
    elif (space.isinstance_w(w_value, space.w_str) or
          space.isinstance_w(w_value, space.w_bytearray)):
        strvalue = space.bufferstr_w(w_value)
        try:
            value = rfloat.string_to_float(strvalue)
        except ParseStringError, e:
            raise OperationError(space.w_ValueError,
                                 space.wrap(e.msg))
Example #12
0
def load_object(fp):
    fp.next_reference_obj -= 1
    needs_ref = (fp.next_reference_obj == 0)
    #
    fp.error_pos = fp.pos
    try:
        i = fp.consume(2)
    except SerializerError:
        i = fp.consume(1)
        if fp.s[i] == '}':
            fp.space.ec.notice("unserialize(): "
                               "Unexpected end of serialized data")
        raise
    s = fp.s
    tp = s[i]
    check_nonneg(i)
    check_nonneg(fp.pos)
    #
    if tp == 'i':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        i = fp.read_int_until(';')
        w_result = fp.space.wrap(i)
    #
    elif tp == 's':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        w_result = fp.space.newstr(load_str(fp, ';'))
    #
    elif tp == 'd':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        data = fp.read_substring_until(';')
        try:
            result = string_to_float(data)
        except ParseStringError:
            raise SerializerError('bad double')
        w_result = fp.space.newfloat(result)
    #
    elif tp == 'b':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        i = fp.consume(2)
        digit = s[i]
        if digit == '0':
            w_result = fp.space.w_False
        elif digit == '1':
            w_result = fp.space.w_True
        else:
            raise SerializerError('bad bool')
        if s[i + 1] != ';':
            raise SerializerError("';' expected")
    #
    elif tp == 'N':
        if s[i + 1] != ';':
            raise SerializerError("';' expected")
        w_result = fp.space.w_Null
    #
    elif tp == 'a':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        length = fp.read_int_until(':', can_be_negative=False)
        if length < 0:
            raise SerializerError("integer overflow")
        i = fp.consume(1)
        if s[i] != '{':
            raise SerializerError("'{' expected")
        w_result = None
        if needs_ref:
            w_result = fp.space.empty_ref()
            fp.save_reference(w_result)
        # first try to load the array as a direct list
        lst_w = []
        expected = ['i', ':', '0', ';']
        for n in range(length):
            i = fp.pos
            if i + len(expected) >= len(s):
                break
            for j in range(len(expected)):
                if s[i] != expected[j]:
                    break
                i += 1
            else:
                # ok, we got exactly 'i:N;' where N is the expected index
                fp.pos = i
                lst_w.append(load_object(fp))
                # increment the expected counter
                j = len(expected) - 2
                while j >= 2:
                    if expected[j] != '9':
                        expected[j] = chr(ord(expected[j]) + 1)
                        break
                    expected[j] = '0'
                    j -= 1
                else:
                    expected = ['i', ':', '1'] + expected[2:]
                continue
            break
        else:
            # we succeeded in loading the complete array as a list
            n = length
            _succeeded_as_a_list()  # for tests
        # fill in the remaining entries, if any, the slow way
        w_array = fp.space.new_array_from_list(lst_w)
        for n in range(n, length):
            w_key = load_array_key(fp)
            w_value = load_object(fp)
            w_array = fp.space.setitem_maybe_inplace(w_array, w_key, w_value)
        fp.expect_closing_brace()
        if w_result is not None:  # needs_ref
            w_result.store(w_array, unique=True)
            return w_result
        else:
            return w_array
    #
    elif tp == 'R':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        return load_reference(fp)
    #
    elif tp == 'r':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        return load_reference(fp).deref()
    #
    elif tp == 'O':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        klass_name = load_str(fp, ':')
        space = fp.space
        interp = space.ec.interpreter
        klass = interp.lookup_class_or_intf(klass_name)
        if klass is None:
            klass = k_incomplete
            w_instance = klass.get_empty_instance(space)
            w_instance.setattr(interp, '__PHP_Incomplete_Class_Name',
                               space.wrap(klass_name), None)
        else:
            w_instance = klass.get_empty_instance(space)
        w_result = w_instance
        if needs_ref:
            w_result = W_Reference(w_instance)
            fp.save_reference(w_result)
        count_attrs = fp.read_int_until(':')  # negative value accepted :-(
        i = fp.consume(1)
        if s[i] != '{':
            raise SerializerError("'{' expected")
        attrs = {}
        for i in xrange(count_attrs):
            w_attr = load_array_key(fp)
            w_value = load_object(fp)
            attr_name = space.str_w(w_attr)
            attrs[attr_name] = w_value
            w_instance.setattr(interp, attr_name, w_value, None)
        fp.expect_closing_brace()

        w_instance.unserialize(space, attrs)

        if '__wakeup' in klass.methods:
            klass.methods['__wakeup'].method_func.call_args(
                space.ec.interpreter, [], w_this=w_instance, thisclass=klass)
        return w_result
    #
    else:
        if tp == '}':
            fp.space.ec.notice("unserialize(): "
                               "Unexpected end of serialized data")
        raise SerializerError('malformed input')

    # this is for primitive types only; complex types 'return' above
    if needs_ref:
        w_result = W_Reference(w_result)
        fp.save_reference(w_result)
    return w_result
 def _string_to_float(space, w_source, string):
     try:
         return rfloat.string_to_float(string)
     except ParseStringError as e:
         raise oefmt(space.w_ValueError,
                     "could not convert string to float: %R", w_source)
Example #14
0
            if len(e_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" % s)

            try:
                num = float(e_parts[0])
                exp = int(e_parts[1])
                p = math.pow(10, exp)
            except ValueError, e:
                return values.w_false

            return values.W_Flonum(num*p)

        if "." in s or re.match("[+-]?([\d]+)(\.[\d]+)?e[+-][\d]+$", s):
            if not radix == 10: # FIXME
                raise SchemeException("string->number : floats with base different than 10 are not supported yet : given number : %s - radix : %s" % (s, str(radix)))
            return values.W_Flonum(rfloat.string_to_float(s))
        else:
            try:
                return values.W_Fixnum(rarithmetic.string_to_int(s, base=radix))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s, base=radix))
    except ParseStringError as e:
        return values.w_false

@expose("number->string",
        [values.W_Number, default(values.W_Fixnum, values.W_Fixnum.make(10))])
def num2str(a, radix):
    from rpython.rlib.rbigint import BASE8, BASE16
    if radix.value == 10:
        return W_String.fromascii(a.tostring())
    else:
Example #15
0
def test_string_to_float():
    from rpython.rlib.rstring import ParseStringError
    import random
    assert string_to_float('0') == 0.0
    assert string_to_float('1') == 1.0
    assert string_to_float('-1.5') == -1.5
    assert string_to_float('1.5E2') == 150.0
    assert string_to_float('2.5E-1') == 0.25
    assert string_to_float('1e1111111111111') == float('1e1111111111111')
    assert string_to_float('1e-1111111111111') == float('1e-1111111111111')
    assert string_to_float('-1e1111111111111') == float('-1e1111111111111')
    assert string_to_float('-1e-1111111111111') == float('-1e-1111111111111')
    assert string_to_float('1e111111111111111111111') == float('1e111111111111111111111')
    assert string_to_float('1e-111111111111111111111') == float('1e-111111111111111111111')
    assert string_to_float('-1e111111111111111111111') == float('-1e111111111111111111111')
    assert string_to_float('-1e-111111111111111111111') == float('-1e-111111111111111111111')

    valid_parts = [['', '  ', ' \f\n\r\t\v'],
                   ['', '+', '-'],
                   ['00', '90', '.5', '2.4', '3.', '0.07',
                    '12.3489749871982471987198371293717398256187563298638726'
                    '2187362820947193247129871083561249818451804287437824015'
                    '013816418758104762348932657836583048761487632840726386'],
                   ['', 'e0', 'E+1', 'E-01', 'E42'],
                   ['', '  ', ' \f\n\r\t\v'],
                   ]
    invalid_parts = [['#'],
                     ['++', '+-', '-+', '--'],
                     ['', '1.2.3', '.', '5..6'],
                     ['E+', 'E-', 'e', 'e++', 'E++2'],
                     ['#'],
                     ]
    for part0 in valid_parts[0]:
        for part1 in valid_parts[1]:
            for part2 in valid_parts[2]:
                for part3 in valid_parts[3]:
                    for part4 in valid_parts[4]:
                        s = part0+part1+part2+part3+part4
                        assert (abs(string_to_float(s) - float(s)) <=
                                1E-13 * abs(float(s)))

    for j in range(len(invalid_parts)):
        for invalid in invalid_parts[j]:
            for i in range(20):
                parts = [random.choice(lst) for lst in valid_parts]
                parts[j] = invalid
                s = ''.join(parts)
                print repr(s)
                if s.strip(): # empty s raises OperationError directly
                    py.test.raises(ParseStringError, string_to_float, s)
    py.test.raises(ParseStringError, string_to_float, "")
Example #16
0
            if len(e_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" % s)

            try:
                num = float(e_parts[0])
                exp = int(e_parts[1])
                p = math.pow(10, exp)
            except ValueError, e:
                return values.w_false

            return values.W_Flonum(num*p)

        if "." in s or re.match("[+-]?([\d]+)(\.[\d]+)?e[+-][\d]+$", s):
            if not radix == 10: # FIXME
                raise SchemeException("string->number : floats with base different than 10 are not supported yet : given number : %s - radix : %s" % (w_s.tostring(), str(radix)))
            return values.W_Flonum(rfloat.string_to_float(s))
        else:
            try:
                return values.W_Fixnum(rarithmetic.string_to_int(s, base=radix))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s, base=radix))
    except ParseStringError as e:
        return values.w_false

@expose("number->string",
        [values.W_Number, default(values.W_Fixnum, values.W_Fixnum.make(10))])
def num2str(a, radix):
    from rpython.rlib.rbigint import BASE8, BASE16
    if radix.value == 10:
        return W_String.fromascii(a.tostring())
    else:
Example #17
0
def _string_to_float(space, w_source, string):
    try:
        return rfloat.string_to_float(string)
    except ParseStringError as e:
        from pypy.objspace.std.intobject import wrap_parsestringerror
        raise wrap_parsestringerror(space, e, w_source)
Example #18
0
def string_to_float(s):
    return model.w_float(rfloat.string_to_float(s))
Example #19
0
def load_object(fp):
    fp.next_reference_obj -= 1
    needs_ref = (fp.next_reference_obj == 0)
    #
    fp.error_pos = fp.pos
    try:
        i = fp.consume(2)
    except SerializerError:
        i = fp.consume(1)
        if fp.s[i] == '}':
            fp.space.ec.notice("unserialize(): "
                               "Unexpected end of serialized data")
        raise
    s = fp.s
    tp = s[i]
    check_nonneg(i)
    check_nonneg(fp.pos)
    #
    if tp == 'i':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        i = fp.read_int_until(';')
        w_result = fp.space.wrap(i)
    #
    elif tp == 's':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        w_result = fp.space.newstr(load_str(fp, ';'))
    #
    elif tp == 'd':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        data = fp.read_substring_until(';')
        try:
            result = string_to_float(data)
        except ParseStringError:
            raise SerializerError('bad double')
        w_result = fp.space.newfloat(result)
    #
    elif tp == 'b':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        i = fp.consume(2)
        digit = s[i]
        if digit == '0':
            w_result = fp.space.w_False
        elif digit == '1':
            w_result = fp.space.w_True
        else:
            raise SerializerError('bad bool')
        if s[i + 1] != ';':
            raise SerializerError("';' expected")
    #
    elif tp == 'N':
        if s[i + 1] != ';':
            raise SerializerError("';' expected")
        w_result = fp.space.w_Null
    #
    elif tp == 'a':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        length = fp.read_int_until(':', can_be_negative=False)
        if length < 0:
            raise SerializerError("integer overflow")
        i = fp.consume(1)
        if s[i] != '{':
            raise SerializerError("'{' expected")
        w_result = None
        if needs_ref:
            w_result = fp.space.empty_ref()
            fp.save_reference(w_result)
        # first try to load the array as a direct list
        lst_w = []
        expected = ['i', ':', '0', ';']
        for n in range(length):
            i = fp.pos
            if i + len(expected) >= len(s):
                break
            for j in range(len(expected)):
                if s[i] != expected[j]:
                    break
                i += 1
            else:
                # ok, we got exactly 'i:N;' where N is the expected index
                fp.pos = i
                lst_w.append(load_object(fp))
                # increment the expected counter
                j = len(expected) - 2
                while j >= 2:
                    if expected[j] != '9':
                        expected[j] = chr(ord(expected[j]) + 1)
                        break
                    expected[j] = '0'
                    j -= 1
                else:
                    expected = ['i', ':', '1'] + expected[2:]
                continue
            break
        else:
            # we succeeded in loading the complete array as a list
            n = length
            _succeeded_as_a_list()   # for tests
        # fill in the remaining entries, if any, the slow way
        w_array = fp.space.new_array_from_list(lst_w)
        for n in range(n, length):
            w_key = load_array_key(fp)
            w_value = load_object(fp)
            w_array = fp.space.setitem_maybe_inplace(w_array, w_key, w_value)
        fp.expect_closing_brace()
        if w_result is not None:    # needs_ref
            w_result.store(w_array, unique=True)
            return w_result
        else:
            return w_array
    #
    elif tp == 'R':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        return load_reference(fp)
    #
    elif tp == 'r':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        return load_reference(fp).deref()
    #
    elif tp == 'O':
        if s[i + 1] != ':':
            raise SerializerError("':' expected")
        klass_name = load_str(fp, ':')
        space = fp.space
        interp = space.ec.interpreter
        klass = interp.lookup_class_or_intf(klass_name)
        if klass is None:
            klass = k_incomplete
            w_instance = klass.get_empty_instance(space)
            w_instance.setattr(interp, '__PHP_Incomplete_Class_Name',
                               space.wrap(klass_name), None)
        else:
            w_instance = klass.get_empty_instance(space)
        w_result = w_instance
        if needs_ref:
            w_result = W_Reference(w_instance)
            fp.save_reference(w_result)
        count_attrs = fp.read_int_until(':')    # negative value accepted :-(
        i = fp.consume(1)
        if s[i] != '{':
            raise SerializerError("'{' expected")
        attrs = {}
        for i in xrange(count_attrs):
            w_attr = load_array_key(fp)
            w_value = load_object(fp)
            attr_name = space.str_w(w_attr)
            attrs[attr_name] = w_value
            w_instance.setattr(interp, attr_name, w_value, None)
        fp.expect_closing_brace()

        w_instance.unserialize(space, attrs)

        if '__wakeup' in klass.methods:
            klass.methods['__wakeup'].method_func.call_args(space.ec.interpreter,
                                                            [], w_this=w_instance,
                                                            thisclass=klass)
        return w_result
    #
    else:
        if tp == '}':
            fp.space.ec.notice("unserialize(): "
                               "Unexpected end of serialized data")
        raise SerializerError('malformed input')

    # this is for primitive types only; complex types 'return' above
    if needs_ref:
        w_result = W_Reference(w_result)
        fp.save_reference(w_result)
    return w_result
Example #20
0
        if space.is_w(w_floattype, space.w_float):
            return w_obj
        value = space.float_w(w_obj)
    elif (space.isinstance_w(w_value, space.w_str) or
          space.isinstance_w(w_value, space.w_bytearray)):
        strvalue = space.bufferstr_w(w_value)
        try:
            value = rfloat.string_to_float(strvalue)
        except ParseStringError, e:
            raise OperationError(space.w_ValueError,
                                 space.wrap(e.msg))
    elif space.isinstance_w(w_value, space.w_unicode):
        from unicodeobject import unicode_to_decimal_w
        strvalue = unicode_to_decimal_w(space, w_value)
        try:
            value = rfloat.string_to_float(strvalue)
        except ParseStringError, e:
            raise OperationError(space.w_ValueError,
                                 space.wrap(e.msg))
    else:
        value = space.float_w(w_x)
    w_obj = space.allocate_instance(W_FloatObject, w_floattype)
    W_FloatObject.__init__(w_obj, value)
    return w_obj


def detect_floatformat():
    from rpython.rtyper.lltypesystem import rffi, lltype
    buf = lltype.malloc(rffi.CCHARP.TO, 8, flavor='raw')
    rffi.cast(rffi.DOUBLEP, buf)[0] = 9006104071832581.0
    packed = rffi.charpsize2str(buf, 8)
Example #21
0
 def _string_to_float(space, w_source, string):
     try:
         return rfloat.string_to_float(string)
     except ParseStringError as e:
         raise wrap_parsestringerror(space, e, w_source)
Example #22
0
def str2num(w_s, radix, convert_mode, decimal_mode):
    from rpython.rlib import rarithmetic, rfloat, rbigint
    from rpython.rlib.rstring import ParseStringError, ParseStringOverflowError
    from rpython.rlib.rsre import rsre_re as re
    import math

    s = w_s.as_str_utf8()
    try:
        if re.match("[+-]?([\d]+)?.?\d+[tT]\d", s):
            # it's an extflonum
            return values.W_ExtFlonum(s)

        if re.match("[+-]?([\d]+)?.?\d+[sf]\d", s):
            if "f" in s:
                f_parts = s.split("f")
            elif "s" in s:
                f_parts = s.split("s")
            else:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            if len(f_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            try:
                numb = float(f_parts[0])
                prec = int(f_parts[1])
                p = math.pow(10, prec)
            except ValueError:
                return values.w_false

            return values.W_Flonum.make(numb * p, True)

        if re.match("[+-]?([\d]+)?.?\d+e\d", s):
            e_parts = s.split("e")
            if len(e_parts) > 2:
                raise ParseStringError("invalid floating point number : %s" %
                                       s)

            try:
                num = float(e_parts[0])
                exp = int(e_parts[1])
                p = math.pow(10, exp)
            except ValueError:
                return values.w_false

            return values.W_Flonum(num * p)

        if "." in s or re.match("[+-]?([\d]+)(\.[\d]+)?e[+-][\d]+$", s):
            if not radix.equal(values.W_Fixnum(10)):  # FIXME
                raise SchemeException(
                    "string->number : floats with base different than 10 are not supported yet : given number : %s - radix : %s"
                    % (w_s.tostring(), radix.tostring()))
            return values.W_Flonum(rfloat.string_to_float(s))
        else:
            try:
                return values.W_Fixnum(
                    rarithmetic.string_to_int(s, base=radix.toint()))
            except ParseStringOverflowError:
                return values.W_Bignum(rbigint.rbigint.fromstr(s))
    except ParseStringError as e:
        return values.w_false
Example #23
0
def test_string_to_float():
    from rpython.rlib.rstring import ParseStringError
    import random
    assert string_to_float('0') == 0.0
    assert string_to_float('1') == 1.0
    assert string_to_float('-1.5') == -1.5
    assert string_to_float('1.5E2') == 150.0
    assert string_to_float('2.5E-1') == 0.25
    assert string_to_float('1e1111111111111') == float('1e1111111111111')
    assert string_to_float('1e-1111111111111') == float('1e-1111111111111')
    assert string_to_float('-1e1111111111111') == float('-1e1111111111111')
    assert string_to_float('-1e-1111111111111') == float('-1e-1111111111111')
    assert string_to_float('1e111111111111111111111') == float(
        '1e111111111111111111111')
    assert string_to_float('1e-111111111111111111111') == float(
        '1e-111111111111111111111')
    assert string_to_float('-1e111111111111111111111') == float(
        '-1e111111111111111111111')
    assert string_to_float('-1e-111111111111111111111') == float(
        '-1e-111111111111111111111')

    valid_parts = [
        ['', '  ', ' \f\n\r\t\v'],
        ['', '+', '-'],
        [
            '00', '90', '.5', '2.4', '3.', '0.07',
            '12.3489749871982471987198371293717398256187563298638726'
            '2187362820947193247129871083561249818451804287437824015'
            '013816418758104762348932657836583048761487632840726386'
        ],
        ['', 'e0', 'E+1', 'E-01', 'E42'],
        ['', '  ', ' \f\n\r\t\v'],
    ]
    invalid_parts = [
        ['#'],
        ['++', '+-', '-+', '--'],
        ['', '1.2.3', '.', '5..6'],
        ['E+', 'E-', 'e', 'e++', 'E++2'],
        ['#'],
    ]
    for part0 in valid_parts[0]:
        for part1 in valid_parts[1]:
            for part2 in valid_parts[2]:
                for part3 in valid_parts[3]:
                    for part4 in valid_parts[4]:
                        s = part0 + part1 + part2 + part3 + part4
                        assert (abs(string_to_float(s) - float(s)) <=
                                1E-13 * abs(float(s)))

    for j in range(len(invalid_parts)):
        for invalid in invalid_parts[j]:
            for i in range(20):
                parts = [random.choice(lst) for lst in valid_parts]
                parts[j] = invalid
                s = ''.join(parts)
                print repr(s)
                if s.strip():  # empty s raises OperationError directly
                    py.test.raises(ParseStringError, string_to_float, s)
    py.test.raises(ParseStringError, string_to_float, "")
Example #24
0
def _string_to_float(space, w_source, string):
    try:
        return rfloat.string_to_float(string)
    except ParseStringError as e:
        from pypy.objspace.std.intobject import wrap_parsestringerror
        raise wrap_parsestringerror(space, e, w_source)