Bug 415514 reported that e.g.

"%#x" % 0
blew up, at heart because C sprintf supplies a base marker if and only if
the value is not 0.  I then fixed that, by tolerating C's inconsistency
when it does %#x, and taking away that *Python* produced 0x0 when
formatting 0L (the "long" flavor of 0) under %#x itself.  But after talking
with Guido, we agreed it would be better to supply 0x for the short int
case too, despite that it's inconsistent with C, because C is inconsistent
with itself and with Python's hex(0) (plus, while "%#x" % 0 didn't work
before, "%#x" % 0L *did*, and returned "0x0").  Similarly for %#X conversion.
This commit is contained in:
Tim Peters 2001-04-12 18:38:48 +00:00
parent bfb0cf822b
commit fff5325078
3 changed files with 47 additions and 42 deletions

View file

@ -4683,7 +4683,14 @@ formatint(Py_UNICODE *buf,
"formatted integer is too long (precision too long?)");
return -1;
}
sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type);
/* When converting 0 under %#x or %#X, C leaves off the base marker,
* but we want it (for consistency with other %#x conversions, and
* for consistency with Python's hex() function).
*/
if (x == 0 && (flags & F_ALT) && (type == 'x' || type == 'X'))
sprintf(fmt, "0%c%%%s.%dl%c", type, "#", prec, type);
else
sprintf(fmt, "%%%s.%dl%c", (flags & F_ALT) ? "#" : "", prec, type);
return usprintf(buf, fmt, x);
}
@ -5081,17 +5088,16 @@ PyObject *PyUnicode_Format(PyObject *format,
}
if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
assert(pbuf[0] == '0');
if (pbuf[1] == c) {
if (fill != ' ') {
*res++ = *pbuf++;
*res++ = *pbuf++;
}
rescnt -= 2;
width -= 2;
if (width < 0)
width = 0;
len -= 2;
assert(pbuf[1] == c);
if (fill != ' ') {
*res++ = *pbuf++;
*res++ = *pbuf++;
}
rescnt -= 2;
width -= 2;
if (width < 0)
width = 0;
len -= 2;
}
if (width > len && !(flags & F_LJUST)) {
do {
@ -5102,9 +5108,9 @@ PyObject *PyUnicode_Format(PyObject *format,
if (fill == ' ') {
if (sign)
*res++ = sign;
if ((flags & F_ALT) && (c == 'x' || c == 'X') &&
pbuf[1] == c) {
if ((flags & F_ALT) && (c == 'x' || c == 'X')) {
assert(pbuf[0] == '0');
assert(pbuf[1] == c);
*res++ = *pbuf++;
*res++ = *pbuf++;
}