Exemple #1
0
 def _get_locale(self, tp):
     if tp == "n":
         dec, thousands, grouping = rlocale.numeric_formatting()
     elif self._thousands_sep:
         dec = "."
         thousands = ","
         grouping = "\3"
     else:
         dec = "."
         thousands = ""
         grouping = "\xFF"  # special value to mean 'stop'
     if self.is_unicode:
         self._loc_dec = rutf8.decode_latin_1(dec)
         self._loc_thousands = rutf8.decode_latin_1(thousands)
     else:
         self._loc_dec = dec
         self._loc_thousands = thousands
     self._loc_grouping = grouping
Exemple #2
0
 def _long_to_base(self, base, value):
     prefix = ""
     if base == 2:
         prefix = "0b"
     elif base == 8:
         prefix = "0o"
     elif base == 16:
         prefix = "0x"
     as_str = value.format(LONG_DIGITS[:base], prefix)
     if self.is_unicode:
         return rutf8.decode_latin_1(as_str)
     return as_str
Exemple #3
0
 def _format_float(self, w_float):
     """helper for format_float"""
     space = self.space
     flags = 0
     default_precision = 6
     if self._alternate:
         raise oefmt(space.w_ValueError,
                     "Alternate form (#) not allowed in float formats")
     tp = self._type
     self._get_locale(tp)
     if tp == "\0":
         tp = "g"
         default_precision = 12
         flags |= rfloat.DTSF_ADD_DOT_0
     elif tp == "n":
         tp = "g"
     value = space.float_w(w_float)
     if tp == "%":
         tp = "f"
         value *= 100
         add_pct = True
     else:
         add_pct = False
     if self._precision == -1:
         self._precision = default_precision
     result, special = rfloat.double_to_string(value, tp,
                                               self._precision, flags)
     if add_pct:
         result += "%"
     n_digits = len(result)
     if result[0] == "-":
         sign = "-"
         to_number = 1
         n_digits -= 1
     else:
         sign = "\0"
         to_number = 0
     have_dec_point, to_remainder = self._parse_number(
         result, to_number)
     n_remainder = len(result) - to_remainder
     if self.is_unicode:
         digits = rutf8.decode_latin_1(result)
     else:
         digits = result
     spec = self._calc_num_width(0, sign, to_number, n_digits,
                                 n_remainder, have_dec_point, digits)
     fill = self._fill_char
     return self.wrap(
         self._fill_number(spec, digits, to_number, 0, fill,
                           to_remainder, False))
