Forward port of r64958.
Added '#' formatting to integers.  This adds the 0b, 0o, or 0x prefix for bin, oct, hex.  There's still one failing case, and I need to finish the docs.  I hope to finish those today.
diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h
index 018121a..9b7d607 100644
--- a/Objects/stringlib/formatter.h
+++ b/Objects/stringlib/formatter.h
@@ -89,6 +89,7 @@
 typedef struct {
     STRINGLIB_CHAR fill_char;
     STRINGLIB_CHAR align;
+    int alternate;
     STRINGLIB_CHAR sign;
     Py_ssize_t width;
     Py_ssize_t precision;
@@ -117,6 +118,7 @@
 
     format->fill_char = '\0';
     format->align = '\0';
+    format->alternate = 0;
     format->sign = '\0';
     format->width = -1;
     format->precision = -1;
@@ -154,6 +156,13 @@
         ++ptr;
     }
 
+    /* If the next character is #, we're in alternate mode.  This only
+       applies to integers. */
+    if (end-ptr >= 1 && ptr[0] == '#') {
+	format->alternate = 1;
+	++ptr;
+    }
+
     /* XXX add error checking */
     specified_width = get_integer(&ptr, end, &format->width);
 
@@ -221,7 +230,8 @@
    and more efficient enough to justify a little obfuscation? */
 static void
 calc_number_widths(NumberFieldWidths *r, STRINGLIB_CHAR actual_sign,
-                   Py_ssize_t n_digits, const InternalFormatSpec *format)
+		   Py_ssize_t n_prefix, Py_ssize_t n_digits,
+		   const InternalFormatSpec *format)
 {
     r->n_lpadding = 0;
     r->n_spadding = 0;
@@ -232,13 +242,15 @@
     r->n_rsign = 0;
 
     /* the output will look like:
-       |                                                           |
-       | <lpadding> <lsign> <spadding> <digits> <rsign> <rpadding> |
-       |                                                           |
+       |                                                                    |
+       | <lpadding> <lsign> <prefix> <spadding> <digits> <rsign> <rpadding> |
+       |                                                                    |
 
        lsign and rsign are computed from format->sign and the actual
        sign of the number
 
+       prefix is given (it's for the '0x' prefix)
+
        digits is already known
 
        the total width is either given, or computed from the
@@ -363,6 +375,14 @@
         goto done;
     }
 
+    /* alternate is not allowed on strings */
+    if (format->alternate) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Alternate form (#) not allowed in string format "
+			"specifier");
+        goto done;
+    }
+
     /* '=' alignment not allowed on strings */
     if (format->align == '=') {
         PyErr_SetString(PyExc_ValueError,
@@ -505,31 +525,33 @@
     }
     else {
         int base;
-	int leading_chars_to_skip;  /* Number of characters added by
-				       PyNumber_ToBase that we want to
-				       skip over. */
+	int leading_chars_to_skip = 0;  /* Number of characters added by
+				           PyNumber_ToBase that we want to
+				           skip over. */
 
         /* Compute the base and how many characters will be added by
            PyNumber_ToBase */
         switch (format->type) {
         case 'b':
             base = 2;
-            leading_chars_to_skip = 2; /* 0b */
+	    if (!format->alternate)
+		leading_chars_to_skip = 2; /* 0b */
             break;
         case 'o':
             base = 8;
-            leading_chars_to_skip = 2; /* 0o */
+	    if (!format->alternate)
+		leading_chars_to_skip = 2; /* 0o */
             break;
         case 'x':
         case 'X':
             base = 16;
-            leading_chars_to_skip = 2; /* 0x */
+	    if (!format->alternate)
+		leading_chars_to_skip = 2; /* 0x */
             break;
         default:  /* shouldn't be needed, but stops a compiler warning */
         case 'd':
         case 'n':
             base = 10;
-            leading_chars_to_skip = 0;
             break;
         }
 
@@ -564,7 +586,7 @@
 			       0, &n_grouping_chars, 0);
 
     /* Calculate the widths of the various leading and trailing parts */
-    calc_number_widths(&spec, sign, n_digits + n_grouping_chars, format);
+    calc_number_widths(&spec, sign, 0, n_digits + n_grouping_chars, format);
 
     /* Allocate a new string to hold the result */
     result = STRINGLIB_NEW(NULL, spec.n_total);
@@ -670,6 +692,14 @@
     Py_UNICODE unicodebuf[FLOAT_FORMATBUFLEN];
 #endif
 
+    /* alternate is not allowed on floats. */
+    if (format->alternate) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Alternate form (#) not allowed in float format "
+			"specifier");
+        goto done;
+    }
+
     /* first, do the conversion as 8-bit chars, using the platform's
        snprintf.  then, if needed, convert to unicode. */
 
@@ -730,7 +760,7 @@
         --n_digits;
     }
 
-    calc_number_widths(&spec, sign, n_digits, format);
+    calc_number_widths(&spec, sign, 0, n_digits, format);
 
     /* allocate a string with enough space */
     result = STRINGLIB_NEW(NULL, spec.n_total);