1. python_mirrors
  2. features/faster-format

Commits

Victor Stinner  committed d789054

_PyLong_FormatWriter() supports also the alternate form

  • Participants
  • Parent commits 21a65c1
  • Branches default

Comments (0)

Files changed (4)

File Include/longobject.h

View file
 PyAPI_FUNC(int) _PyLong_FormatWriter(
     PyObject *aa,
     int base,
+    int alternate,
     _PyUnicodeWriter *writer);
 
 /* Format the object based on the format_spec, as defined in PEP 3101

File Objects/longobject.c

View file
 
 /* Convert a long int object to a string, using a given conversion base,
    which should be one of 2, 8 or 16.  Return a string object.
-   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */
+   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'
+   if alternate is nonzero. */
 
 static int
-long_format_binary(PyObject *aa, int base,
+long_format_binary(PyObject *aa, int base, int alternate,
                    PyObject **p_output, _PyUnicodeWriter *writer)
 {
     register PyLongObject *a = (PyLongObject *)aa;
 
     /* Compute exact length 'sz' of output string. */
     if (size_a == 0) {
-        sz = 3;
+        sz = 1;
     }
     else {
         Py_ssize_t size_a_in_bits;
         }
         size_a_in_bits = (size_a - 1) * PyLong_SHIFT +
                          bits_in_digit(a->ob_digit[size_a - 1]);
-        /* Allow 2 characters for prefix and 1 for a '-' sign. */
-        sz = 2 + negative + (size_a_in_bits + (bits - 1)) / bits;
+        /* Allow 1 character for a '-' sign. */
+        sz = negative + (size_a_in_bits + (bits - 1)) / bits;
+    }
+    if (alternate) {
+        /* 2 characters for prefix  */
+        sz += 2;
     }
 
     if (writer) {
             }                                                           \
         }                                                               \
                                                                         \
-        if (base == 16)                                                 \
-            *--p = 'x';                                                 \
-        else if (base == 8)                                             \
-            *--p = 'o';                                                 \
-        else /* (base == 2) */                                          \
-            *--p = 'b';                                                 \
-        *--p = '0';                                                     \
+        if (alternate) {                                                \
+            if (base == 16)                                             \
+                *--p = 'x';                                             \
+            else if (base == 8)                                         \
+                *--p = 'o';                                             \
+            else /* (base == 2) */                                      \
+                *--p = 'b';                                             \
+            *--p = '0';                                                 \
+        }                                                               \
         if (negative)                                                   \
             *--p = '-';                                                 \
         if (writer)                                                     \
     if (base == 10)
         err = long_to_decimal_string_internal(aa, &str, NULL);
     else
-        err = long_format_binary(aa, base, &str, NULL);
+        err = long_format_binary(aa, base, 1, &str, NULL);
     if (err == -1)
         return NULL;
     return str;
 }
 
 int
-_PyLong_FormatWriter(PyObject *aa, int base, _PyUnicodeWriter *writer)
+_PyLong_FormatWriter(PyObject *aa,
+                     int base, int alternate,
+                     _PyUnicodeWriter *writer)
 {
     if (base == 10)
         return long_to_decimal_string_internal(aa, NULL, writer);
     else
-        return long_format_binary(aa, base, NULL, writer);
+        return long_format_binary(aa, base, alternate, NULL, writer);
 }
 
 /* Table of digit values for 8-bit string -> integer conversion.

File Objects/unicodeobject.c

View file
                         goto nextarg;
                     }
                     else if (PyLong_CheckExact(v)) {
-                        if (_PyLong_FormatWriter(v, 10, &writer) == -1)
+                        if (_PyLong_FormatWriter(v, 10, flags & F_ALT, &writer) == -1)
                             goto onError;
                         goto nextarg;
                     }
             case 'o':
             case 'x':
             case 'X':
+                if (PyLong_CheckExact(v) && width == -1 && prec == -1) {
+                    /* Fast path */
+                    switch(c)
+                    {
+                    case 'd':
+                    case 'i':
+                        if (_PyLong_FormatWriter(v, 10, flags & F_ALT, &writer) == -1)
+                            goto onError;
+                        goto nextarg;
+                    case 'x':
+                        if (_PyLong_FormatWriter(v, 16, flags & F_ALT, &writer) == -1)
+                            goto onError;
+                        goto nextarg;
+                    case 'o':
+                        if (_PyLong_FormatWriter(v, 8, flags & F_ALT, &writer) == -1)
+                            goto onError;
+                        goto nextarg;
+                    default:
+                        break;
+                    }
+                }
+
                 isnumok = 0;
                 if (PyNumber_Check(v)) {
                     PyObject *iobj=NULL;

File Python/formatter_unicode.c

View file
         }
 
         if (format->sign != '+' && format->sign != ' '
-            && !format->alternate
             && format->width == -1
             && format->type != 'X' && format->type != 'n'
             && PyLong_CheckExact(value))
         {
             /* Fast path */
-            return _PyLong_FormatWriter(value, base, writer);
+            return _PyLong_FormatWriter(value, base, format->alternate, writer);
         }
 
         /* The number of prefix chars is the same as the leading
 
     /* check for the special case of zero length format spec, make
        it equivalent to str(obj) */
-    if (start == end)
-        return format_obj(obj, writer);
+    if (start == end) {
+        if (PyUnicode_CheckExact(obj))
+            return _PyUnicodeWriter_WriteStr(writer, obj);
+        else
+            return format_obj(obj, writer);
+    }
 
     /* parse the format_spec */
     if (!parse_internal_render_format_spec(format_spec, start, end,
        it equivalent to str(obj) */
     if (start == end) {
         if (PyLong_CheckExact(obj))
-            return _PyLong_FormatWriter(obj, 10, writer);
+            return _PyLong_FormatWriter(obj, 10, 0, writer);
         else
             return format_obj(obj, writer);
     }