Exemple #4
0
 def _int_to_base(self, base, value):
     if base == 10:
         s = str(value)
         if self.is_unicode:
             return rutf8.decode_latin_1(s)
         return s
     # This part is slow.
     negative = value < 0
     base = r_uint(base)
     value = r_uint(value)
     if negative:  # change the sign on the unsigned number: otherwise,
         value = -value  #   we'd risk overflow if value==-sys.maxint-1
     #
     buf = ["\0"] * (8 * 8 + 6)  # Too much on 32 bit, but who cares?
     i = len(buf) - 1
     while True:
         div = value // base  # unsigned
         mod = value - div * base  # unsigned, always in range(0,base)
         digit = intmask(mod)
         digit += ord("0") if digit < 10 else ord("a") - 10
         buf[i] = chr(digit)
         value = div  # unsigned
         i -= 1
         if not value:
             break
     if base == r_uint(2):
         buf[i] = "b"
         buf[i - 1] = "0"
     elif base == r_uint(8):
         buf[i] = "o"
         buf[i - 1] = "0"
     elif base == r_uint(16):
         buf[i] = "x"
         buf[i - 1] = "0"
     else:
         buf[i] = "#"
         buf[i - 1] = chr(ord("0") + intmask(base % r_uint(10)))
         if base > r_uint(10):
             buf[i - 2] = chr(ord("0") + intmask(base // r_uint(10)))
             i -= 1
     i -= 1
     if negative:
         i -= 1
         buf[i] = "-"
     assert i >= 0
     return "".join(buf[i:])
Exemple #5
0
        def _format_complex(self, w_complex):
            space = self.space
            tp = self._type
            self._get_locale(tp)
            default_precision = 6
            if self._align == "=":
                # '=' alignment is invalid
                raise oefmt(
                    space.w_ValueError,
                    "'=' alignment flag is not allowed in complex "
                    "format specifier")
            if self._fill_char == "0":
                # zero padding is invalid
                raise oefmt(
                    space.w_ValueError,
                    "Zero padding is not allowed in complex format "
                    "specifier")
            if self._alternate:
                # alternate is invalid
                raise oefmt(
                    space.w_ValueError,
                    "Alternate form (#) not allowed in complex format "
                    "specifier")
            skip_re = 0
            add_parens = 0
            if tp == "\0":
                #should mirror str() output
                tp = "g"
                default_precision = 12
                #test if real part is non-zero
                if (w_complex.realval == 0
                        and math.copysign(1., w_complex.realval) == 1.):
                    skip_re = 1
                else:
                    add_parens = 1

            if tp == "n":
                #same as 'g' except for locale, taken care of later
                tp = "g"

            #check if precision not set
            if self._precision == -1:
                self._precision = default_precision

            #might want to switch to double_to_string from formatd
            #in CPython it's named 're' - clashes with re module
            re_num = formatd(w_complex.realval, tp, self._precision)
            im_num = formatd(w_complex.imagval, tp, self._precision)
            n_re_digits = len(re_num)
            n_im_digits = len(im_num)

            to_real_number = 0
            to_imag_number = 0
            re_sign = im_sign = ''
            #if a sign character is in the output, remember it and skip
            if re_num[0] == "-":
                re_sign = "-"
                to_real_number = 1
                n_re_digits -= 1
            if im_num[0] == "-":
                im_sign = "-"
                to_imag_number = 1
                n_im_digits -= 1

            #turn off padding - do it after number composition
            #calc_num_width uses self._width, so assign to temporary variable,
            #calculate width of real and imag parts, then reassign padding, align
            tmp_fill_char = self._fill_char
            tmp_align = self._align
            tmp_width = self._width
            self._fill_char = "\0"
            self._align = "<"
            self._width = -1

            #determine if we have remainder, might include dec or exponent or both
            re_have_dec, re_remainder_ptr = self._parse_number(
                re_num, to_real_number)
            im_have_dec, im_remainder_ptr = self._parse_number(
                im_num, to_imag_number)

            if self.is_unicode:
                re_num = rutf8.decode_latin_1(re_num)
                im_num = rutf8.decode_latin_1(im_num)

            #set remainder, in CPython _parse_number sets this
            #using n_re_digits causes tests to fail
            re_n_remainder = len(re_num) - re_remainder_ptr
            im_n_remainder = len(im_num) - im_remainder_ptr
            re_spec = self._calc_num_width(0, re_sign, to_real_number,
                                           n_re_digits, re_n_remainder,
                                           re_have_dec, re_num)

            #capture grouped digits b/c _fill_number reads from self._grouped_digits
            #self._grouped_digits will get overwritten in imaginary calc_num_width
            re_grouped_digits = self._grouped_digits
            if not skip_re:
                self._sign = "+"
            im_spec = self._calc_num_width(0, im_sign, to_imag_number,
                                           n_im_digits, im_n_remainder,
                                           im_have_dec, im_num)

            im_grouped_digits = self._grouped_digits
            if skip_re:
                re_spec.n_total = 0

            #reassign width, alignment, fill character
            self._align = tmp_align
            self._width = tmp_width
            self._fill_char = tmp_fill_char

            #compute L and R padding - stored in self._left_pad and self._right_pad
            self._calc_padding(
                "", re_spec.n_total + im_spec.n_total + 1 + add_parens * 2)

            out = self._builder()
            fill = self._fill_char

            #compose the string
            #add left padding
            out.append_multiple_char(fill, self._left_pad)
            if add_parens:
                out.append(self._lit('(')[0])

            #if the no. has a real component, add it
            if not skip_re:
                out.append(
                    self._fill_number(re_spec, re_num, to_real_number, 0, fill,
                                      re_remainder_ptr, False,
                                      re_grouped_digits))

            #add imaginary component
            out.append(
                self._fill_number(im_spec, im_num, to_imag_number, 0, fill,
                                  im_remainder_ptr, False, im_grouped_digits))

            #add 'j' character
            out.append(self._lit('j')[0])

            if add_parens:
                out.append(self._lit(')')[0])

            #add right padding
            out.append_multiple_char(fill, self._right_pad)

            return self.wrap(out.build())