Fix for SF bug #415514: "%#x" % 0 caused assertion failure/abort.
http://sourceforge.net/tracker/index.php?func=detail&aid=415514&group_id=5470&atid=105470
For short ints, Python defers to the platform C library to figure out what
%#x should do.  The code asserted that the platform C returned a string
beginning with "0x".  However, that's not true when-- and only when --the
*value* being formatted is 0.  Changed the code to live with C's inconsistency
here.  In the meantime, the problem does not arise if you format a long 0 (0L)
instead.  However, that's because the code *we* wrote to do %#x conversions on
longs produces a leading "0x" regardless of value.  That's probably wrong too:
we should drop leading "0x", for consistency with C, when (& only when) formatting
0L.  So I changed the long formatting code to do that too.
diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py
index 6a60603..ce5d5f2 100644
--- a/Lib/test/test_format.py
+++ b/Lib/test/test_format.py
@@ -164,6 +164,22 @@
 testboth("%d", -42, "-42")
 testboth("%d", 42L, "42")
 testboth("%d", -42L, "-42")
+testboth("%#x", 1, "0x1")
+testboth("%#x", 1L, "0x1")
+testboth("%#X", 1, "0X1")
+testboth("%#X", 1L, "0X1")
+testboth("%#o", 1, "01")
+testboth("%#o", 1L, "01")
+testboth("%#o", 0, "0")
+testboth("%#o", 0L, "0")
+testboth("%o", 0, "0")
+testboth("%o", 0L, "0")
+testboth("%d", 0, "0")
+testboth("%d", 0L, "0")
+testboth("%#x", 0, "0")
+testboth("%#x", 0L, "0")
+testboth("%#X", 0, "0")
+testboth("%#X", 0L, "0")
 
 testboth("%x", 0x42, "42")
 # testboth("%x", -0x42, "ffffffbe") # Alas, that's specific to 32-bit machines
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 740cbe2..8e11536 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -2575,8 +2575,16 @@
 	numdigits = len - numnondigits;
 	assert(numdigits > 0);
 
-	/* Get rid of base marker unless F_ALT */
-	if ((flags & F_ALT) == 0) {
+	/* Get rid of base marker unless F_ALT.  Even if F_ALT, leading 0x
+	 * must be stripped if the *value* is 0.
+	 */
+	if ((flags & F_ALT) == 0 ||
+	    ((flags & F_ALT) &&
+	     (type == 'x' || type == 'X') &&
+	     numdigits == 1 &&
+	     !sign &&
+	     buf[2] == '0'
+	    )) {
 		/* Need to skip 0x, 0X or 0. */
 		int skipped = 0;
 		switch (type) {
@@ -3015,17 +3023,21 @@
 					width--;
 			}
 			if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+				/* There's a base marker ("0x" or "0X") if and
+				 * only if the value is non-zero.
+				 */
 				assert(pbuf[0] == '0');
-				assert(pbuf[1] == c);
-				if (fill != ' ') {
-					*res++ = *pbuf++;
-					*res++ = *pbuf++;
+				if (pbuf[1] == c) {
+					if (fill != ' ') {
+						*res++ = *pbuf++;
+						*res++ = *pbuf++;
+					}
+					rescnt -= 2;
+					width -= 2;
+					if (width < 0)
+						width = 0;
+					len -= 2;
 				}
-				rescnt -= 2;
-				width -= 2;
-				if (width < 0)
-					width = 0;
-				len -= 2;
 			}
 			if (width > len && !(flags & F_LJUST)) {
 				do {
@@ -3037,9 +3049,8 @@
 				if (sign)
 					*res++ = sign;
 				if ((flags & F_ALT) &&
-				    (c == 'x' || c == 'X')) {
-					assert(pbuf[0] == '0');
-					assert(pbuf[1] == c);
+				    (c == 'x' || c == 'X') &&
+				    pbuf[1] == c) {
 					*res++ = *pbuf++;
 					*res++ = *pbuf++;
 				}
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index c237789..aecc261 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -5081,16 +5081,17 @@
 	    }
 	    if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
 		assert(pbuf[0] == '0');
-		assert(pbuf[1] == c);
-		if (fill != ' ') {
-		    *res++ = *pbuf++;
-		    *res++ = *pbuf++;
+		if (pbuf[1] == c) {
+			if (fill != ' ') {
+			    *res++ = *pbuf++;
+			    *res++ = *pbuf++;
+			}
+			rescnt -= 2;
+			width -= 2;
+			if (width < 0)
+			    width = 0;
+			len -= 2;
 		}
-		rescnt -= 2;
-		width -= 2;
-		if (width < 0)
-		    width = 0;
-		len -= 2;
 	    }
 	    if (width > len && !(flags & F_LJUST)) {
 		do {
@@ -5101,9 +5102,9 @@
 	    if (fill == ' ') {
 		if (sign)
 		    *res++ = sign;
-		if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
+		if ((flags & F_ALT) && (c == 'x' || c == 'X') &&
+		    pbuf[1] == c) {
 		    assert(pbuf[0] == '0');
-		    assert(pbuf[1] == c);
 		    *res++ = *pbuf++;
 		    *res++ = *pbuf++;
 		}